/* -*- Mode: c; c-basic-offset: 2 -*- * * rdfproc.c - Redland RDF command processor * * Copyright (C) 2000-2007, David Beckett http://purl.org/net/dajobe/ * Copyright (C) 2000-2005, University of Bristol, UK http://www.bristol.ac.uk/ * * This package is Free Software and part of Redland http://librdf.org/ * * It is licensed under the following three licenses as alternatives: * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version * 2. GNU General Public License (GPL) V2 or any newer version * 3. Apache License, V2.0 or any newer version * * You may not use this file except in compliance with at least one of * the above three licenses. * * See LICENSE.html or LICENSE.txt at the top of this package for the * complete terms and further detail along with the license texts for * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively. * * */ #ifdef HAVE_CONFIG_H #include #endif #ifdef WIN32 #include #endif #include #include #include #include #ifdef HAVE_GETOPT_H #include #else #include #endif #ifdef HAVE_STDLIB_H #include #endif #include #include #include #ifdef NEED_OPTIND_DECLARATION extern int optind; extern char *optarg; #endif /* one prototype needed */ int main(int argc, char *argv[]); static char *program=NULL; enum command_type { CMD_PRINT, CMD_CONTAINS, CMD_FIND, CMD_SOURCES, CMD_ARCS, CMD_TARGETS, CMD_SOURCE, CMD_ARC, CMD_TARGET, CMD_ADD, CMD_REMOVE, CMD_ADD_TYPED, CMD_PARSE_MODEL, CMD_PARSE_STREAM, CMD_ARCS_IN, CMD_ARCS_OUT, CMD_HAS_ARC_IN, CMD_HAS_ARC_OUT, CMD_QUERY_AS_BINDINGS, CMD_QUERY, CMD_SERIALIZE, CMD_REMOVE_CONTEXT, CMD_CONTEXTS, CMD_MATCH, CMD_SIZE }; typedef struct { enum command_type type; const char *name; int min_args; /* min args needed? */ int max_args; /* max args needed? */ int write; /* write to db? */ } command; static command commands[]={ {CMD_PRINT, "print", 0, 0, 0,}, {CMD_CONTAINS, "contains", 3, 3, 0}, {CMD_FIND, "find", 3, 4, 0}, {CMD_SOURCES, "sources", 2, 2, 0}, {CMD_ARCS, "arcs", 2, 2, 0}, {CMD_TARGETS, "targets", 2, 2, 0}, {CMD_SOURCE, "source", 2, 2, 0}, {CMD_ARC, "arc", 2, 2, 0}, {CMD_TARGET, "target", 2, 2, 0}, {CMD_ADD, "add", 3, 4, 1}, {CMD_REMOVE, "remove", 3, 4, 1}, {CMD_ADD_TYPED, "add-typed", 5, 6, 1}, {CMD_PARSE_MODEL, "parse", 1, 4, 1}, {CMD_PARSE_STREAM, "parse-stream", 1, 4, 1}, {CMD_ARCS_IN, "arcs-in", 1, 1, 0}, {CMD_ARCS_OUT, "arcs-out", 1, 1, 0}, {CMD_HAS_ARC_IN, "has-arc-in", 2, 2, 0}, {CMD_HAS_ARC_OUT, "has-arc-out", 2, 2, 0}, /* FIXME triples-match-query is deliberately not documented */ {CMD_QUERY, "triples-match-query", 3, 3, 0}, {CMD_QUERY_AS_BINDINGS, "query", 3, 3, 0}, {CMD_SERIALIZE, "serialize", 0, 4, 0}, {CMD_REMOVE_CONTEXT, "remove-context", 1, 1, 0}, {CMD_CONTEXTS, "contexts", 0, 0, 0}, {CMD_MATCH, "match", 3, 4, 0}, {CMD_SIZE, "size", 0, 0, 0}, {(enum command_type)-1, NULL, 0, 0, 0} }; #ifdef HAVE_GETOPT_LONG #define HELP_TEXT(short, long, description) " -" #short ", --" long " " description #define HELP_ARG(short, long) "--" #long #else #define HELP_TEXT(short, long, description) " -" #short " " description #define HELP_ARG(short, long) "-" #short #endif #define GETOPT_STRING "chno:pr:s:t:Tv" #ifdef HAVE_GETOPT_LONG static struct option long_options[] = { /* name, has_arg, flag, val */ {"contexts", 0, 0, 'c'}, {"help", 0, 0, 'h'}, {"new", 0, 0, 'n'}, {"output", 1, 0, 'o'}, {"password", 0, 0, 'p'}, {"results", 1, 0, 'r'}, {"storage", 1, 0, 's'}, {"storage-options", 1, 0, 't'}, {"transactions", 0, 0, 'T'}, {"version", 0, 0, 'v'}, {NULL, 0, 0, 0} }; #endif static const char *title_format_string="Redland RDF processor utility %s\n"; static const char *default_storage_name="hashes"; static const char *default_storage_options="hash-type='bdb',dir='.'"; static int log_handler(void *user_data, librdf_log_message *message) { /* int code=message->code; */ /* The error code */ raptor_locator *locator=(raptor_locator*)(message->locator); /* Do not handle messages below warning*/ if(message->level < LIBRDF_LOG_WARN) return 0; if(message->level == LIBRDF_LOG_WARN) fprintf(stderr, "%s: Warning - ", program); else fprintf(stderr, "%s: Error - ", program); if(locator) { /* && message->facility == LIBRDF_FROM_PARSER) */ raptor_print_locator(stderr, locator); fputc(':', stderr); fputc(' ', stderr); } fputs(message->message, stderr); fputc('\n', stderr); if(message->level >= LIBRDF_LOG_FATAL) exit(1); /* Handled */ return 1; } static void print_nodes(FILE* fh, librdf_iterator* iterator) { int count; librdf_node* context_node; librdf_node* node; /* (Common code) Print out nodes */ count=0; while(!librdf_iterator_end(iterator)) { context_node=(librdf_node*)librdf_iterator_get_context(iterator); node=(librdf_node*)librdf_iterator_get_object(iterator); if(!node) { fprintf(stderr, "%s: librdf_iterator_get_object returned NULL\n", program); break; } fputs("Matched node: ", fh); librdf_node_print(node, fh); if(context_node) { fputs(" with context ", fh); librdf_node_print(context_node, fh); } fputc('\n', fh); count++; librdf_iterator_next(iterator); } librdf_free_iterator(iterator); fprintf(stderr, "%s: matching nodes: %d\n", program, count); } static void print_node(FILE* fh, librdf_node* node) { if(node) { fputs("Matched node: ", fh); librdf_node_print(node, fh); fputc('\n', fh); librdf_free_node(node); } } int main(int argc, char *argv[]) { librdf_world* world; librdf_parser* parser; librdf_serializer* serializer; librdf_storage *storage; librdf_model* model; librdf_node *source, *arc, *target, *node; librdf_node* context_node=NULL; librdf_stream* stream; librdf_iterator* iterator; librdf_uri *uri; librdf_uri *base_uri=NULL; librdf_query *query; librdf_query_results *results; librdf_hash *options; int usage=0; int help=0; int is_new=0; char *identifier=NULL; char *cmd=NULL; char *name; char *mime_type; int cmd_index= -1; int count; int type; int result; char *p; int i; int rc; int transactions=0; char *storage_name=(char*)default_storage_name; char *storage_options=(char*)default_storage_options; char *storage_password=NULL; librdf_statement* partial_statement=NULL; unsigned char *uri_string=NULL; int free_uri_string=0; librdf_model* output_model=NULL; librdf_storage* output_storage=NULL; librdf_serializer* output_serializer=NULL; size_t capacity; size_t size; const char *query_graph_serializer_syntax_name="rdfxml"; char* results_format=NULL; program=argv[0]; if((p=strrchr(program, '/'))) program=p+1; else if((p=strrchr(program, '\\'))) program=p+1; argv[0]=program; world=librdf_new_world(); librdf_world_set_logger(world, NULL, log_handler); librdf_world_open(world); options=librdf_new_hash(world, NULL); librdf_hash_open(options, NULL, 0, 1, 1, NULL); #ifdef HAVE_GETENV if((name=getenv("RDFPROC_STORAGE_OPTIONS"))) storage_options=name; if((name=getenv("RDFPROC_STORAGE_TYPE"))) storage_name=name; #endif while (!usage && !help) { int c; #ifdef HAVE_GETOPT_LONG int option_index = 0; c = getopt_long (argc, argv, GETOPT_STRING, long_options, &option_index); #else c = getopt (argc, argv, GETOPT_STRING); #endif if(c == -1) break; switch(c) { case 0: case '?': /* getopt() - unknown option */ usage=1; break; case 'c': librdf_hash_put_strings(options, "contexts", "yes"); break; case 'h': help=1; break; case 'n': is_new=1; break; case 'o': if(optarg) { if(!strcmp(optarg, "simple")) output_serializer=NULL; else { output_serializer=librdf_new_serializer(world, optarg, NULL, NULL); if(!output_serializer) { fprintf(stderr, "%s: unknown output serializer `%s' for `" HELP_ARG(o, output) "'\n", program, optarg); fprintf(stderr, "Valid arguments are:\n `simple' for a simple format (default)\n `ntriples' for N-Triples\n"); usage=1; } else { output_storage = librdf_new_storage(world, NULL, NULL, NULL); if(!output_storage) { fprintf(stderr, "%s: Failed to create output storage\n", program); librdf_free_serializer(output_serializer); output_serializer=NULL; } else { output_model = librdf_new_model(world, output_storage, NULL); if(!output_model) { fprintf(stderr, "%s: Failed to create output storage model\n", program); librdf_free_storage(output_storage); output_storage=NULL; librdf_free_serializer(output_serializer); output_serializer=NULL; } } } } } break; case 'p': /* gets() the password from stdin, checking for input overflow */ capacity=0; size=0; while(!feof(stdin)) { if((capacity-size) < 10) { capacity += 10; p=(char*)malloc(capacity); if(storage_password) { strncpy(p, storage_password, size); free(storage_password); } storage_password=p; } rc=fgetc(stdin); /* short enough that I don't care to use fread */ if(rc == '\n' || rc == EOF) { storage_password[size]='\0'; break; } storage_password[size++]=(char)rc; } if(!size) { fprintf(stderr, "%s: WARNING: No storage password found on input\n", program); if(storage_password) { free(storage_password); storage_password=NULL; } } if(storage_password) { librdf_hash_put_strings(options, "password", storage_password); free(storage_password); } break; case 'r': if(optarg) { if(!strcmp(optarg, "help")) { fprintf(stderr, "%s: Valid query result formats are:\n", program); for(i=0; 1; i++) { const char *format_name; const char *format_label; if(rasqal_query_results_formats_enumerate(world->rasqal_world_ptr, i, &format_name, &format_label, NULL, NULL, NULL)) break; printf(" %-20s %s\n", format_name, format_label); } exit(0); } else { if(rasqal_query_results_formats_check(world->rasqal_world_ptr, optarg, NULL, NULL)) results_format=optarg; else { fprintf(stderr, "%s: invalid argument `%s' for `" HELP_ARG(r, results) "'\nTry '%s " HELP_ARG(r, results) " help' for a list of valid formats\n", program, optarg, program); usage=1; } } } break; case 's': if(optarg) { if(!librdf_get_storage_factory(world, optarg)) { fprintf(stderr, "%s: invalid storage `%s'\n", program, optarg); usage=1; } else storage_name=optarg; } break; case 't': storage_options=optarg; break; case 'T': transactions=1; break; case 'v': fputs(librdf_version_string, stdout); fputc('\n', stdout); exit(0); } } if(usage || help) goto usage; if(optind == argc) { usage=2; /* Title and usage */ goto usage; } argv+=optind; argc-=optind; identifier=argv[0]; argv++; argc--; if(!argc) { fprintf(stderr, "%s: No command given\n", program); usage=1; goto usage; } cmd=argv[0]; for(i=0; commands[i].name; i++) if(!strcmp(cmd, commands[i].name)) { cmd_index=i; break; } if(cmd_index<0) { fprintf(stderr, "%s: No such command `%s'\n", program, argv[0]); usage=1; goto usage; } argv++; argc--; if(argc < commands[cmd_index].min_args) { fprintf(stderr, "%s: Command %s needs %d arguments\n", program, cmd, commands[cmd_index].min_args); usage=1; } else if(argc > commands[cmd_index].max_args) { fprintf(stderr, "%s: Command %s given more than %d arguments\n", program, cmd, commands[cmd_index].max_args); usage=1; } /* otherwise is just fine and argv points to remaining args */ usage: if(usage) { if(usage>1) { fprintf(stderr, title_format_string, librdf_version_string); fputs(librdf_short_copyright_string, stderr); fputc('\n', stderr); } fprintf(stderr, "Try `%s " HELP_ARG(h, help) "' for more information.\n", program); exit(1); } if(help) { printf("Usage: %s [options] store-name command arg...\n", program); printf(title_format_string, librdf_version_string); puts(librdf_short_copyright_string); puts("Utility for processing RDF using the Redland library."); puts("\nMain options:"); puts(HELP_TEXT(c, "contexts ", "Use Redland contexts")); puts(HELP_TEXT(h, "help ", "Print this help, then exit")); puts(HELP_TEXT(n, "new ", "Create a new store (default no)")); puts(HELP_TEXT(o, "output FORMAT ", "Set the triple output format to one of:")); puts(" simple A simple format (default)\n ntriples N-Triples\n rdfxml RDF/XML"); puts(HELP_TEXT(p, "password ", "Read storage option 'password' from standard input")); puts(HELP_TEXT(r, "results FORMAT ", "Set the query results format")); for(i=0; 1; i++) { const char *help_name; const char *help_label; if(librdf_query_results_formats_enumerate(world, i, &help_name, &help_label, NULL, NULL)) break; printf(" %-10s %s", help_name, help_label); if(!i) puts(" (default)"); else putchar('\n'); } puts(HELP_TEXT(s, "storage TYPE ", "Set the graph storage type")); for(i=0; 1; i++) { const char *help_name; const char *help_label; if(librdf_storage_enumerate(world, i, &help_name, &help_label)) break; printf(" %-10s %s", help_name, help_label); if(!i) puts(" (default)"); else putchar('\n'); } printf(HELP_TEXT(t, "storage-options OPTIONS\n ", "Storage options (default \"%s\")\n"), default_storage_options); puts(HELP_TEXT(v, "version ", "Print the Redland version")); puts("\nCommands:"); puts(" parse FILE|URI [SYNTAX [BASEURI [CONTEXT]]]"); puts(" parse-stream FILE|URI [SYNTAX [BASEURI [CONTEXT]]]"); puts(" Parse RDF syntax (default RDF/XML) in FILE or URI into the graph"); puts(" with optional BASEURI, into the optional CONTEXT."); puts(" print Print the graph triples."); puts(" serialize [SYNTAX [URI [MIME-TYPE]]] Serializes to a syntax (RDF/XML)."); puts(" query NAME|- URI|- QUERY-STRING Run QUERY-STRING query in language NAME for bindings"); #if 0 puts(" triples-match-query NAME URI|- QUERY-STRING Query for matching triples"); #endif puts(" find SUBJECT|- PREDICATE|- OBJECT|- [CONTEXT] Find matching triples"); puts(" contains SUBJECT PREDICATE OBJECT Check if triple is in the graph."); puts(" contexts List the contexts in the graph."); puts(" add SUBJECT PREDICATE OBJECT [CONTEXT] Add triple to graph."); puts(" add-typed SUBJECT PREDICATE OBJECT OBJECT-LANG OBJECT-URI [CONTEXT]"); puts(" Add datatyped triple to graph."); puts(" remove SUBJECT PREDICATE OBJECT [CONTEXT] Remove triple from graph."); puts(" remove-context CONTEXT Remove all triples with CONTEXT."); puts(" sources | targets | arcs NODE1 NODE2 Show matching nodes."); puts(" source | target | arc NODE1 NODE2 Show 1 matching node."); puts(" arcs-in | arcs-out NODE Show properties in/out of NODE"); puts(" has-arc-in | has-arc-out NODE ARC Check for property in/out of NODE."); puts(" size Print the number of triples in the graph."); puts("\nNotation:"); puts(" nodes are either blank node identifiers like _:ABC,"); puts(" URIs like http://example.org otherwise are literal strings."); puts(" - matches any node when allowed."); puts(" triples are three nodes (subject, predicate, object)"); puts(" predicates can only be uris, only objects can be literals"); puts(" source means subject of triples matching (?, NODE1, NODE2)"); puts(" target means object of triples matching (NODE1, NODE2, ?)"); puts(" arc means predicate of triples matching (NODE1, ?, NODE2)"); puts("\nReport bugs to http://bugs.librdf.org/"); puts("Redland home page: http://librdf.org/"); exit(0); } type=commands[cmd_index].type; if(commands[cmd_index].write) { librdf_hash_put_strings(options, "write", "yes"); if(is_new) librdf_hash_put_strings(options, "new", "yes"); } librdf_hash_from_string(options, storage_options); storage=librdf_new_storage_with_options(world, storage_name, identifier, options); if(!storage) { fprintf(stderr, "%s: Failed to open %s storage '%s'\n", program, storage_name, identifier); return(1); } model=librdf_new_model(world, storage, NULL); if(!model) { fprintf(stderr, "%s: Failed to create model\n", program); return(1); } if(transactions) librdf_model_transaction_start(model); /* Do this or gcc moans */ stream=NULL; iterator=NULL; parser=NULL; serializer=NULL; source=NULL; arc=NULL; target=NULL; uri=NULL; node=NULL; query=NULL; results=NULL; switch(type) { case CMD_PRINT: librdf_model_print(model, stdout); break; case CMD_PARSE_MODEL: case CMD_PARSE_STREAM: uri_string=(unsigned char *)argv[0]; if(!access((const char*)uri_string, R_OK)) { uri_string=raptor_uri_filename_to_uri_string((char*)uri_string); free_uri_string=1; } uri=librdf_new_uri(world, uri_string); if(!uri) { fprintf(stderr, "%s: Failed to create URI from %s\n", program, argv[0]); break; } parser=librdf_new_parser(world, ((argc > 1) ? argv[1] : NULL), NULL, NULL); if(!parser) { fprintf(stderr, "%s: Failed to create new parser %s\n", program, argv[1]); librdf_free_uri(uri); break; } fprintf(stdout, "%s: Parsing URI %s with %s parser\n", program, librdf_uri_as_string(uri), (argc > 1) ? argv[1] : "default"); if(argc >= 3 && argv[2]) { base_uri=NULL; if(strcmp(argv[2], "-")) { base_uri=librdf_new_uri(world, (const unsigned char *)argv[2]); if(!base_uri) { fprintf(stderr, "%s: Failed to create base URI from %s\n", program, argv[2]); break; } } fprintf(stderr, "%s: Using base URI %s\n", program, (base_uri ? (const char*)librdf_uri_as_string(base_uri) : "NULL")); target=NULL; /* context node */ if(argc >= 4 && argv[3]) { if(librdf_heuristic_is_blank_node(argv[3])) target=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[3])); else target=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[3]); } fprintf(stderr, "%s: Using context node %s\n", program, (argv[3] ? argv[3] : "NULL")); } else base_uri=librdf_new_uri_from_uri(uri); rc=0; if(type == CMD_PARSE_MODEL && !target) { if(librdf_parser_parse_into_model(parser, uri, base_uri, model)) { fprintf(stderr, "%s: Failed to parse into the graph\n", program); rc=1; } } else { /* either CMD_PARSE_STREAM or it's a parse into context */ count=0; if(!(stream=librdf_parser_parse_as_stream(parser, uri, base_uri))) { fprintf(stderr, "%s: Failed to parse RDF as stream\n", program); rc=1; } else { while(!librdf_stream_end(stream)) { librdf_statement *statement=librdf_stream_get_object(stream); if(!statement) { fprintf(stderr, "%s: librdf_stream_next returned NULL\n", program); break; } if(target) /* context node */ librdf_model_context_add_statement(model, target, statement); else librdf_model_add_statement(model, statement); count++; librdf_stream_next(stream); } librdf_free_stream(stream); } if(target) { librdf_free_node(target); target=NULL; } fprintf(stderr, "%s: Added %d triples\n", program, count); rc=1; } if(rc) { librdf_uri* error_count_uri=librdf_new_uri(world, (const unsigned char*)LIBRDF_PARSER_FEATURE_ERROR_COUNT); librdf_uri* warning_count_uri=librdf_new_uri(world, (const unsigned char*)LIBRDF_PARSER_FEATURE_WARNING_COUNT); librdf_node* error_count_node; librdf_node* warning_count_node; int error_count, warning_count; error_count_node=librdf_parser_get_feature(parser, error_count_uri); if(error_count_node) { error_count=atoi((const char*)librdf_node_get_literal_value(error_count_node)); librdf_free_node(error_count_node); } else { fprintf(stderr, "%s: Could not get parsing error count\n", program); error_count= (-1); } warning_count_node=librdf_parser_get_feature(parser, warning_count_uri); if(warning_count_node) { warning_count=atoi((const char*)librdf_node_get_literal_value(error_count_node)); librdf_free_node(warning_count_node); } else { fprintf(stderr, "%s: Could not get parsing warning count\n", program); warning_count= (-1); } if((error_count >=0) && (warning_count >=0) && error_count+warning_count >0) fprintf(stderr, "%s: The parsing returned %d errors and %d warnings\n", program, error_count, warning_count); librdf_free_uri(error_count_uri); librdf_free_uri(warning_count_uri); } librdf_free_parser(parser); librdf_free_uri(uri); if(base_uri) librdf_free_uri(base_uri); break; case CMD_SERIALIZE: /* args are name (optional), uri (may be NULL), mime_type * (optional), base URI (optional) */ uri=NULL; name=NULL; mime_type=NULL; base_uri=NULL; if(!argc) goto serialize; if(strcmp(argv[0], "-")) name=argv[0]; if(argc < 2) goto serialize; if(strcmp(argv[1], "-")) { uri=librdf_new_uri(world, (const unsigned char *)argv[1]); if(!uri) { fprintf(stderr, "%s: Failed to create URI from %s\n", program, argv[1]); break; } } if(argc == 3) { if(strcmp(argv[2], "-")) mime_type=argv[2]; } if(argc == 4) { if(strcmp(argv[3], "-")) { base_uri=librdf_new_uri(world, (const unsigned char *)argv[3]); if(!base_uri) { fprintf(stderr, "%s: Failed to create base URI from %s\n", program, argv[3]); break; } } } serialize: serializer=librdf_new_serializer(world, name, mime_type, uri); if(!serializer) { fprintf(stderr, "%s: Failed to create new serializer name %s, uri %s, mime type %s\n", program, argv[0], argv[1], argv[2]); if(uri) librdf_free_uri(uri); break; } librdf_serializer_serialize_model_to_file_handle(serializer, stdout, NULL, model); librdf_free_serializer(serializer); if(uri) librdf_free_uri(uri); break; case CMD_QUERY: /* args are name, uri (may be NULL), query_string/mime_type */ name=argv[0]; if(!strcmp(name, "-")) name=NULL; if(!strcmp(argv[1], "-")) uri=NULL; else { uri=librdf_new_uri(world, (const unsigned char *)argv[1]); if(!uri) { fprintf(stderr, "%s: Failed to create URI from %s\n", program, argv[1]); break; } } query=librdf_new_query(world, name, uri, (const unsigned char *)argv[2], NULL); goto printmatching; break; case CMD_QUERY_AS_BINDINGS: /* args are name (optional), uri (may be NULL), query_string */ uri=NULL; name=NULL; if(strcmp(argv[0], "-")) name=argv[0]; if(!strcmp(argv[1], "-")) uri=NULL; else { uri=librdf_new_uri(world, (const unsigned char *)argv[1]); if(!uri) { fprintf(stderr, "%s: Failed to create URI from %s\n", program, argv[1]); break; } } query=librdf_new_query(world, name, uri, (const unsigned char *)argv[2], NULL); if(!query) { fprintf(stderr, "%s: Failed to create new query %s\n", program, argv[2]); if(uri) librdf_free_uri(uri); break; } if(!(results=librdf_model_query_execute(model, query))) { fprintf(stderr, "%s: Query of model with '%s' failed\n", program, argv[2]); if(uri) librdf_free_uri(uri); librdf_free_query(query); query=NULL; break; } if(results_format) { raptor_iostream *iostr; librdf_query_results_formatter *formatter; fprintf(stdout, "%s: Formatting query result as '%s':\n", program, results_format); iostr=raptor_new_iostream_to_file_handle(stdout); formatter=librdf_new_query_results_formatter(results, results_format, NULL); librdf_query_results_formatter_write(iostr, formatter, results, base_uri); librdf_free_query_results_formatter(formatter); raptor_free_iostream(iostr); } else if(librdf_query_results_is_bindings(results)) { fprintf(stdout, "%s: Query returned bindings results:\n", program); while(!librdf_query_results_finished(results)) { fputs("result: [", stdout); for(i=0; i0) fputs(", ", stdout); fprintf(stdout, "%s=", name); if(value) { librdf_node_print(value, stdout); librdf_free_node(value); } else fputs("NULL", stdout); } fputs("]\n", stdout); librdf_query_results_next(results); } fprintf(stdout, "%s: Query returned %d results\n", program, librdf_query_results_get_count(results)); } else if(librdf_query_results_is_boolean(results)) { fprintf(stdout, "%s: Query returned boolean result: %s\n", program, librdf_query_results_get_boolean(results) ? "true" : "false"); } else if(librdf_query_results_is_graph(results)) { librdf_storage* tmp_storage; librdf_model* tmp_model; tmp_storage=librdf_new_storage(world, NULL, NULL, NULL); tmp_model=librdf_new_model(world, tmp_storage, NULL); fprintf(stdout, "%s: Query returned graph result:\n", program); stream=librdf_query_results_as_stream(results); if(!stream) { fprintf(stderr, "%s: Failed to get query results graph\n", program); return(1); } librdf_model_add_statements(tmp_model, stream); librdf_free_stream(stream); fprintf(stdout, "%s: Total %d triples\n", program, librdf_model_size(model)); serializer=librdf_new_serializer(world, query_graph_serializer_syntax_name, NULL, NULL); if(!serializer) { fprintf(stderr, "%s: Failed to create serializer type %s\n", program, query_graph_serializer_syntax_name); return(1); } librdf_serializer_serialize_model_to_file_handle(serializer, stdout, NULL, tmp_model); librdf_free_serializer(serializer); librdf_free_model(tmp_model); librdf_free_storage(tmp_storage); } else { fprintf(stdout, "%s: Query returned unknown result format\n", program); rc=1; } if(uri) librdf_free_uri(uri); librdf_free_query_results(results); break; case CMD_CONTAINS: case CMD_FIND: case CMD_MATCH: case CMD_ADD: case CMD_REMOVE: case CMD_ADD_TYPED: if(!strcmp(argv[0], "-")) source=NULL; else if(librdf_heuristic_is_blank_node(argv[0])) source=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[0])); else source=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[0]); if(!strcmp(argv[1], "-")) arc=NULL; else arc=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[1]); if(type == CMD_ADD_TYPED) { char *lang=(strcmp(argv[3], "-")) ? argv[3] : NULL; librdf_uri* dt_uri=librdf_new_uri(world, (const unsigned char *)argv[4]); target=librdf_new_node_from_typed_literal(world, (const unsigned char *)argv[2], lang, dt_uri); librdf_free_uri(dt_uri); } else { if(!strcmp(argv[2], "-")) target=NULL; else { if(!strncmp(argv[2], "_:", 2)) target=librdf_new_node_from_blank_identifier(world, (const unsigned char *)argv[2]+2); else if(librdf_heuristic_object_is_literal(argv[2])) target=librdf_new_node_from_literal(world, (const unsigned char *)argv[2], NULL, 0); else target=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[2]); } } partial_statement=librdf_new_statement(world); librdf_statement_set_subject(partial_statement, source); librdf_statement_set_predicate(partial_statement, arc); librdf_statement_set_object(partial_statement, target); if((type != CMD_FIND) && (type != CMD_MATCH)) { if(!source || !arc || !target) { fprintf(stderr, "%s: cannot have missing triple parts for %s\n", program, cmd); librdf_free_statement(partial_statement); break; } } printmatching: switch(type) { case CMD_CONTAINS: if(librdf_model_contains_statement(model, partial_statement)) fprintf(stdout, "%s: the graph contains the triple\n", program); else fprintf(stdout, "%s: the graph does not contain the triple\n", program); break; case CMD_FIND: case CMD_MATCH: case CMD_QUERY: /* Print out matching statements */ if(type==CMD_FIND || type==CMD_MATCH) { if(argc == 4 || type==CMD_MATCH) { if(argc == 4) { if(librdf_heuristic_is_blank_node(argv[3])) context_node=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[3])); else context_node=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[3]); } if(type == CMD_MATCH) { librdf_hash* match_options=librdf_new_hash(world, NULL); librdf_hash_open(match_options, NULL, 0, 1, 1, NULL); librdf_hash_put_strings(match_options, "match-substring", "yes"); stream=librdf_model_find_statements_with_options(model, partial_statement, context_node, match_options); librdf_free_hash(match_options); } else { stream=librdf_model_find_statements_in_context(model, partial_statement, context_node); } if(context_node) librdf_free_node(context_node); } else stream=librdf_model_find_statements(model, partial_statement); } else { if(!(results=librdf_model_query_execute(model, query))) { fprintf(stderr, "%s: Query of model with '%s' failed\n", program, argv[2]); librdf_free_query(query); query=NULL; break; } stream=librdf_query_results_as_stream(results); } if(!stream) { fprintf(stderr, "%s: %s returned no results (NULL stream)\n", program, commands[type].name); } else { count=0; while(!librdf_stream_end(stream)) { librdf_statement *statement=librdf_stream_get_object(stream); context_node=(librdf_node*)librdf_stream_get_context(stream); if(!statement) { fprintf(stderr, "%s: librdf_stream_next returned NULL\n", program); break; } if(output_model) { librdf_model_add_statement(output_model, librdf_new_statement_from_statement(statement)); } else { fputs("Matched triple: ", stdout); librdf_statement_print(statement, stdout); if(context_node) { fputs(" with context ", stdout); librdf_node_print(context_node, stdout); } fputc('\n', stdout); } count++; librdf_stream_next(stream); } librdf_free_stream(stream); if(!output_model) fprintf(stderr, "%s: matching triples: %d\n", program, count); if(results) librdf_free_query_results(results); } break; case CMD_ADD: case CMD_ADD_TYPED: if(argv[3]) { if(librdf_heuristic_is_blank_node(argv[3])) context_node=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[3])); else context_node=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[3]); rc=librdf_model_context_add_statement(model, context_node, partial_statement); librdf_free_node(context_node); } else { if(argv[3]) fprintf(stderr, "%s: ERROR: Cannot add in context - model does not support contexts\n", program); rc=librdf_model_add_statement(model, partial_statement); } if(rc) fprintf(stdout, "%s: failed to add triple to the graph\n", program); else fprintf(stdout, "%s: added triple to the graph\n", program); break; case CMD_REMOVE: if(argv[3]) { if(librdf_heuristic_is_blank_node(argv[3])) context_node=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[3])); else context_node=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[3]); rc=librdf_model_context_remove_statement(model, context_node, partial_statement); librdf_free_node(context_node); } else rc=librdf_model_remove_statement(model, partial_statement); if(rc) fprintf(stdout, "%s: failed to remove triple from the graph\n", program); else fprintf(stdout, "%s: removed triple from the graph\n", program); break; default: fprintf(stderr, "Unexpected command %d\n", type); } /* end inner switch */ /* also frees the nodes */ librdf_free_statement(partial_statement); break; case CMD_SOURCES: arc=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[0]); if(librdf_heuristic_is_blank_node(argv[1])) target=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[1])); else if(librdf_heuristic_object_is_literal(argv[1])) target=librdf_new_node_from_literal(world, (const unsigned char *)argv[1], NULL, 0); else target=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[1]); iterator=librdf_model_get_sources(model, arc, target); if(!iterator) { fprintf(stderr, "%s: Failed to get sources\n", program); break; } print_nodes(stdout, iterator); librdf_free_node(arc); librdf_free_node(target); break; case CMD_ARCS: if(!iterator) { if(librdf_heuristic_is_blank_node(argv[0])) source=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[0])); else source=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[0]); if(librdf_heuristic_is_blank_node(argv[1])) target=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[1])); else if(librdf_heuristic_object_is_literal(argv[1])) target=librdf_new_node_from_literal(world, (const unsigned char *)argv[1], NULL, 0); else target=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[1]); iterator=librdf_model_get_arcs(model, source, target); if(!iterator) { fprintf(stderr, "Failed to get arcs\n"); break; } } print_nodes(stdout, iterator); librdf_free_node(source); librdf_free_node(target); break; case CMD_TARGETS: if(!iterator) { if(librdf_heuristic_is_blank_node(argv[0])) source=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[0])); else source=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[0]); arc=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[1]); iterator=librdf_model_get_targets(model, source, arc); if(!iterator) { fprintf(stderr, "%s: Failed to get targets\n", program); break; } } print_nodes(stdout, iterator); librdf_free_node(source); librdf_free_node(arc); break; case CMD_SOURCE: arc=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[0]); if(librdf_heuristic_is_blank_node(argv[1])) target=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[1])); else if(librdf_heuristic_object_is_literal(argv[1])) target=librdf_new_node_from_literal(world, (const unsigned char *)argv[1], NULL, 0); else target=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[1]); node=librdf_model_get_source(model, arc, target); if(!node) { fprintf(stderr, "%s: Failed to get source\n", program); librdf_free_node(arc); librdf_free_node(target); break; } print_node(stdout, node); librdf_free_node(arc); librdf_free_node(target); break; case CMD_ARC: if(!node) { if(librdf_heuristic_is_blank_node(argv[0])) source=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[0])); else source=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[0]); if(librdf_heuristic_is_blank_node(argv[1])) target=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[1])); else if(librdf_heuristic_object_is_literal(argv[1])) target=librdf_new_node_from_literal(world, (const unsigned char *)argv[1], NULL, 0); else target=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[1]); node=librdf_model_get_arc(model, source, target); if(!node) { fprintf(stderr, "Failed to get arc\n"); librdf_free_node(source); librdf_free_node(target); break; } } print_node(stdout, node); librdf_free_node(source); librdf_free_node(target); break; case CMD_TARGET: if(!node) { if(librdf_heuristic_is_blank_node(argv[0])) source=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[0])); else source=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[0]); arc=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[1]); node=librdf_model_get_target(model, source, arc); if(!node) { fprintf(stderr, "%s: Failed to get target\n", program); librdf_free_node(source); librdf_free_node(arc); break; } } print_node(stdout, node); librdf_free_node(source); librdf_free_node(arc); break; case CMD_ARCS_IN: case CMD_ARCS_OUT: if(librdf_heuristic_is_blank_node(argv[0])) source=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[0])); else source=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[0]); iterator=(type == CMD_ARCS_IN) ? librdf_model_get_arcs_in(model, source) : librdf_model_get_arcs_out(model, source); if(!iterator) { fprintf(stderr, "%s: Failed to get arcs in/out\n", program); librdf_free_node(source); break; } count=0; while(!librdf_iterator_end(iterator)) { context_node=(librdf_node*)librdf_iterator_get_context(iterator); node=(librdf_node*)librdf_iterator_get_object(iterator); if(!node) { fprintf(stderr, "%s: librdf_iterator_get_next returned NULL\n", program); break; } fputs("Matched arc: ", stdout); librdf_node_print(node, stdout); if(context_node) { fputs(" with context ", stdout); librdf_node_print(context_node, stdout); } fputc('\n', stdout); librdf_free_node(node); count++; librdf_iterator_next(iterator); } librdf_free_iterator(iterator); fprintf(stderr, "%s: matching arcs: %d\n", program, count); librdf_free_node(source); break; case CMD_HAS_ARC_IN: case CMD_HAS_ARC_OUT: if(librdf_heuristic_is_blank_node(argv[0])) source=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[0])); else source=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[0]); arc=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[1]); result=(type == CMD_HAS_ARC_IN) ? librdf_model_has_arc_in(model, arc, source) : librdf_model_has_arc_out(model, source, arc); if(result) fprintf(stdout, "%s: the graph contains the arc\n", program); else fprintf(stdout, "%s: the graph does not contain the arc\n", program); librdf_free_node(source); librdf_free_node(arc); break; case CMD_REMOVE_CONTEXT: if(librdf_heuristic_is_blank_node(argv[0])) context_node=librdf_new_node_from_blank_identifier(world, (const unsigned char *)librdf_heuristic_get_blank_node(argv[0])); else context_node=librdf_new_node_from_uri_string(world, (const unsigned char *)argv[0]); rc=librdf_model_context_remove_statements(model, context_node); librdf_free_node(context_node); if(rc) fprintf(stdout, "%s: failed to remove context triples from the graph\n", program); else fprintf(stdout, "%s: removed context triples from the graph\n", program); break; case CMD_CONTEXTS: iterator=librdf_model_get_contexts(model); if(!iterator) { fprintf(stderr, "%s: Failed to get contexts\n", program); break; } count=0; while(!librdf_iterator_end(iterator)) { node=(librdf_node*)librdf_iterator_get_object(iterator); if(!node) { fprintf(stderr, "%s: librdf_iterator_get_next returned NULL\n", program); break; } fputs("Context: ", stdout); librdf_node_print(node, stdout); fputc('\n', stdout); librdf_free_node(node); count++; librdf_iterator_next(iterator); } librdf_free_iterator(iterator); fprintf(stderr, "%s: contexts: %d\n", program, count); break; case CMD_SIZE: count=librdf_model_size(model); if(count >= 0) fprintf(stderr, "%s: graph has %d triples\n", program, count); else fprintf(stderr, "%s: graph has unknown number of triples\n", program); break; default: fprintf(stderr, "%s: Unknown command %d\n", program, type); return(1); } if(query) librdf_free_query(query); if(free_uri_string) free(uri_string); if(output_model) { if(librdf_serializer_serialize_model_to_file_handle(output_serializer, stdout, NULL, output_model)) { fprintf(stderr, "%s: Failed to serialize output model\n", program); }; librdf_free_serializer(output_serializer); librdf_free_model(output_model); librdf_free_storage(output_storage); } librdf_free_hash(options); if(transactions) librdf_model_transaction_commit(model); librdf_free_model(model); librdf_free_storage(storage); librdf_free_world(world); #ifdef LIBRDF_MEMORY_DEBUG librdf_memory_report(stderr); #endif /* keep gcc -Wall happy */ return(0); }