mirror of
				https://github.com/cookiengineer/audacity
				synced 2025-11-04 08:04:06 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			1919 lines
		
	
	
		
			53 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1919 lines
		
	
	
		
			53 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* -*- Mode: c; c-basic-offset: 2 -*-
 | 
						|
 *
 | 
						|
 * rdf_storage.c - RDF Storage (Triple store) interface
 | 
						|
 *
 | 
						|
 * Copyright (C) 2000-2008, David Beckett http://www.dajobe.org/
 | 
						|
 * 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 <rdf_config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef WIN32
 | 
						|
#include <win32_rdf_config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include <string.h>
 | 
						|
#include <ctype.h>
 | 
						|
#include <sys/types.h>
 | 
						|
#ifdef HAVE_STDLIB_H
 | 
						|
#include <stdlib.h> /* for abort() as used in errors */
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef MODULAR_LIBRDF
 | 
						|
#include <ltdl.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <redland.h>
 | 
						|
#include <rdf_storage.h>
 | 
						|
 | 
						|
 | 
						|
#ifndef STANDALONE
 | 
						|
 | 
						|
/* prototypes for functions implementing get_sources, arcs, targets
 | 
						|
 * librdf_iterator via conversion from a librdf_stream of librdf_statement
 | 
						|
 */
 | 
						|
static int librdf_storage_stream_to_node_iterator_is_end(void* iterator);
 | 
						|
static int librdf_storage_stream_to_node_iterator_next_method(void* iterator);
 | 
						|
static void* librdf_storage_stream_to_node_iterator_get_method(void* iterator, int flags);
 | 
						|
static void librdf_storage_stream_to_node_iterator_finished(void* iterator);
 | 
						|
 | 
						|
/* helper function for creating iterators for get sources, targets, arcs */
 | 
						|
static librdf_iterator* librdf_storage_node_stream_to_node_create(librdf_storage* storage, librdf_node* node1, librdf_node *node2, librdf_statement_part want);
 | 
						|
 | 
						|
#ifdef MODULAR_LIBRDF
 | 
						|
/* helper function for dynamically loading storage modules */
 | 
						|
static lt_dlhandle
 | 
						|
librdf_storage_load_module(librdf_world *world,
 | 
						|
                           const char* lib_name,
 | 
						|
                           const char* init_func_name);
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_init_storage:
 | 
						|
 * @world: redland world object
 | 
						|
 *
 | 
						|
 * INTERNAL - Initialise the storage module.
 | 
						|
 * 
 | 
						|
 * Initialises and registers all
 | 
						|
 * compiled storage modules.  Must be called before using any of the storage
 | 
						|
 * factory functions such as librdf_get_storage_factory()
 | 
						|
 **/
 | 
						|
void
 | 
						|
