Exemplo n.º 1
0
static int cdbi_connect_database (cdbi_database_t *db) /* {{{ */
{
  dbi_driver driver;
  dbi_conn connection;
  size_t i;
  int status;

  if (db->connection != NULL)
  {
    status = dbi_conn_ping (db->connection);
    if (status != 0) /* connection is alive */
      return (0);

    dbi_conn_close (db->connection);
    db->connection = NULL;
  }

  driver = dbi_driver_open_r (db->driver, dbi_instance);
  if (driver == NULL)
  {
    ERROR ("dbi plugin: cdbi_connect_database: dbi_driver_open_r (%s) failed.",
        db->driver);
    INFO ("dbi plugin: Maybe the driver isn't installed? "
        "Known drivers are:");
    for (driver = dbi_driver_list_r (NULL, dbi_instance);
        driver != NULL;
        driver = dbi_driver_list_r (driver, dbi_instance))
    {
      INFO ("dbi plugin: * %s", dbi_driver_get_name (driver));
    }
    return (-1);
  }

  connection = dbi_conn_open (driver);
  if (connection == NULL)
  {
    ERROR ("dbi plugin: cdbi_connect_database: dbi_conn_open (%s) failed.",
        db->driver);
    return (-1);
  }

  /* Set all the driver options. Because this is a very very very generic
   * interface, the error handling is kind of long. If an invalid option is
   * encountered, it will get a list of options understood by the driver and
   * report that as `INFO'. This way, users hopefully don't have too much
   * trouble finding out how to configure the plugin correctly.. */
  for (i = 0; i < db->driver_options_num; i++)
  {
    if (db->driver_options[i].is_numeric)
    {
      status = dbi_conn_set_option_numeric (connection,
          db->driver_options[i].key, db->driver_options[i].value.numeric);
      if (status != 0)
      {
        char errbuf[1024];
        ERROR ("dbi plugin: cdbi_connect_database (%s): "
            "dbi_conn_set_option_numeric (\"%s\", %i) failed: %s.",
            db->name,
            db->driver_options[i].key, db->driver_options[i].value.numeric,
            cdbi_strerror (connection, errbuf, sizeof (errbuf)));
      }
    }
    else
    {
      status = dbi_conn_set_option (connection,
          db->driver_options[i].key, db->driver_options[i].value.string);
      if (status != 0)
      {
        char errbuf[1024];
        ERROR ("dbi plugin: cdbi_connect_database (%s): "
            "dbi_conn_set_option (\"%s\", \"%s\") failed: %s.",
            db->name,
            db->driver_options[i].key, db->driver_options[i].value.string,
            cdbi_strerror (connection, errbuf, sizeof (errbuf)));
      }
    }

    if (status != 0)
    {
      char const *opt;

      INFO ("dbi plugin: This is a list of all options understood "
          "by the `%s' driver:", db->driver);
      for (opt = dbi_conn_get_option_list (connection, NULL);
          opt != NULL;
          opt = dbi_conn_get_option_list (connection, opt))
      {
        INFO ("dbi plugin: * %s", opt);
      }

      dbi_conn_close (connection);
      return (-1);
    }
  } /* for (i = 0; i < db->driver_options_num; i++) */

  status = dbi_conn_connect (connection);
  if (status != 0)
  {
    char errbuf[1024];
    ERROR ("dbi plugin: cdbi_connect_database (%s): "
        "dbi_conn_connect failed: %s",
        db->name, cdbi_strerror (connection, errbuf, sizeof (errbuf)));
    dbi_conn_close (connection);
    return (-1);
  }

  if (db->select_db != NULL)
  {
    status = dbi_conn_select_db (connection, db->select_db);
    if (status != 0)
    {
      char errbuf[1024];
      WARNING ("dbi plugin: cdbi_connect_database (%s): "
          "dbi_conn_select_db (%s) failed: %s. Check the `SelectDB' option.",
          db->name, db->select_db,
          cdbi_strerror (connection, errbuf, sizeof (errbuf)));
      dbi_conn_close (connection);
      return (-1);
    }
  }

  db->connection = connection;
  return (0);
} /* }}} int cdbi_connect_database */
Exemplo n.º 2
0
/**
 * check if requested driver is provided by local DBI installation
 * 
 * @param driver_name string with the name of the driver
 * @return 1 if exists, 0 otherwise
 */
int tagsistant_driver_is_available(const char *driver_name)
{
	int counter = 0;
	int driver_found = 0;
	dbi_driver driver = NULL;

	dbg('b', LOG_INFO, "Available drivers:");
#if TAGSISTANT_REENTRANT_DBI
	while ((driver = dbi_driver_list_r(driver, tagsistant.dbi_instance)) != NULL) {
#else
	while ((driver = dbi_driver_list(driver)) != NULL) {
#endif
		counter++;
		dbg('b', LOG_INFO, "  Driver #%d: %s - %s", counter, dbi_driver_get_name(driver), dbi_driver_get_filename(driver));
		if (g_strcmp0(dbi_driver_get_name(driver), driver_name) == 0) {
			driver_found = 1;
		}
	}

	if (!counter) {
		dbg('b', LOG_ERR, "No SQL driver found! Exiting now.");
		return(0);
	}

	if (!driver_found) {
		dbg('b', LOG_ERR, "No %s driver found!", driver_name);
		return(0);
	}

	return(1);
}

/**
 * Contains DBI parsed options
 */
struct {
	int backend;
	gchar *backend_name;
	gchar *host;
	gchar *db;
	gchar *username;
	gchar *password;
} dboptions;

#if TAGSISTANT_ENABLE_TAG_ID_CACHE
/** a map tag_name -> tag_id */
GHashTable *tagsistant_tag_cache = NULL;
#endif

/** regular expressions used to escape query parameters */
GRegex *RX1, *RX2, *RX3;

/**
 * Initialize libDBI structures
 */
void tagsistant_db_init()
{
	// initialize DBI library
#if TAGSISTANT_REENTRANT_DBI
	dbi_initialize_r(NULL, &(tagsistant.dbi_instance));
#else
	dbi_initialize(NULL);
#endif

#if TAGSISTANT_USE_QUERY_MUTEX
	g_mutex_init(&tagsistant_query_mutex);
#endif

#if TAGSISTANT_ENABLE_TAG_ID_CACHE
	tagsistant_tag_cache = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
#endif

	// by default, DBI backend provides intersect
	tagsistant.sql_backend_have_intersect = 1;
	tagsistant.sql_database_driver = TAGSISTANT_NULL_BACKEND;
	dboptions.backend = TAGSISTANT_NULL_BACKEND;

	// if no database option has been passed, use default SQLite3
	if (strlen(tagsistant.dboptions) == 0) {
		tagsistant.dboptions = g_strdup("sqlite3::::");
		dboptions.backend_name = g_strdup("sqlite3");
		dboptions.backend = TAGSISTANT_DBI_SQLITE_BACKEND;
		dbg('b', LOG_INFO, "Using default driver: sqlite3");
	}

	dbg('b', LOG_INFO, "Database options: %s", tagsistant.dboptions);

	// split database option value up to 5 tokens
	gchar **_dboptions = g_strsplit(tagsistant.dboptions, ":", 5);

	// set failsafe DB options
	if (_dboptions[0]) {
		if (strcmp(_dboptions[0], "sqlite3") == 0) {

			tagsistant.sql_database_driver = TAGSISTANT_DBI_SQLITE_BACKEND;
			dboptions.backend = TAGSISTANT_DBI_SQLITE_BACKEND;
			dboptions.backend_name = g_strdup("sqlite3");

		} else if (strcmp(_dboptions[0], "mysql") == 0) {

			tagsistant.sql_database_driver = TAGSISTANT_DBI_MYSQL_BACKEND;
			dboptions.backend = TAGSISTANT_DBI_MYSQL_BACKEND;
			dboptions.backend_name = g_strdup("mysql");

		}
	}

	if (TAGSISTANT_DBI_MYSQL_BACKEND == dboptions.backend) {
		if (_dboptions[1] && strlen(_dboptions[1])) {
			dboptions.host = g_strdup(_dboptions[1]);

			if (_dboptions[2] && strlen(_dboptions[2])) {
				dboptions.db = g_strdup(_dboptions[2]);

				if (_dboptions[3] && strlen(_dboptions[3])) {
					dboptions.username = g_strdup(_dboptions[3]);

					if (_dboptions[4] && strlen(_dboptions[4])) {
						dboptions.password = g_strdup(_dboptions[4]);
					} else {
						dboptions.password = g_strdup("tagsistant");
					}

				} else {
					dboptions.password = g_strdup("tagsistant");
					dboptions.username = g_strdup("tagsistant");
				}

			} else {
				dboptions.password = g_strdup("tagsistant");
				dboptions.username = g_strdup("tagsistant");
				dboptions.db = g_strdup("tagsistant");
			}

		} else {
			dboptions.password = g_strdup("tagsistant");
			dboptions.username = g_strdup("tagsistant");
			dboptions.db = g_strdup("tagsistant");
			dboptions.host = g_strdup("localhost");
		}

	}

	g_strfreev(_dboptions);

#if 0
	dbg('b', LOG_INFO, "Database driver: %s", dboptions.backend_name);

	// list configured options
	const char *option = NULL;
	int counter = 0;
	dbg('b', LOG_INFO, "Connection settings: ");
	while ((option = dbi_conn_get_option_list(tagsistant_dbi_conn, option))	!= NULL ) {
		counter++;
		dbg('b', LOG_INFO, "  Option #%d: %s = %s", counter, option, dbi_conn_get_option(tagsistant_dbi_conn, option));
	}

	// tell if backend have INTERSECT
	if (tagsistant.sql_backend_have_intersect) {
		dbg('b', LOG_INFO, "Database supports INTERSECT operator");
	} else {
		dbg('b', LOG_INFO, "Database does not support INTERSECT operator");
	}
#endif

	/* initialize the regular expressions used to escape the SQL queries */
	RX1 = g_regex_new("[\"']", 0, 0, NULL);
	RX2 = g_regex_new("'", 0, 0, NULL);
	RX3 = g_regex_new("<><>", 0, 0, NULL);
}