blob: 7f09278338195dd31f1374b422dfb3a0515d63b3 [file] [log] [blame]
/*
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
#include <cassandra.h>
#include <stdio.h>
void print_keyspace_meta(const CassKeyspaceMeta* meta, int indent);
void print_table_meta(const CassTableMeta* meta, int indent);
void print_function_meta(const CassFunctionMeta* meta, int indent);
void print_aggregate_meta(const CassAggregateMeta* meta, int indent);
void print_keyspace(CassSession* session, const char* keyspace) {
const CassSchemaMeta* schema_meta = cass_session_get_schema_meta(session);
const CassKeyspaceMeta* keyspace_meta = cass_schema_meta_keyspace_by_name(schema_meta, keyspace);
if (keyspace_meta != NULL) {
print_keyspace_meta(keyspace_meta, 0);
} else {
fprintf(stderr, "Unable to find \"%s\" keyspace in the schema metadata\n", keyspace);
}
cass_schema_meta_free(schema_meta);
}
void print_table(CassSession* session, const char* keyspace, const char* table) {
const CassSchemaMeta* schema_meta = cass_session_get_schema_meta(session);
const CassKeyspaceMeta* keyspace_meta = cass_schema_meta_keyspace_by_name(schema_meta, keyspace);
if (keyspace_meta != NULL) {
const CassTableMeta* table_meta = cass_keyspace_meta_table_by_name(keyspace_meta, table);
if (table_meta != NULL) {
print_table_meta(table_meta, 0);
} else {
fprintf(stderr, "Unable to find \"%s\" table in the schema metadata\n", table);
}
} else {
fprintf(stderr, "Unable to find \"%s\" keyspace in the schema metadata\n", keyspace);
}
cass_schema_meta_free(schema_meta);
}
void print_function(CassSession* session, const char* keyspace, const char* function,
const char* arguments) {
const CassSchemaMeta* schema_meta = cass_session_get_schema_meta(session);
const CassKeyspaceMeta* keyspace_meta = cass_schema_meta_keyspace_by_name(schema_meta, keyspace);
if (keyspace_meta != NULL) {
const CassFunctionMeta* function_meta =
cass_keyspace_meta_function_by_name(keyspace_meta, function, arguments);
if (function_meta != NULL) {
print_function_meta(function_meta, 0);
} else {
fprintf(stderr, "Unable to find \"%s\" function in the schema metadata\n", function);
}
} else {
fprintf(stderr, "Unable to find \"%s\" keyspace in the schema metadata\n", keyspace);
}
cass_schema_meta_free(schema_meta);
}
void print_aggregate(CassSession* session, const char* keyspace, const char* aggregate,
const char* arguments) {
const CassSchemaMeta* schema_meta = cass_session_get_schema_meta(session);
const CassKeyspaceMeta* keyspace_meta = cass_schema_meta_keyspace_by_name(schema_meta, keyspace);
if (keyspace_meta != NULL) {
const CassAggregateMeta* aggregate_meta =
cass_keyspace_meta_aggregate_by_name(keyspace_meta, aggregate, arguments);
if (aggregate_meta != NULL) {
print_aggregate_meta(aggregate_meta, 0);
} else {
fprintf(stderr, "Unable to find \"%s\" aggregate in the schema metadata\n", aggregate);
}
} else {
fprintf(stderr, "Unable to find \"%s\" keyspace in the schema metadata\n", keyspace);
}
cass_schema_meta_free(schema_meta);
}
void print_error(CassFuture* future) {
const char* message;
size_t message_length;
cass_future_error_message(future, &message, &message_length);
fprintf(stderr, "Error: %.*s\n", (int)message_length, message);
}
CassError execute_query(CassSession* session, const char* query) {
CassError rc = CASS_OK;
CassFuture* future = NULL;
CassStatement* statement = cass_statement_new(query, 0);
future = cass_session_execute(session, statement);
cass_future_wait(future);
rc = cass_future_error_code(future);
if (rc != CASS_OK) {
print_error(future);
}
cass_future_free(future);
cass_statement_free(statement);
return rc;
}
int main(int argc, char* argv[]) {
CassFuture* connect_future = NULL;
CassCluster* cluster = cass_cluster_new();
CassSession* session = cass_session_new();
char* hosts = "127.0.0.1";
if (argc > 1) {
hosts = argv[1];
}
cass_cluster_set_contact_points(cluster, hosts);
connect_future = cass_session_connect(session, cluster);
if (cass_future_error_code(connect_future) == CASS_OK) {
const CassSchemaMeta* schema_meta = cass_session_get_schema_meta(session);
CassVersion version = cass_schema_meta_version(schema_meta);
execute_query(session, "DROP KEYSPACE IF EXISTS examples;");
execute_query(session, "CREATE KEYSPACE examples WITH replication = { \
'class': 'SimpleStrategy', 'replication_factor': '3' }");
print_keyspace(session, "examples");
execute_query(session, "CREATE TABLE examples.schema_meta (key text, \
value bigint, \
PRIMARY KEY (key))");
execute_query(session, "CREATE INDEX schema_meta_idx \
ON examples.schema_meta (value)");
execute_query(session, "CREATE FUNCTION \
examples.avg_state(state tuple<int, bigint>, val int) \
CALLED ON NULL INPUT RETURNS tuple<int, bigint> \
LANGUAGE java AS \
'if (val != null) { \
state.setInt(0, state.getInt(0) + 1); \
state.setLong(1, state.getLong(1) + val.intValue()); \
} \
return state;'");
execute_query(session, "CREATE FUNCTION \
examples.avg_final (state tuple<int, bigint>) \
CALLED ON NULL INPUT RETURNS double \
LANGUAGE java AS \
'double r = 0; \
if (state.getInt(0) == 0) return null; \
r = state.getLong(1); \
r /= state.getInt(0); \
return Double.valueOf(r);'");
execute_query(session, "CREATE AGGREGATE examples.average(int) \
SFUNC avg_state STYPE tuple<int, bigint> FINALFUNC avg_final \
INITCOND(0, 0)");
print_table(session, "examples", "schema_meta");
if (version.major_version >= 3) {
/* Collection types are marked as frozen in Cassandra 3.x and later. */
print_function(session, "examples", "avg_state", "frozen<tuple<int,bigint>>,int");
print_function(session, "examples", "avg_final", "frozen<tuple<int,bigint>>");
} else {
print_function(session, "examples", "avg_state", "tuple<int,bigint>,int");
print_function(session, "examples", "avg_final", "tuple<int,bigint>");
}
print_aggregate(session, "examples", "average", "int");
cass_schema_meta_free(schema_meta);
} else {
print_error(connect_future);
}
cass_future_free(connect_future);
cass_cluster_free(cluster);
cass_session_free(session);
return 0;
}
void print_schema_value(const CassValue* value);
void print_schema_bytes(const CassValue* value);
void print_schema_list(const CassValue* value);
void print_schema_map(const CassValue* value);
void print_meta_field(const CassIterator* iterator, int indent);
void print_meta_fields(CassIterator* iterator, int indent);
void print_column_meta(const CassColumnMeta* meta, int indent);
void print_index_meta(const CassIndexMeta* meta, int indent);
void print_indent(int indent) {
int i;
for (i = 0; i < indent; ++i) {
printf("\t");
}
}
void print_schema_value(const CassValue* value) {
cass_int32_t i;
cass_bool_t b;
cass_double_t d;
const char* s;
size_t s_length;
CassUuid u;
char us[CASS_UUID_STRING_LENGTH];
CassValueType type = cass_value_type(value);
switch (type) {
case CASS_VALUE_TYPE_INT:
cass_value_get_int32(value, &i);
printf("%d", i);
break;
case CASS_VALUE_TYPE_BOOLEAN:
cass_value_get_bool(value, &b);
printf("%s", b ? "true" : "false");
break;
case CASS_VALUE_TYPE_DOUBLE:
cass_value_get_double(value, &d);
printf("%f", d);
break;
case CASS_VALUE_TYPE_TEXT:
case CASS_VALUE_TYPE_ASCII:
case CASS_VALUE_TYPE_VARCHAR:
cass_value_get_string(value, &s, &s_length);
printf("\"%.*s\"", (int)s_length, s);
break;
case CASS_VALUE_TYPE_UUID:
cass_value_get_uuid(value, &u);
cass_uuid_string(u, us);
printf("%s", us);
break;
case CASS_VALUE_TYPE_LIST:
print_schema_list(value);
break;
case CASS_VALUE_TYPE_MAP:
print_schema_map(value);
break;
case CASS_VALUE_TYPE_BLOB:
print_schema_bytes(value);
break;
default:
if (cass_value_is_null(value)) {
printf("null");
} else {
printf("<unhandled type>");
}
break;
}
}
void print_schema_bytes(const CassValue* value) {
const cass_byte_t* bytes;
size_t b_length;
size_t i;
cass_value_get_bytes(value, &bytes, &b_length);
printf("0x");
for (i = 0; i < b_length; ++i)
printf("%02x", bytes[i]);
}
void print_schema_list(const CassValue* value) {
CassIterator* iterator = cass_iterator_from_collection(value);
cass_bool_t is_first = cass_true;
printf("[ ");
while (cass_iterator_next(iterator)) {
if (!is_first) printf(", ");
print_schema_value(cass_iterator_get_value(iterator));
is_first = cass_false;
}
printf(" ]");
cass_iterator_free(iterator);
}
void print_schema_map(const CassValue* value) {
CassIterator* iterator = cass_iterator_from_map(value);
cass_bool_t is_first = cass_true;
printf("{ ");
while (cass_iterator_next(iterator)) {
if (!is_first) printf(", ");
print_schema_value(cass_iterator_get_map_key(iterator));
printf(" : ");
print_schema_value(cass_iterator_get_map_value(iterator));
is_first = cass_false;
}
printf(" }");
cass_iterator_free(iterator);
}
void print_meta_field(const CassIterator* iterator, int indent) {
const char* name;
size_t name_length;
const CassValue* value;
cass_iterator_get_meta_field_name(iterator, &name, &name_length);
value = cass_iterator_get_meta_field_value(iterator);
print_indent(indent);
printf("%.*s: ", (int)name_length, name);
print_schema_value(value);
printf("\n");
}
void print_meta_fields(CassIterator* iterator, int indent) {
while (cass_iterator_next(iterator)) {
print_meta_field(iterator, indent);
}
cass_iterator_free(iterator);
}
void print_keyspace_meta(const CassKeyspaceMeta* meta, int indent) {
const char* name;
size_t name_length;
CassIterator* iterator;
print_indent(indent);
cass_keyspace_meta_name(meta, &name, &name_length);
printf("Keyspace \"%.*s\":\n", (int)name_length, name);
print_meta_fields(cass_iterator_fields_from_keyspace_meta(meta), indent + 1);
printf("\n");
iterator = cass_iterator_tables_from_keyspace_meta(meta);
while (cass_iterator_next(iterator)) {
print_table_meta(cass_iterator_get_table_meta(iterator), indent + 1);
}
printf("\n");
cass_iterator_free(iterator);
}
void print_table_meta(const CassTableMeta* meta, int indent) {
const char* name;
size_t name_length;
CassIterator* iterator;
print_indent(indent);
cass_table_meta_name(meta, &name, &name_length);
printf("Table \"%.*s\":\n", (int)name_length, name);
print_meta_fields(cass_iterator_fields_from_table_meta(meta), indent + 1);
printf("\n");
iterator = cass_iterator_columns_from_table_meta(meta);
while (cass_iterator_next(iterator)) {
print_column_meta(cass_iterator_get_column_meta(iterator), indent + 1);
}
printf("\n");
cass_iterator_free(iterator);
iterator = cass_iterator_indexes_from_table_meta(meta);
while (cass_iterator_next(iterator)) {
print_index_meta(cass_iterator_get_index_meta(iterator), indent + 1);
}
printf("\n");
cass_iterator_free(iterator);
}
void print_function_meta(const CassFunctionMeta* meta, int indent) {
const char* name;
size_t name_length;
print_indent(indent);
cass_function_meta_name(meta, &name, &name_length);
printf("Function \"%.*s\":\n", (int)name_length, name);
print_meta_fields(cass_iterator_fields_from_function_meta(meta), indent + 1);
printf("\n");
}
void print_aggregate_meta(const CassAggregateMeta* meta, int indent) {
const char* name;
size_t name_length;
print_indent(indent);
cass_aggregate_meta_name(meta, &name, &name_length);
printf("Aggregate \"%.*s\":\n", (int)name_length, name);
print_meta_fields(cass_iterator_fields_from_aggregate_meta(meta), indent + 1);
printf("\n");
}
void print_column_meta(const CassColumnMeta* meta, int indent) {
const char* name;
size_t name_length;
print_indent(indent);
cass_column_meta_name(meta, &name, &name_length);
printf("Column \"%.*s\":\n", (int)name_length, name);
print_meta_fields(cass_iterator_fields_from_column_meta(meta), indent + 1);
printf("\n");
}
void print_index_meta(const CassIndexMeta* meta, int indent) {
const char* name;
size_t name_length;
print_indent(indent);
cass_index_meta_name(meta, &name, &name_length);
printf("Index \"%.*s\":\n", (int)name_length, name);
print_meta_fields(cass_iterator_fields_from_index_meta(meta), indent + 1);
printf("\n");
}