librdf_init_storage(librdf_world *world)
 | 
						|
{
 | 
						|
#ifdef MODULAR_LIBRDF
 | 
						|
  lt_dlhandle module = NULL;
 | 
						|
 | 
						|
  if (!world->storage_modules)
 | 
						|
    world->storage_modules = raptor_new_sequence(
 | 
						|
        (raptor_sequence_free_handler *)lt_dlclose, NULL);
 | 
						|
#endif
 | 
						|
 | 
						|
  /* Always have storage memory - must always be the default storage */
 | 
						|
  librdf_init_storage_list(world);
 | 
						|
 | 
						|
  /* Always have storage list, hashes, file implementations available */
 | 
						|
  librdf_init_storage_hashes(world);
 | 
						|
 | 
						|
#ifdef STORAGE_TREES
 | 
						|
  librdf_init_storage_trees(world);
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef MODULAR_LIBRDF
 | 
						|
 | 
						|
  #ifdef STORAGE_FILE
 | 
						|
    module = librdf_storage_load_module(world, "librdf_storage_file",
 | 
						|
                                        "librdf_init_storage_file");
 | 
						|
    if (module)
 | 
						|
      raptor_sequence_push(world->storage_modules, module);
 | 
						|
  #endif
 | 
						|
  
 | 
						|
  #ifdef STORAGE_MYSQL
 | 
						|
    module = librdf_storage_load_module(world, "librdf_storage_mysql",
 | 
						|
                                        "librdf_init_storage_mysql");
 | 
						|
    if (module)
 | 
						|
      raptor_sequence_push(world->storage_modules, module);
 | 
						|
  #endif
 | 
						|
  
 | 
						|
  #ifdef STORAGE_POSTGRESQL
 | 
						|
    module = librdf_storage_load_module(world, "librdf_storage_postgresql",
 | 
						|
                                        "librdf_init_storage_postgresql");
 | 
						|
    if (module)
 | 
						|
      raptor_sequence_push(world->storage_modules, module);
 | 
						|
  #endif
 | 
						|
  
 | 
						|
  #ifdef STORAGE_TSTORE
 | 
						|
    module = librdf_storage_load_module(world, "librdf_storage_tstore",
 | 
						|
                                        "librdf_init_storage_tstore");
 | 
						|
    if (module)
 | 
						|
      raptor_sequence_push(world->storage_modules, module);
 | 
						|
  #endif
 | 
						|
  
 | 
						|
  #ifdef STORAGE_SQLITE
 | 
						|
    module = librdf_storage_load_module(world, "librdf_storage_sqlite",
 | 
						|
                                        "librdf_init_storage_sqlite");
 | 
						|
    if (module)
 | 
						|
      raptor_sequence_push(world->storage_modules, module);
 | 
						|
  #endif
 | 
						|
 | 
						|
#else /* if !MODULAR_LIBRDF */
 | 
						|
  
 | 
						|
  #ifdef STORAGE_FILE
 | 
						|
    librdf_init_storage_file(world);
 | 
						|
  #endif
 | 
						|
  #ifdef STORAGE_MYSQL
 | 
						|
    librdf_init_storage_mysql(world);
 | 
						|
  #endif
 | 
						|
  #ifdef STORAGE_POSTGRESQL
 | 
						|
    librdf_init_storage_postgresql(world);
 | 
						|
  #endif
 | 
						|
  #ifdef STORAGE_TSTORE
 | 
						|
    librdf_init_storage_tstore(world);
 | 
						|
  #endif
 | 
						|
  #ifdef STORAGE_SQLITE
 | 
						|
    librdf_init_storage_sqlite(world);
 | 
						|
  #endif
 | 
						|
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_finish_storage:
 | 
						|
 * @world: redland world object
 | 
						|
 *
 | 
						|
 * INTERNAL - Terminate the storage module.
 | 
						|
 *
 | 
						|
 **/
 | 
						|
void
 | 
						|
librdf_finish_storage(librdf_world *world) 
 | 
						|
{
 | 
						|
#ifdef MODULAR_LIBRDF
 | 
						|
  if(world->storage_modules) {
 | 
						|
    raptor_free_sequence(world->storage_modules);
 | 
						|
    world->storage_modules=NULL;
 | 
						|
  }
 | 
						|
#endif
 | 
						|
  
 | 
						|
  if(world->storages) {
 | 
						|
    raptor_free_sequence(world->storages);
 | 
						|
    world->storages=NULL;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/* helper functions */
 | 
						|
 | 
						|
 | 
						|
static void
 | 
						|
librdf_free_storage_factory(librdf_storage_factory* factory)
 | 
						|
{
 | 
						|
  if(factory->name)
 | 
						|
    LIBRDF_FREE(librdf_storage_factory, factory->name);
 | 
						|
  if(factory->label)
 | 
						|
    LIBRDF_FREE(librdf_storage_factory, factory->label);
 | 
						|
  LIBRDF_FREE(librdf_storage_factory, factory);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#ifdef MODULAR_LIBRDF
 | 
						|
/**
 | 
						|
 * librdf_storage_load_module:
 | 
						|
 * @world: redland world object
 | 
						|
 * @lib_name: base name of shared library file
 | 
						|
 * @init_func_name: name of initialization function in library
 | 
						|
 *
 | 
						|
 * INTERNAL - Load and initialize/register a storage module
 | 
						|
 **/
 | 
						|
static lt_dlhandle
 | 
						|
librdf_storage_load_module(librdf_world *world,
 | 
						|
                           const char* lib_name,
 | 
						|
                           const char* init_func_name)
 | 
						|
{
 | 
						|
  typedef void init_func_t(librdf_world* world);
 | 
						|
  init_func_t* init;
 | 
						|
 | 
						|
  lt_dlhandle module = lt_dlopenext(lib_name);
 | 
						|
  if (module) {
 | 
						|
    init = (init_func_t*)lt_dlsym(module, init_func_name);
 | 
						|
    if (init) {
 | 
						|
      init(world);
 | 
						|
    } else {
 | 
						|
      LIBRDF_DEBUG2("Failed to initialize storage module %s\n", lib_name);
 | 
						|
      lt_dlclose(module);
 | 
						|
      module = NULL;
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    LIBRDF_DEBUG2("Failed to load storage module %s\n", lib_name);
 | 
						|
  }
 | 
						|
 | 
						|
  return module;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
/* class methods */
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_register_factory:
 | 
						|
 * @world: redland world object
 | 
						|
 * @name: the storage factory name
 | 
						|
 * @label: the storage factory label
 | 
						|
 * @factory: pointer to function to call to register the factory
 | 
						|
 *
 | 
						|
 * Register a storage factory.
 | 
						|
 **/
 | 
						|
void
 | 
						|
librdf_storage_register_factory(librdf_world* world,
 | 
						|
                                const char *name, const char *label,
 | 
						|
                                void (*factory) (librdf_storage_factory*)) 
 | 
						|
{
 | 
						|
  librdf_storage_factory *storage;
 | 
						|
  int i;
 | 
						|
 | 
						|
  librdf_world_open(world);
 | 
						|
 | 
						|
#if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1
 | 
						|
  LIBRDF_DEBUG2("Received registration for storage %s\n", name);
 | 
						|
#endif
 | 
						|
 | 
						|
  if(!world->storages) {
 | 
						|
    world->storages=raptor_new_sequence((raptor_sequence_free_handler *)librdf_free_storage_factory, NULL);
 | 
						|
    if(!world->storages)
 | 
						|
      goto oom;
 | 
						|
  }
 | 
						|
 | 
						|
  for(i=0;
 | 
						|
      (storage=(librdf_storage_factory*)raptor_sequence_get_at(world->storages, i));
 | 
						|
      i++) {
 | 
						|
    if(!strcmp(storage->name, name)) {
 | 
						|
      librdf_log(world,
 | 
						|
                 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
 | 
						|
                 "storage %s already registered", storage->name);
 | 
						|
      return;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  storage=(librdf_storage_factory*)LIBRDF_CALLOC(librdf_storage_factory, 1,
 | 
						|
                                                 sizeof(librdf_storage_factory));
 | 
						|
  if(!storage)
 | 
						|
    goto oom;
 | 
						|
 | 
						|
  storage->name=(char*)LIBRDF_MALLOC(cstring, strlen(name)+1);
 | 
						|
  if(!storage->name)
 | 
						|
    goto oom_tidy;
 | 
						|
  strcpy(storage->name, name);
 | 
						|
 | 
						|
  storage->label=(char*)LIBRDF_MALLOC(cstring, strlen(label)+1);
 | 
						|
  if(!storage->label)
 | 
						|
    goto oom_tidy;
 | 
						|
  strcpy(storage->label, label);
 | 
						|
 | 
						|
  if(raptor_sequence_push(world->storages, storage))
 | 
						|
    goto oom;
 | 
						|
 | 
						|
  /* Call the storage registration function on the new object */
 | 
						|
  (*factory)(storage);
 | 
						|
 | 
						|
#if defined(LIBRDF_DEBUG) && LIBRDF_DEBUG > 1
 | 
						|
  LIBRDF_DEBUG3("%s has context size %d\n", name, storage->context_length);
 | 
						|
#endif
 | 
						|
 | 
						|
  return;
 | 
						|
 | 
						|
  oom_tidy:
 | 
						|
  librdf_free_storage_factory(storage);
 | 
						|
  oom:
 | 
						|
  LIBRDF_FATAL1(world, LIBRDF_FROM_STORAGE, "Out of memory");
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_get_storage_factory:
 | 
						|
 * @world: redland world object
 | 
						|
 * @name: the factory name or NULL for the default factory
 | 
						|
 *
 | 
						|
 * Get a storage factory by name.
 | 
						|
 * 
 | 
						|
 * Return value: the factory object or NULL if there is no such factory
 | 
						|
 **/
 | 
						|
librdf_storage_factory*
 | 
						|
librdf_get_storage_factory(librdf_world* world, const char *name) 
 | 
						|
{
 | 
						|
  librdf_storage_factory *factory;
 | 
						|
 | 
						|
  librdf_world_open(world);
 | 
						|
 | 
						|
  /* return 1st storage if no particular one wanted - why? */
 | 
						|
  if(!name) {
 | 
						|
    factory=(librdf_storage_factory *)raptor_sequence_get_at(world->storages, 0);
 | 
						|
    if(!factory) {
 | 
						|
      LIBRDF_DEBUG1("No (default) storages registered\n");
 | 
						|
      return NULL;
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    int i;
 | 
						|
    
 | 
						|
    for(i=0;
 | 
						|
        (factory=(librdf_storage_factory*)raptor_sequence_get_at(world->storages, i));
 | 
						|
        i++) {
 | 
						|
      if(!strcmp(factory->name, name))
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    /* else FACTORY name not found */
 | 
						|
    if(!factory) {
 | 
						|
      LIBRDF_DEBUG2("No storage with name %s found\n", name);
 | 
						|
      return NULL;
 | 
						|
    }
 | 
						|
  }
 | 
						|
        
 | 
						|
  return factory;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_enumerate:
 | 
						|
 * @world: redland world object
 | 
						|
 * @counter: index into the list of storages
 | 
						|
 * @name: pointer to store the name of the storage (or NULL)
 | 
						|
 * @label: pointer to store syntax readable label (or NULL)
 | 
						|
 *
 | 
						|
 * Get information on storages.
 | 
						|
 * 
 | 
						|
 * Return value: non 0 on failure of if counter is out of range
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_enumerate(librdf_world* world,
 | 
						|
                         const unsigned int counter,
 | 
						|
                         const char **name, const char **label)
 | 
						|
{
 | 
						|
  librdf_storage_factory *factory;
 | 
						|
  
 | 
						|
  librdf_world_open(world);
 | 
						|
 | 
						|
  factory=(librdf_storage_factory*)raptor_sequence_get_at(world->storages,
 | 
						|
                                                          counter);
 | 
						|
  if(!factory)
 | 
						|
    return 1;
 | 
						|
  
 | 
						|
  if(name)
 | 
						|
    *name=factory->name;
 | 
						|
  if(label)
 | 
						|
    *label=factory->label;
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_new_storage:
 | 
						|
 * @world: redland world object
 | 
						|
 * @storage_name: the storage factory name
 | 
						|
 * @name: an identifier for the storage
 | 
						|
 * @options_string: options to initialise storage
 | 
						|
 *
 | 
						|
 * Constructor - create a new #librdf_storage object.
 | 
						|
 *
 | 
						|
 * The options are encoded as described in librdf_hash_from_string()
 | 
						|
 * and can be NULL if none are required.
 | 
						|
 *
 | 
						|
 * Return value: a new #librdf_storage object or NULL on failure
 | 
						|
 *
 | 
						|
 */
 | 
						|
librdf_storage*
 | 
						|
librdf_new_storage(librdf_world *world, 
 | 
						|
                   const char *storage_name, const char *name, 
 | 
						|
                   const char *options_string)
 | 
						|
{
 | 
						|
  librdf_storage_factory* factory;
 | 
						|
  librdf_hash* options_hash;
 | 
						|
  
 | 
						|
  librdf_world_open(world);
 | 
						|
 | 
						|
  factory=librdf_get_storage_factory(world, storage_name);
 | 
						|
  if(!factory)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  options_hash=librdf_new_hash(world, NULL);
 | 
						|
  if(!options_hash)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  if(librdf_hash_open(options_hash, NULL, 0, 1, 1, NULL)) {
 | 
						|
    librdf_free_hash(options_hash);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
  
 | 
						|
  if(librdf_hash_from_string(options_hash, options_string)) {
 | 
						|
    librdf_free_hash(options_hash);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  return librdf_new_storage_from_factory(world, factory, name, options_hash);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_new_storage_with_options:
 | 
						|
 * @world: redland world object
 | 
						|
 * @storage_name: the storage factory name
 | 
						|
 * @name: an identifier for the storage
 | 
						|
 * @options: #librdf_hash of options to use
 | 
						|
 *
 | 
						|
 * Constructor - create a new #librdf_storage object.
 | 
						|
 *
 | 
						|
 * The options can be NULL if none are required.
 | 
						|
 *
 | 
						|
 * Return value: a new #librdf_storage object or NULL on failure
 | 
						|
 *
 | 
						|
 */
 | 
						|
librdf_storage*
 | 
						|
librdf_new_storage_with_options(librdf_world *world, 
 | 
						|
                                const char *storage_name, const char *name, 
 | 
						|
                                librdf_hash *options)
 | 
						|
{
 | 
						|
  librdf_storage_factory* factory;
 | 
						|
  librdf_hash* options_hash;
 | 
						|
  
 | 
						|
  librdf_world_open(world);
 | 
						|
 | 
						|
  factory=librdf_get_storage_factory(world, storage_name);
 | 
						|
  if(!factory)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  options_hash=librdf_new_hash_from_hash(options);
 | 
						|
  if(!options_hash)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  if(librdf_hash_open(options_hash, NULL, 0, 1, 1, NULL)) {
 | 
						|
    librdf_free_hash(options_hash);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
  
 | 
						|
  return librdf_new_storage_from_factory(world, factory, name, options_hash);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_new_storage_from_storage - Copy constructor - create a new librdf_storage object from an existing one
 | 
						|
 * @old_storage: the existing storage #librdf_storage to use
 | 
						|
 *
 | 
						|
 * Should create a new storage in the same context as the existing one
 | 
						|
 * as appropriate for the storage.  For example, in a RDBMS storage
 | 
						|
 * it would be a new database, or in on disk it would be a new
 | 
						|
 * set of files.  This will mean automatically generating
 | 
						|
 * a new identifier for the storage, maybe based on the existing
 | 
						|
 * storage identifier.
 | 
						|
 *
 | 
						|
 * Return value: a new #librdf_storage object or NULL on failure
 | 
						|
 *
 | 
						|
 */
 | 
						|
librdf_storage*
 | 
						|
librdf_new_storage_from_storage(librdf_storage* old_storage) 
 | 
						|
{
 | 
						|
  librdf_storage* new_storage;
 | 
						|
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(old_storage, librdf_storage, NULL);
 | 
						|
 | 
						|
  if(!old_storage->factory->clone) {
 | 
						|
    librdf_log(old_storage->world,
 | 
						|
               0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
 | 
						|
               "clone method not implemented for storage factory %s", 
 | 
						|
               old_storage->factory->name);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  new_storage=(librdf_storage*)LIBRDF_CALLOC(librdf_storage, 1,
 | 
						|
                                             sizeof(librdf_storage));
 | 
						|
  if(!new_storage)
 | 
						|
    return NULL;
 | 
						|
  
 | 
						|
  /* set usage to 1 early to allow cleanup with librdf_free_storage() */
 | 
						|
  new_storage->usage=1;
 | 
						|
 | 
						|
  new_storage->context=(char*)LIBRDF_CALLOC(librdf_storage_context, 1,
 | 
						|
                                            old_storage->factory->context_length);
 | 
						|
  if(!new_storage->context) {
 | 
						|
    librdf_free_storage(new_storage);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  new_storage->world=old_storage->world;
 | 
						|
 | 
						|
  /* do this now so librdf_free_storage won't call new factory on
 | 
						|
   * partially copied storage 
 | 
						|
   */
 | 
						|
  new_storage->factory=old_storage->factory;
 | 
						|
 | 
						|
  /* clone is assumed to do leave the new storage in the same state
 | 
						|
   * after an init() method on an existing storage - i.e ready to
 | 
						|
   * use but closed.
 | 
						|
   */
 | 
						|
  if(old_storage->factory->clone(new_storage, old_storage)) {
 | 
						|
    librdf_free_storage(new_storage);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 
 | 
						|
  return new_storage;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_new_storage_from_factory:
 | 
						|
 * @world: redland world object
 | 
						|
 * @factory: the factory to use to construct the storage
 | 
						|
 * @name: name to use for storage
 | 
						|
 * @options: #librdf_hash of options to initialise storage
 | 
						|
 *
 | 
						|
 * Constructor - create a new #librdf_storage object.
 | 
						|
 *
 | 
						|
 * If the options are present, they become owned by the storage
 | 
						|
 * and should no longer be used.
 | 
						|
 *
 | 
						|
 * Return value: a new #librdf_storage object or NULL on failure
 | 
						|
 *
 | 
						|
 */
 | 
						|
librdf_storage*
 | 
						|
librdf_new_storage_from_factory(librdf_world *world,
 | 
						|
                                librdf_storage_factory* factory,
 | 
						|
                                const char *name,
 | 
						|
                                librdf_hash* options)
 | 
						|
{
 | 
						|
  librdf_storage* storage;
 | 
						|
 | 
						|
  librdf_world_open(world);
 | 
						|
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(factory, librdf_storage_factory, NULL);
 | 
						|
 | 
						|
  if(!factory) {
 | 
						|
    librdf_free_hash(options);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
  
 | 
						|
  storage=(librdf_storage*)LIBRDF_CALLOC(librdf_storage, 1,
 | 
						|
                                         sizeof(librdf_storage));
 | 
						|
  if(!storage) {
 | 
						|
    librdf_free_hash(options);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
  
 | 
						|
  storage->world=world;
 | 
						|
 | 
						|
  /* set usage to 1 early to allow cleanup with librdf_free_storage() */
 | 
						|
  storage->usage=1; 
 | 
						|
  
 | 
						|
  storage->context=(char*)LIBRDF_CALLOC(librdf_storage_context, 1,
 | 
						|
                                        factory->context_length);
 | 
						|
  if(!storage->context) {
 | 
						|
    librdf_free_hash(options);
 | 
						|
    librdf_free_storage(storage);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
  
 | 
						|
  storage->factory=factory;
 | 
						|
 | 
						|
  if(factory->init(storage, name, options)) {
 | 
						|
    librdf_free_storage(storage);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
  
 | 
						|
  return storage;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_free_storage:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 *
 | 
						|
 * Destructor - destroy a #librdf_storage object.
 | 
						|
 **/
 | 
						|
void
 | 
						|
librdf_free_storage(librdf_storage* storage) 
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN(storage, librdf_storage);
 | 
						|
 | 
						|
  if(--storage->usage)
 | 
						|
    return;
 | 
						|
 | 
						|
  if(storage->factory)
 | 
						|
    storage->factory->terminate(storage);
 | 
						|
 | 
						|
  if(storage->context)
 | 
						|
    LIBRDF_FREE(librdf_storage_context, storage->context);
 | 
						|
  LIBRDF_FREE(librdf_storage, storage);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_add_reference:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 *
 | 
						|
 * Increment storage reference count by one.
 | 
						|
 * This function is intended to be internal to librdf storage modules.
 | 
						|
 **/
 | 
						|
void
 | 
						|
librdf_storage_add_reference(librdf_storage *storage)
 | 
						|
{
 | 
						|
  storage->usage++;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_remove_reference(libdf_storage *storage)
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 *
 | 
						|
 * Decrement storage reference count by one.
 | 
						|
 * Free the storage if reference count becomes zero.
 | 
						|
 * This function is intended to be internal to librdf storage modules.
 | 
						|
 **/
 | 
						|
void
 | 
						|
librdf_storage_remove_reference(librdf_storage *storage)
 | 
						|
{
 | 
						|
  librdf_free_storage(storage);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* methods */
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_open:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @model: model stored
 | 
						|
 *
 | 
						|
 * Start a model / storage association.
 | 
						|
 *
 | 
						|
 * This is ended with librdf_storage_close()
 | 
						|
 * 
 | 
						|
 * Return value: non 0 on failure
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_open(librdf_storage* storage, librdf_model* model) 
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, 1);
 | 
						|
 | 
						|
  return storage->factory->open(storage, model);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_close:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 *
 | 
						|
 * End a model / storage association.
 | 
						|
 * 
 | 
						|
 * Return value: non 0 on failure
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_close(librdf_storage* storage)
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, 1);
 | 
						|
 | 
						|
  return storage->factory->close(storage);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_size:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 *
 | 
						|
 * Get the number of statements stored.
 | 
						|
 * 
 | 
						|
 * Return value: The number of statements or < 0 if cannot be determined
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_size(librdf_storage* storage) 
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, -1);
 | 
						|
 | 
						|
  return storage->factory->size(storage);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_add_statement:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @statement: #librdf_statement statement to add
 | 
						|
 *
 | 
						|
 * Add a statement to a storage.
 | 
						|
 * 
 | 
						|
 * The passed-in statement is copied when added to the store, not
 | 
						|
 * shared with the store.  
 | 
						|
 *
 | 
						|
 * If the statement already exists in the store, it is not added
 | 
						|
 * unless Redland contexts are being used.
 | 
						|
 *
 | 
						|
 * Enforces that the statement is legal for RDF - URI or blank subject,
 | 
						|
 * URI predicate and URI or blank or literal object (i.e. anything).
 | 
						|
 *
 | 
						|
 * Return value: non 0 on failure, <0 on error, >0 if statement was illegal
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_add_statement(librdf_storage* storage,
 | 
						|
                             librdf_statement* statement) 
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, 1);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, 1);
 | 
						|
 | 
						|
  /* subject can be a URI or blank node */
 | 
						|
  if(!librdf_node_is_resource(statement->subject) &&
 | 
						|
     !librdf_node_is_blank(statement->subject))
 | 
						|
    return 1;
 | 
						|
  
 | 
						|
  /* predicate can only be a URI */
 | 
						|
  if(!librdf_node_is_resource(statement->predicate))
 | 
						|
     return 1;
 | 
						|
 | 
						|
  /* object can be any node - no check needed */
 | 
						|
 | 
						|
  if(storage->factory->add_statement)
 | 
						|
    return storage->factory->add_statement(storage, statement);
 | 
						|
 | 
						|
  return -1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_add_statements:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @statement_stream: #librdf_stream of statements
 | 
						|
 *
 | 
						|
 * Add a stream of statements to the storage.
 | 
						|
 * 
 | 
						|
 * If any of the statements already exists in the store, they are not
 | 
						|
 * added unless Redland contexts are being used.
 | 
						|
 *
 | 
						|
 * Return value: non 0 on failure
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_add_statements(librdf_storage* storage,
 | 
						|
                              librdf_stream* statement_stream) 
 | 
						|
{
 | 
						|
  int status=0;
 | 
						|
  
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, 1);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement_stream, librdf_stream, 1);
 | 
						|
 | 
						|
  if(storage->factory->add_statements)
 | 
						|
    return storage->factory->add_statements(storage, statement_stream);
 | 
						|
 | 
						|
  while(!librdf_stream_end(statement_stream)) {
 | 
						|
    librdf_statement* statement=librdf_stream_get_object(statement_stream);
 | 
						|
 | 
						|
    if(statement) {
 | 
						|
      status=librdf_storage_add_statement(storage, statement);
 | 
						|
      if(status > 0)
 | 
						|
        /* just skip illegal statements */
 | 
						|
        status=0;
 | 
						|
    }
 | 
						|
    else
 | 
						|
      status=1;
 | 
						|
 | 
						|
    if(status)
 | 
						|
      break;
 | 
						|
 | 
						|
    librdf_stream_next(statement_stream);
 | 
						|
  }
 | 
						|
  
 | 
						|
  return status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_remove_statement:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @statement: #librdf_statement statement to remove
 | 
						|
 *
 | 
						|
 * Remove a statement from the storage.
 | 
						|
 * 
 | 
						|
 * Return value: non 0 on failure
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_remove_statement(librdf_storage* storage, 
 | 
						|
                                librdf_statement* statement) 
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, 1);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, 1);
 | 
						|
 | 
						|
  if(storage->factory->remove_statement)
 | 
						|
    return storage->factory->remove_statement(storage, statement);
 | 
						|
  return 1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_contains_statement:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @statement: #librdf_statement statement to check
 | 
						|
 *
 | 
						|
 * Test if a given statement is present in the storage.
 | 
						|
 *
 | 
						|
 * Return value: non 0 if the storage contains the statement (>0 if illegal statement)
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_contains_statement(librdf_storage* storage,
 | 
						|
                                  librdf_statement* statement) 
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, 1);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, 1);
 | 
						|
 | 
						|
  /* subject can be a URI or blank node */
 | 
						|
  if(!statement->subject ||
 | 
						|
     (!librdf_node_is_resource(statement->subject) &&
 | 
						|
      !librdf_node_is_blank(statement->subject)))
 | 
						|
    return 1;
 | 
						|
  
 | 
						|
  /* predicate can only be a URI */
 | 
						|
  if(!statement->predicate || !librdf_node_is_resource(statement->predicate))
 | 
						|
     return 1;
 | 
						|
 | 
						|
  if(!statement->object)
 | 
						|
    return 1;
 | 
						|
 | 
						|
  return storage->factory->contains_statement(storage, statement);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_serialise:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 *
 | 
						|
 * Serialise the storage as a librdf_stream of statemetns.
 | 
						|
 * 
 | 
						|
 * Return value: #librdf_stream of statements or NULL on failure
 | 
						|
 **/
 | 
						|
librdf_stream*
 | 
						|
librdf_storage_serialise(librdf_storage* storage) 
 | 
						|
{
 | 
						|
  return storage->factory->serialise(storage);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_find_statements:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @statement: #librdf_statement partial statement to find
 | 
						|
 *
 | 
						|
 * Search the storage for matching statements.
 | 
						|
 * 
 | 
						|
 * Searches the storage for a (partial) statement as described in
 | 
						|
 * librdf_statement_match() and returns a #librdf_stream of
 | 
						|
 * matching #librdf_statement objects.
 | 
						|
 * 
 | 
						|
 * Return value:  #librdf_stream of matching statements (may be empty) or NULL on failure
 | 
						|
 **/
 | 
						|
librdf_stream*
 | 
						|
librdf_storage_find_statements(librdf_storage* storage,
 | 
						|
                               librdf_statement* statement) 
 | 
						|
{
 | 
						|
  librdf_node *subject, *predicate, *object;
 | 
						|
  librdf_iterator *iterator;
 | 
						|
  
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, NULL);
 | 
						|
 | 
						|
  subject=librdf_statement_get_subject(statement);
 | 
						|
  predicate=librdf_statement_get_predicate(statement);
 | 
						|
  object=librdf_statement_get_object(statement);
 | 
						|
 | 
						|
  /* try to pick the most efficient storage back end */
 | 
						|
 | 
						|
  /* only subject/source field blank -> use find_sources */
 | 
						|
  if(storage->factory->find_sources && !subject && predicate && object) {
 | 
						|
    iterator=storage->factory->find_sources(storage, predicate, object);
 | 
						|
    if(iterator)
 | 
						|
      return librdf_new_stream_from_node_iterator(iterator, statement,
 | 
						|
                                                  LIBRDF_STATEMENT_SUBJECT);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
  
 | 
						|
  /* only predicate/arc field blank -> use find_arcs */
 | 
						|
  if(storage->factory->find_arcs && subject && !predicate && object) {
 | 
						|
    iterator=storage->factory->find_arcs(storage, subject, object);
 | 
						|
    if(iterator)
 | 
						|
      return librdf_new_stream_from_node_iterator(iterator, statement,
 | 
						|
                                                  LIBRDF_STATEMENT_PREDICATE);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
  
 | 
						|
  /* only object/target field blank -> use find_targets */
 | 
						|
  if(storage->factory->find_targets && subject && predicate && !object) {
 | 
						|
    iterator=storage->factory->find_targets(storage, subject, predicate);
 | 
						|
    if(iterator)
 | 
						|
      return librdf_new_stream_from_node_iterator(iterator, statement,
 | 
						|
                                                  LIBRDF_STATEMENT_OBJECT);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
  
 | 
						|
  return storage->factory->find_statements(storage, statement);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
typedef struct {
 | 
						|
  librdf_storage *storage;
 | 
						|
  librdf_stream *stream;
 | 
						|
  librdf_statement *partial_statement;
 | 
						|
  librdf_statement_part want;
 | 
						|
  librdf_node *object_node;
 | 
						|
  librdf_node *context_node;
 | 
						|
} librdf_storage_stream_to_node_iterator_context;
 | 
						|
 | 
						|
 | 
						|
static int
 | 
						|
librdf_storage_stream_to_node_iterator_is_end(void* iterator)
 | 
						|
{
 | 
						|
  librdf_storage_stream_to_node_iterator_context* context=(librdf_storage_stream_to_node_iterator_context*)iterator;
 | 
						|
 | 
						|
  return librdf_stream_end(context->stream);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static int
 | 
						|
librdf_storage_stream_to_node_iterator_next_method(void* iterator) 
 | 
						|
{
 | 
						|
  librdf_storage_stream_to_node_iterator_context* context=(librdf_storage_stream_to_node_iterator_context*)iterator;
 | 
						|
 | 
						|
  if(context->object_node) {
 | 
						|
    librdf_free_node(context->object_node);
 | 
						|
    context->object_node=NULL;
 | 
						|
  }
 | 
						|
  if(context->context_node) {
 | 
						|
    librdf_free_node(context->context_node);
 | 
						|
    context->context_node=NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  return librdf_stream_next(context->stream);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static void*
 | 
						|
librdf_storage_stream_to_node_iterator_get_method(void* iterator, int flags) 
 | 
						|
{
 | 
						|
  librdf_storage_stream_to_node_iterator_context* context=(librdf_storage_stream_to_node_iterator_context*)iterator;
 | 
						|
  librdf_node* node;
 | 
						|
  librdf_statement* statement=librdf_stream_get_object(context->stream);
 | 
						|
 | 
						|
  if(!statement)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  switch(flags) {
 | 
						|
    case LIBRDF_ITERATOR_GET_METHOD_GET_OBJECT:
 | 
						|
 | 
						|
      if(!context->object_node) {
 | 
						|
        switch(context->want) {
 | 
						|
          case LIBRDF_STATEMENT_SUBJECT: /* SOURCES (subjects) */
 | 
						|
            node=librdf_statement_get_subject(statement);
 | 
						|
            break;
 | 
						|
            
 | 
						|
          case LIBRDF_STATEMENT_PREDICATE: /* ARCS (predicates) */
 | 
						|
            node=librdf_statement_get_predicate(statement);
 | 
						|
            break;
 | 
						|
            
 | 
						|
          case LIBRDF_STATEMENT_OBJECT: /* TARGETS (objects) */
 | 
						|
            node=librdf_statement_get_object(statement);
 | 
						|
            break;
 | 
						|
 | 
						|
          case LIBRDF_STATEMENT_ALL:
 | 
						|
            default: /* error */
 | 
						|
              librdf_log(statement->world,
 | 
						|
                         0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
 | 
						|
                         "Unknown statement part %d", context->want);
 | 
						|
              node=NULL;
 | 
						|
        }
 | 
						|
        context->object_node=librdf_new_node_from_node(node);
 | 
						|
      }
 | 
						|
      node=context->object_node;
 | 
						|
      break;
 | 
						|
      
 | 
						|
    case LIBRDF_ITERATOR_GET_METHOD_GET_CONTEXT:
 | 
						|
      if(!context->context_node) {
 | 
						|
        node=(librdf_node*)librdf_stream_get_context(context->stream);
 | 
						|
        context->context_node=node ? librdf_new_node_from_node(node) : NULL;
 | 
						|
      }
 | 
						|
      node=context->context_node;
 | 
						|
      break;
 | 
						|
      
 | 
						|
    default:
 | 
						|
      librdf_log(statement->world,
 | 
						|
                 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
 | 
						|
                 "Unknown iterator method flag %d", flags);
 | 
						|
      node=NULL;
 | 
						|
  }
 | 
						|
  
 | 
						|
  return (void*)node;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static void
 | 
						|
librdf_storage_stream_to_node_iterator_finished(void* iterator) 
 | 
						|
{
 | 
						|
  librdf_storage_stream_to_node_iterator_context* context=(librdf_storage_stream_to_node_iterator_context*)iterator;
 | 
						|
  librdf_statement *partial_statement=context->partial_statement;
 | 
						|
 | 
						|
  if(partial_statement)
 | 
						|
    librdf_free_statement(partial_statement);
 | 
						|
 | 
						|
  if(context->stream)
 | 
						|
    librdf_free_stream(context->stream);
 | 
						|
 | 
						|
  if(context->storage)
 | 
						|
    librdf_storage_remove_reference(context->storage);
 | 
						|
 | 
						|
  if(context->object_node)
 | 
						|
    librdf_free_node(context->object_node);
 | 
						|
 | 
						|
  if(context->context_node)
 | 
						|
    librdf_free_node(context->context_node);
 | 
						|
  
 | 
						|
  LIBRDF_FREE(librdf_storage_stream_to_node_iterator_context, context);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * librdf_storage_node_stream_to_node_create - Create a stream for get sources, targets or arcs methods using find_statements method
 | 
						|
 * @storage: the storage object to use
 | 
						|
 * @node1: the first node to encode in the key (or NULL if not needed)
 | 
						|
 * @node2: the second node to encode in the key (or NULL if not needed)
 | 
						|
 * @want: the field required from the statement
 | 
						|
 *
 | 
						|
 * node1 and node2 cannot both be NULL
 | 
						|
 * 
 | 
						|
 * Return value: a new #librdf_iterator or NULL on failure
 | 
						|
 **/
 | 
						|
static librdf_iterator*
 | 
						|
librdf_storage_node_stream_to_node_create(librdf_storage* storage,
 | 
						|
                                          librdf_node *node1,
 | 
						|
                                          librdf_node *node2,
 | 
						|
                                          librdf_statement_part want)
 | 
						|
{
 | 
						|
  librdf_statement *partial_statement;
 | 
						|
  librdf_stream *stream;
 | 
						|
  librdf_storage_stream_to_node_iterator_context* context;
 | 
						|
  librdf_iterator* iterator;
 | 
						|
  
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL);
 | 
						|
  LIBRDF_ASSERT_RETURN(node1 == NULL && node2 == NULL, "both node objects are NULL", NULL);
 | 
						|
 | 
						|
  partial_statement=librdf_new_statement(storage->world);
 | 
						|
  if(!partial_statement)
 | 
						|
    return NULL;
 | 
						|
  
 | 
						|
  context=(librdf_storage_stream_to_node_iterator_context*)LIBRDF_CALLOC(librdf_storage_stream_to_node_iterator_context, 1, sizeof(librdf_storage_stream_to_node_iterator_context));
 | 
						|
  if(!context) {
 | 
						|
    librdf_free_statement(partial_statement);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  if(node1)
 | 
						|
    node1=librdf_new_node_from_node(node1);
 | 
						|
  if(node2)
 | 
						|
    node2=librdf_new_node_from_node(node2);
 | 
						|
  
 | 
						|
  switch(want) {
 | 
						|
    case LIBRDF_STATEMENT_SUBJECT:
 | 
						|
      librdf_statement_set_predicate(partial_statement, node1);
 | 
						|
      librdf_statement_set_object(partial_statement, node2);
 | 
						|
      break;
 | 
						|
    case LIBRDF_STATEMENT_PREDICATE:
 | 
						|
      librdf_statement_set_subject(partial_statement, node1);
 | 
						|
      librdf_statement_set_object(partial_statement, node2);
 | 
						|
      break;
 | 
						|
    case LIBRDF_STATEMENT_OBJECT:
 | 
						|
      librdf_statement_set_subject(partial_statement, node1);
 | 
						|
      librdf_statement_set_predicate(partial_statement, node2);
 | 
						|
      break;
 | 
						|
 | 
						|
    case LIBRDF_STATEMENT_ALL:
 | 
						|
    default:
 | 
						|
      librdf_free_node(node1);
 | 
						|
      librdf_free_node(node2);
 | 
						|
      librdf_free_statement(partial_statement);
 | 
						|
      librdf_log(storage->world,
 | 
						|
                 0, LIBRDF_LOG_ERROR, LIBRDF_FROM_STORAGE, NULL,
 | 
						|
                 "Illegal statement part %d seen", want);
 | 
						|
      return NULL;
 | 
						|
  }
 | 
						|
  
 | 
						|
  stream=storage->factory->find_statements(storage, partial_statement);
 | 
						|
  if(!stream) {
 | 
						|
    librdf_storage_stream_to_node_iterator_finished(context);
 | 
						|
    return librdf_new_empty_iterator(storage->world);
 | 
						|
  }
 | 
						|
  
 | 
						|
  /* initialise context */
 | 
						|
  context->partial_statement=partial_statement;
 | 
						|
  context->stream=stream;
 | 
						|
  context->want=want;
 | 
						|
 | 
						|
  context->storage=storage;
 | 
						|
  librdf_storage_add_reference(context->storage);
 | 
						|
 | 
						|
  iterator=librdf_new_iterator(storage->world,
 | 
						|
                               (void*)context,
 | 
						|
                               librdf_storage_stream_to_node_iterator_is_end,
 | 
						|
                               librdf_storage_stream_to_node_iterator_next_method,
 | 
						|
                               librdf_storage_stream_to_node_iterator_get_method,
 | 
						|
                               librdf_storage_stream_to_node_iterator_finished);
 | 
						|
  if(!iterator)
 | 
						|
    librdf_storage_stream_to_node_iterator_finished(context);
 | 
						|
  return iterator;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_get_sources:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @arc: #librdf_node arc
 | 
						|
 * @target: #librdf_node target
 | 
						|
 *
 | 
						|
 * Return the sources (subjects) of arc in an RDF graph given arc (predicate) and target (object).
 | 
						|
 * 
 | 
						|
 * Searches the storage for arcs matching the given arc and target
 | 
						|
 * and returns a list of the source #librdf_node objects as an iterator
 | 
						|
 * 
 | 
						|
 * Return value:  #librdf_iterator of #librdf_node objects (may be empty) or NULL on failure
 | 
						|
 **/
 | 
						|
librdf_iterator*
 | 
						|
librdf_storage_get_sources(librdf_storage *storage,
 | 
						|
                           librdf_node *arc, librdf_node *target) 
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(arc, librdf_node, NULL);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(target, librdf_node, NULL);
 | 
						|
 | 
						|
  if (storage->factory->find_sources)
 | 
						|
    return storage->factory->find_sources(storage, arc, target);
 | 
						|
 | 
						|
  return librdf_storage_node_stream_to_node_create(storage, arc, target,
 | 
						|
                                                   LIBRDF_STATEMENT_SUBJECT);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_get_arcs:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @source: #librdf_node source
 | 
						|
 * @target: #librdf_node target
 | 
						|
 *
 | 
						|
 * Return the arcs (predicates) of an arc in an RDF graph given source (subject) and target (object).
 | 
						|
 * 
 | 
						|
 * Searches the storage for arcs matching the given source and target
 | 
						|
 * and returns a list of the arc #librdf_node objects as an iterator
 | 
						|
 * 
 | 
						|
 * Return value:  #librdf_iterator of #librdf_node objects (may be empty) or NULL on failure
 | 
						|
 **/
 | 
						|
librdf_iterator*
 | 
						|
librdf_storage_get_arcs(librdf_storage *storage,
 | 
						|
                        librdf_node *source, librdf_node *target) 
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(source, librdf_node, NULL);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(target, librdf_node, NULL);
 | 
						|
 | 
						|
  if (storage->factory->find_arcs)
 | 
						|
    return storage->factory->find_arcs(storage, source, target);
 | 
						|
 | 
						|
  return librdf_storage_node_stream_to_node_create(storage, source, target,
 | 
						|
                                                   LIBRDF_STATEMENT_PREDICATE);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_get_targets:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @source: #librdf_node source
 | 
						|
 * @arc: #librdf_node arc
 | 
						|
 *
 | 
						|
 * Return the targets (objects) of an arc in an RDF graph given source (subject) and arc (predicate).
 | 
						|
 * 
 | 
						|
 * Searches the storage for targets matching the given source and arc
 | 
						|
 * and returns a list of the source #librdf_node objects as an iterator
 | 
						|
 * 
 | 
						|
 * Return value:  #librdf_iterator of #librdf_node objects (may be empty) or NULL on failure
 | 
						|
 **/
 | 
						|
librdf_iterator*
 | 
						|
librdf_storage_get_targets(librdf_storage *storage,
 | 
						|
                           librdf_node *source, librdf_node *arc) 
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(source, librdf_node, NULL);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(arc, librdf_node, NULL);
 | 
						|
 | 
						|
  if (storage->factory->find_targets)
 | 
						|
    return storage->factory->find_targets(storage, source, arc);
 | 
						|
 | 
						|
  return librdf_storage_node_stream_to_node_create(storage, source, arc,
 | 
						|
                                                   LIBRDF_STATEMENT_OBJECT);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_get_arcs_in:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @node: #librdf_node resource node
 | 
						|
 *
 | 
						|
 * Return the properties pointing to the given resource.
 | 
						|
 * 
 | 
						|
 * Return value:  #librdf_iterator of #librdf_node objects (may be empty) or NULL on failure
 | 
						|
 **/
 | 
						|
librdf_iterator*
 | 
						|
librdf_storage_get_arcs_in(librdf_storage *storage, librdf_node *node) 
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, NULL);
 | 
						|
 | 
						|
  if (storage->factory->get_arcs_in)
 | 
						|
    return storage->factory->get_arcs_in(storage, node);
 | 
						|
 | 
						|
  return librdf_storage_node_stream_to_node_create(storage, NULL, node,
 | 
						|
                                                   LIBRDF_STATEMENT_PREDICATE);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_get_arcs_out:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @node: #librdf_node resource node
 | 
						|
 *
 | 
						|
 * Return the properties pointing from the given resource.
 | 
						|
 * 
 | 
						|
 * Return value:  #librdf_iterator of #librdf_node objects (may be empty) or NULL on failure
 | 
						|
 **/
 | 
						|
librdf_iterator*
 | 
						|
librdf_storage_get_arcs_out(librdf_storage *storage, librdf_node *node) 
 | 
						|
{
 | 
						|
  if (storage->factory->get_arcs_out)
 | 
						|
    return storage->factory->get_arcs_out(storage, node);
 | 
						|
  return librdf_storage_node_stream_to_node_create(storage, node, NULL,
 | 
						|
                                                   LIBRDF_STATEMENT_PREDICATE);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_has_arc_in:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @node: #librdf_node resource node
 | 
						|
 * @property: #librdf_node property node
 | 
						|
 *
 | 
						|
 * Check if a node has a given property pointing to it.
 | 
						|
 * 
 | 
						|
 * Return value: non 0 if arc property does point to the resource node
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_has_arc_in(librdf_storage *storage, librdf_node *node,
 | 
						|
                          librdf_node *property) 
 | 
						|
{
 | 
						|
  librdf_iterator *iterator;
 | 
						|
  int status;
 | 
						|
  
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, 0);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, 0);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(property, librdf_node, 0);
 | 
						|
 | 
						|
  if (storage->factory->has_arc_in)
 | 
						|
    return storage->factory->has_arc_in(storage, node, property);
 | 
						|
  
 | 
						|
  iterator=librdf_storage_get_sources(storage, property, node);
 | 
						|
  if(!iterator)
 | 
						|
    return 0;
 | 
						|
 | 
						|
  /* a non-empty list of sources is success */
 | 
						|
  status=!librdf_iterator_end(iterator);
 | 
						|
  librdf_free_iterator(iterator);
 | 
						|
 | 
						|
  return status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_has_arc_out:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @node: #librdf_node resource node
 | 
						|
 * @property: #librdf_node property node
 | 
						|
 *
 | 
						|
 * Check if a node has a given property pointing from it.
 | 
						|
 * 
 | 
						|
 * Return value: non 0 if arc property does point from the resource node
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_has_arc_out(librdf_storage *storage, librdf_node *node, 
 | 
						|
                           librdf_node *property) 
 | 
						|
{
 | 
						|
  librdf_iterator *iterator;
 | 
						|
  int status;
 | 
						|
  
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, 0);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(node, librdf_node, 0);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(property, librdf_node, 0);
 | 
						|
 | 
						|
  if (storage->factory->has_arc_out)
 | 
						|
    return storage->factory->has_arc_out(storage, node, property);
 | 
						|
  
 | 
						|
  iterator=librdf_storage_get_targets(storage, node, property);
 | 
						|
  if(!iterator)
 | 
						|
    return 0;
 | 
						|
 | 
						|
  /* a non-empty list of targets is success */
 | 
						|
  status=!librdf_iterator_end(iterator);
 | 
						|
  librdf_free_iterator(iterator);
 | 
						|
 | 
						|
  return status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_context_add_statement:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @context: #librdf_node context node
 | 
						|
 * @statement: #librdf_statement statement to add
 | 
						|
 *
 | 
						|
 * Add a statement to a storage in a context.
 | 
						|
 * 
 | 
						|
 * If @context is NULL, this is equivalent to librdf_storage_add_statement
 | 
						|
 *
 | 
						|
 * Return value: non 0 on failure
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_context_add_statement(librdf_storage* storage,
 | 
						|
                                     librdf_node* context,
 | 
						|
                                     librdf_statement* statement) 
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, 1);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, 1);
 | 
						|
 | 
						|
  if(!context)
 | 
						|
    return librdf_storage_add_statement(storage, statement);
 | 
						|
 | 
						|
  if(storage->factory->context_add_statement)
 | 
						|
    return storage->factory->context_add_statement(storage, context, statement);
 | 
						|
  return 1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_context_add_statements:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @context: #librdf_node context
 | 
						|
 * @stream: #librdf_stream stream object
 | 
						|
 *
 | 
						|
 * Add statements to a storage with a context.
 | 
						|
 * 
 | 
						|
 * If @context is NULL, this is equivalent to librdf_storage_add_statements
 | 
						|
 *
 | 
						|
 * Return value: Non 0 on failure
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_context_add_statements(librdf_storage* storage, 
 | 
						|
                                      librdf_node* context,
 | 
						|
                                      librdf_stream* stream) 
 | 
						|
{
 | 
						|
  int status=0;
 | 
						|
  
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, 1);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(stream, librdf_stream, 1);
 | 
						|
 | 
						|
  if(!context)
 | 
						|
    return librdf_storage_add_statements(storage, stream);
 | 
						|
 | 
						|
  if(storage->factory->context_add_statements)
 | 
						|
    return storage->factory->context_add_statements(storage, context, stream);
 | 
						|
 | 
						|
  if(!storage->factory->context_add_statement)
 | 
						|
    return 1;
 | 
						|
  
 | 
						|
  if(!stream)
 | 
						|
    return 1;
 | 
						|
 | 
						|
  while(!librdf_stream_end(stream)) {
 | 
						|
    librdf_statement* statement=librdf_stream_get_object(stream);
 | 
						|
    if(!statement)
 | 
						|
      break;
 | 
						|
    status=librdf_storage_context_add_statement(storage, context, statement);
 | 
						|
    if(status)
 | 
						|
      break;
 | 
						|
    librdf_stream_next(stream);
 | 
						|
  }
 | 
						|
 | 
						|
  return status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_context_remove_statement:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @context: #librdf_node context node
 | 
						|
 * @statement: #librdf_statement statement to remove
 | 
						|
 *
 | 
						|
 * Remove a statement from a storage in a context.
 | 
						|
 * 
 | 
						|
 * If @context is NULL, this is equivalent to librdf_storage_remove_statement
 | 
						|
 *
 | 
						|
 * Return value: non 0 on failure
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_context_remove_statement(librdf_storage* storage, 
 | 
						|
                                        librdf_node* context,
 | 
						|
                                        librdf_statement* statement) 
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, 1);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(context, librdf_statement, 1);
 | 
						|
 | 
						|
  if(!storage->factory->context_remove_statement)
 | 
						|
    return 1;
 | 
						|
  
 | 
						|
  return storage->factory->context_remove_statement(storage, context, statement);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_context_remove_statements:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @context: #librdf_uri context
 | 
						|
 *
 | 
						|
 * Remove statements from a storage with the given context.
 | 
						|
 * 
 | 
						|
 * Return value: Non 0 on failure
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_context_remove_statements(librdf_storage* storage,
 | 
						|
                                         librdf_node* context) 
 | 
						|
{
 | 
						|
  librdf_stream *stream;
 | 
						|
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, 1);
 | 
						|
 | 
						|
  if(storage->factory->context_remove_statements)
 | 
						|
    return storage->factory->context_remove_statements(storage, context);
 | 
						|
  
 | 
						|
  if(!storage->factory->context_remove_statement)
 | 
						|
    return 1;
 | 
						|
  
 | 
						|
  stream=librdf_storage_context_as_stream(storage, context);
 | 
						|
  if(!stream)
 | 
						|
    return 1;
 | 
						|
 | 
						|
  while(!librdf_stream_end(stream)) {
 | 
						|
    librdf_statement *statement=librdf_stream_get_object(stream);
 | 
						|
    if(!statement)
 | 
						|
      break;
 | 
						|
    librdf_storage_context_remove_statement(storage, context, statement);
 | 
						|
    librdf_stream_next(stream);
 | 
						|
  }
 | 
						|
  librdf_free_stream(stream);  
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_context_as_stream:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @context: #librdf_node context node
 | 
						|
 *
 | 
						|
 * List all statements in a storage context.
 | 
						|
 * 
 | 
						|
 * Return value: #librdf_stream of statements or NULL on failure or context is empty
 | 
						|
 **/
 | 
						|
librdf_stream*
 | 
						|
librdf_storage_context_as_stream(librdf_storage* storage, librdf_node* context)
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL);
 | 
						|
 | 
						|
  return storage->factory->context_serialise(storage, context);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_context_serialise:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @context: #librdf_node context node
 | 
						|
 *
 | 
						|
 * List all statements in a storage context (DEPRECATED).
 | 
						|
 * 
 | 
						|
 * DEPRECATED to reduce confusion with the librdf_serializer class.
 | 
						|
 * Please use librdf_storage_context_as_stream.
 | 
						|
 *
 | 
						|
 * Return value: #librdf_stream of statements or NULL on failure or context is empty
 | 
						|
 **/
 | 
						|
librdf_stream*
 | 
						|
librdf_storage_context_serialise(librdf_storage* storage,
 | 
						|
                                 librdf_node* context)
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL);
 | 
						|
 | 
						|
  return librdf_storage_context_as_stream(storage, context);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_supports_query:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @query: #librdf_query query object
 | 
						|
 * 
 | 
						|
 * Check if a storage system supports a query language.
 | 
						|
 * 
 | 
						|
 * Not implemented.
 | 
						|
 *
 | 
						|
 * Return value: non-0 if the query is supported.
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_supports_query(librdf_storage* storage, librdf_query *query)
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, 0);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, librdf_query, 0);
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_query_execute:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @query: #librdf_query query object
 | 
						|
 * 
 | 
						|
 * Run the given query against the storage.
 | 
						|
 * 
 | 
						|
 * Not implemented.
 | 
						|
 *
 | 
						|
 * Return value: #librdf_query_results or NULL on failure
 | 
						|
 **/
 | 
						|
librdf_query_results*
 | 
						|
librdf_storage_query_execute(librdf_storage* storage, librdf_query *query) 
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(query, librdf_query, NULL);
 | 
						|
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_sync:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * 
 | 
						|
 * Synchronise the storage to the storage implementation.
 | 
						|
 * 
 | 
						|
 * Return value: non-0 on failure
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_sync(librdf_storage* storage) 
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, 1);
 | 
						|
 | 
						|
  if(storage->factory->sync)
 | 
						|
    return storage->factory->sync(storage);
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_find_statements_in_context:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @statement: #librdf_statement partial statement to find
 | 
						|
 * @context_node: context #librdf_node (or NULL)
 | 
						|
 *
 | 
						|
 * Search the storage for matching statements in a given context.
 | 
						|
 * 
 | 
						|
 * Searches the storage for a (partial) statement as described in
 | 
						|
 * librdf_statement_match() in the given context and returns a
 | 
						|
 * #librdf_stream of matching #librdf_statement objects.  If
 | 
						|
 * context is NULL, this is equivalent to librdf_storage_find_statements.
 | 
						|
 * 
 | 
						|
 * Return value: #librdf_stream of matching statements (may be empty) or NULL on failure
 | 
						|
 **/
 | 
						|
librdf_stream*
 | 
						|
librdf_storage_find_statements_in_context(librdf_storage* storage, librdf_statement* statement, librdf_node* context_node) 
 | 
						|
{
 | 
						|
  librdf_stream *stream;
 | 
						|
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(statement, librdf_statement, NULL);
 | 
						|
 | 
						|
  if(storage->factory->find_statements_in_context)
 | 
						|
    return storage->factory->find_statements_in_context(storage, statement, context_node);
 | 
						|
 | 
						|
  statement=librdf_new_statement_from_statement(statement);
 | 
						|
  if(!statement)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  stream=librdf_storage_context_as_stream(storage, context_node);
 | 
						|
  if(!stream) {
 | 
						|
    librdf_free_statement(statement);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  librdf_stream_add_map(stream, 
 | 
						|
                        &librdf_stream_statement_find_map,
 | 
						|
                        (librdf_stream_map_free_context_handler)&librdf_free_statement, (void*)statement);
 | 
						|
 | 
						|
  return stream;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_get_contexts:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 *
 | 
						|
 * Return the list of contexts in the store.
 | 
						|
 * 
 | 
						|
 * Returns an iterator of #librdf_node context nodes for each
 | 
						|
 * context in the store.
 | 
						|
 *
 | 
						|
 * Return value: #librdf_iterator of context nodes or NULL on failure or if contexts are not supported
 | 
						|
 **/
 | 
						|
librdf_iterator*
 | 
						|
librdf_storage_get_contexts(librdf_storage* storage) 
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL);
 | 
						|
 | 
						|
  if(storage->factory->get_contexts)
 | 
						|
    return storage->factory->get_contexts(storage);
 | 
						|
  else
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_get_feature:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @feature: #librdf_uri feature property
 | 
						|
 *
 | 
						|
 * Get the value of a storage feature.
 | 
						|
 * 
 | 
						|
 * Return value: new #librdf_node feature value or NULL if no such feature
 | 
						|
 * exists or the value is empty.
 | 
						|
 **/
 | 
						|
librdf_node*
 | 
						|
librdf_storage_get_feature(librdf_storage* storage, librdf_uri* feature)
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, NULL);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(feature, librdf_uri, NULL);
 | 
						|
 | 
						|
  if(storage->factory->get_feature)
 | 
						|
    return storage->factory->get_feature(storage, feature);
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_set_feature:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @feature: #librdf_uri feature property
 | 
						|
 * @value: #librdf_node feature property value
 | 
						|
 *
 | 
						|
 * Set the value of a storage feature.
 | 
						|
 * 
 | 
						|
 * Return value: non 0 on failure (negative if no such feature)
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_set_feature(librdf_storage* storage, librdf_uri* feature,
 | 
						|
                           librdf_node* value)
 | 
						|
{
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(storage, librdf_storage, -1);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(feature, librdf_uri, -1);
 | 
						|
  LIBRDF_ASSERT_OBJECT_POINTER_RETURN_VALUE(value, librdf_node, -1);
 | 
						|
 | 
						|
  if(storage->factory->set_feature)
 | 
						|
    return storage->factory->set_feature(storage, feature, value);
 | 
						|
  return -1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_find_statements_with_options:
 | 
						|
 * @storage: #librdf_storage object
 | 
						|
 * @statement: #librdf_statement partial statement to find
 | 
						|
 * @context_node: #librdf_node context node or NULL.
 | 
						|
 * @options: #librdf_hash of matching options or NULL
 | 
						|
 *
 | 
						|
 * Search the storage for matching statements with match options.
 | 
						|
 * 
 | 
						|
 * Searches the storage for a (partial) statement as described in
 | 
						|
 * librdf_statement_match() and returns a #librdf_stream of
 | 
						|
 * matching #librdf_statement objects.
 | 
						|
 * 
 | 
						|
 * If options is given then the match is made according to
 | 
						|
 * the given options.  If options is NULL, this is equivalent
 | 
						|
 * to librdf_storage_find_statements_in_context.
 | 
						|
 * 
 | 
						|
 * Return value:  #librdf_stream of matching statements (may be empty) or NULL on failure
 | 
						|
 **/
 | 
						|
librdf_stream*
 | 
						|
librdf_storage_find_statements_with_options(librdf_storage* storage,
 | 
						|
                                            librdf_statement* statement,
 | 
						|
                                            librdf_node* context_node,
 | 
						|
                                            librdf_hash* options) 
 | 
						|
{
 | 
						|
  if(storage->factory->find_statements_with_options)
 | 
						|
    return storage->factory->find_statements_with_options(storage, statement, context_node, options);
 | 
						|
  else
 | 
						|
    return librdf_storage_find_statements_in_context(storage, statement, context_node);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_transaction_start:
 | 
						|
 * @storage: the storage object
 | 
						|
 * 
 | 
						|
 * Start a transaction
 | 
						|
 * 
 | 
						|
 * Return value: non-0 on failure
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_transaction_start(librdf_storage* storage) 
 | 
						|
{
 | 
						|
  if(storage->factory->transaction_start)
 | 
						|
    return storage->factory->transaction_start(storage);
 | 
						|
  else
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_transaction_start_with_handle:
 | 
						|
 * @storage: the storage object
 | 
						|
 * @handle: the transaction object
 | 
						|
 * 
 | 
						|
 * Start a transaction using an existing external transaction object.
 | 
						|
 * 
 | 
						|
 * Return value: non-0 on failure
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_transaction_start_with_handle(librdf_storage* storage, void* handle)
 | 
						|
{
 | 
						|
  if(storage->factory->transaction_start_with_handle)
 | 
						|
    return storage->factory->transaction_start_with_handle(storage, handle);
 | 
						|
  else
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_transaction_commit:
 | 
						|
 * @storage: the storage object
 | 
						|
 * 
 | 
						|
 * Commit a transaction.
 | 
						|
 * 
 | 
						|
 * Return value: non-0 on failure 
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_transaction_commit(librdf_storage* storage) 
 | 
						|
{
 | 
						|
  if(storage->factory->transaction_commit)
 | 
						|
    return storage->factory->transaction_commit(storage);
 | 
						|
  else
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_transaction_rollback:
 | 
						|
 * @storage: the storage object
 | 
						|
 * 
 | 
						|
 * Rollback a transaction.
 | 
						|
 * 
 | 
						|
 * Return value: non-0 on failure 
 | 
						|
 **/
 | 
						|
int
 | 
						|
librdf_storage_transaction_rollback(librdf_storage* storage) 
 | 
						|
{
 | 
						|
  if(storage->factory->transaction_rollback)
 | 
						|
    return storage->factory->transaction_rollback(storage);
 | 
						|
  else
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * librdf_storage_transaction_get_handle:
 | 
						|
 * @storage: the storage object
 | 
						|
 * 
 | 
						|
 * Get the current transaction handle.
 | 
						|
 * 
 | 
						|
 * Return value: non-0 on failure 
 | 
						|
 **/
 | 
						|
void*
 | 
						|
librdf_storage_transaction_get_handle(librdf_storage* storage) 
 | 
						|
{
 | 
						|
  if(storage->factory->transaction_get_handle)
 | 
						|
    return storage->factory->transaction_get_handle(storage);
 | 
						|
  else
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
/* TEST CODE */
 | 
						|
 | 
						|
 | 
						|
#ifdef STANDALONE
 | 
						|
 | 
						|
/* one more prototype */
 | 
						|
int main(int argc, char *argv[]);
 | 
						|
 | 
						|
 | 
						|
int
 | 
						|
main(int argc, char *argv[]) 
 | 
						|
{
 | 
						|
  librdf_storage* storage;
 | 
						|
  const char *program=librdf_basename((const char*)argv[0]);
 | 
						|
  librdf_world *world;
 | 
						|
  
 | 
						|
  /* triples of arguments to librdf_new_storage */
 | 
						|
  const char* const storages[] = {
 | 
						|
	"memory", NULL, "contexts='yes'",
 | 
						|
	"hashes", "test", "hash-type='bdb',dir='.',write='yes',new='yes',contexts='yes'",
 | 
						|
    #ifdef STORAGE_TREES
 | 
						|
	    "trees", "test", "contexts='yes'",
 | 
						|
    #endif
 | 
						|
    #ifdef STORAGE_FILE
 | 
						|
      "file", "file://../redland.rdf", NULL,
 | 
						|
	    "uri", "http://librdf.org/redland.rdf", NULL,
 | 
						|
    #endif
 | 
						|
    #ifdef STORAGE_MYSQL
 | 
						|
      "mysql", "test", "host='localhost',database='test'",
 | 
						|
    #endif
 | 
						|
    #ifdef STORAGE_POSTGRESQL
 | 
						|
      "postgresql", "test", "host='localhost',database='test'",
 | 
						|
    #endif
 | 
						|
    #ifdef STORAGE_TSTORE
 | 
						|
      "tstore", "test", "host='localhost',database='test'",
 | 
						|
    #endif
 | 
						|
    #ifdef STORAGE_SQLITE
 | 
						|
      "sqlite", "test", "new='yes'",
 | 
						|
    #endif
 | 
						|
	NULL, NULL, NULL
 | 
						|
  };
 | 
						|
 | 
						|
  int test = 0;
 | 
						|
  int ret  = 0;
 | 
						|
  
 | 
						|
  world=librdf_new_world();
 | 
						|
  librdf_world_open(world);
 | 
						|
 | 
						|
  for ( ; storages[test] != NULL; test += 3) {
 | 
						|
 | 
						|
    fprintf(stdout, "%s: Creating storage %s\n", program, storages[test]);
 | 
						|
    storage=librdf_new_storage(world,
 | 
						|
                               storages[test], /* type */
 | 
						|
                               storages[test+1], /* name */
 | 
						|
                               storages[test+2]); /* options */
 | 
						|
    if(!storage) {
 | 
						|
      fprintf(stderr, "%s: WARNING: Failed to create new storage %s\n",
 | 
						|
              program, storages[test]);
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    fprintf(stdout, "%s: Opening storage\n", program);
 | 
						|
    if(librdf_storage_open(storage, NULL)) {
 | 
						|
      fprintf(stderr, "%s: Failed to open storage type %s\n",
 | 
						|
              program, storages[test]);
 | 
						|
      ret++;
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /* Can do nothing here since need model and storage working */
 | 
						|
 | 
						|
    fprintf(stdout, "%s: Closing storage\n", program);
 | 
						|
    librdf_storage_close(storage);
 | 
						|
 | 
						|
    fprintf(stdout, "%s: Freeing storage\n", program);
 | 
						|
    librdf_free_storage(storage);
 | 
						|
 | 
						|
  }
 | 
						|
  
 | 
						|
 | 
						|
  librdf_free_world(world);
 | 
						|
  
 | 
						|
  return ret;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |