예제 #1
0
파일: IoDBI.c 프로젝트: BMeph/io
IoObject *IoDBI_drivers(IoDBI *self, IoObject *locals, IoMessage *m)
{
	/*doc DBI drivers
	Get a list of drivers and its associated information:

	<ol>
		<li>name</li>
		<li>description</li>
		<li>filename</li>
		<li>version</li>
		<li>date compiled</li>
		<li>maintainer</li>
		<li>url</li>
	</ol>
	*/
	IoList *list = IOREF(IoList_new(IOSTATE));
	dbi_driver driver = NULL;

	while((driver = dbi_driver_list(driver)) != NULL)
	{
		IoList *dlist = IOREF(IoList_new(IOSTATE));
		IoList_rawAppend_(dlist, IOSYMBOL(dbi_driver_get_name(driver)));
		IoList_rawAppend_(dlist, IOSYMBOL(dbi_driver_get_description(driver)));
		IoList_rawAppend_(dlist, IOSYMBOL(dbi_driver_get_filename(driver)));
		IoList_rawAppend_(dlist, IOSYMBOL(dbi_driver_get_version(driver)));
		IoList_rawAppend_(dlist, IOSYMBOL(dbi_driver_get_date_compiled(driver)));
		IoList_rawAppend_(dlist, IOSYMBOL(dbi_driver_get_maintainer(driver)));
		IoList_rawAppend_(dlist, IOSYMBOL(dbi_driver_get_url(driver)));

		IoList_rawAppend_(list, dlist);
	}

	return list;
}
예제 #2
0
dbi_result _db_rawquery(const char *file, int line, database *db, int log_dupes, char *qry)
{
    dbi_result result;
    const char *errmsg;
    int tries = 0;

    if (debug > 4) {
        LOGRAW(LOG_DEBUG, qry);
    }

    if (!dbi_conn_ping(db->conn)) {
        if (db->conn) dbi_conn_close(db->conn);
        db->conn = dbi_conn_new(db->driver);
        if (db->conn == NULL) {
            perror(db->driver);
            exit(1);
        }

        dbi_conn_set_option(db->conn, "host", db->host);
        dbi_conn_set_option(db->conn, "port", db->port);
        dbi_conn_set_option(db->conn, "username", db->username);
        dbi_conn_set_option(db->conn, "password", db->password);
        dbi_conn_set_option(db->conn, "dbname", db->name);

retry:
        if (++tries == 3) exit(1);
        if (dbi_conn_connect(db->conn) < 0) {
            dbi_conn_error(db->conn, &errmsg);
            _logsrce = file;
            _logline = line;
            _LOG(LOG_ERR, "%s connection failed to %s:%s:%s %s", db->driver, db->host, db->port, db->name, errmsg);
            sleep(3);
            goto retry;
        }

        {
            char versionstring[VERSIONSTRING_LENGTH];
            dbi_driver driver;

            driver = dbi_conn_get_driver(db->conn);
            dbi_conn_get_engine_version_string(db->conn, versionstring);
            LOG(LOG_INFO, "using driver: %s, version %s, compiled %s", dbi_driver_get_filename(driver), dbi_driver_get_version(driver),
                dbi_driver_get_date_compiled(driver));
            LOG(LOG_INFO, "connected to %s:%s:%s, server version %s", db->host, db->port, db->name, versionstring);
        }
    }

    if (debug > 2) {
        char *src, *dst, buf[4096];

        for (dst = buf, src = qry; *src; src++, dst++) {
            if (*src == '%') *dst++ = '%';
            *dst = *src;
        }
        *dst = 0;
        LOG(LOG_INFO, buf);
    }
    result = dbi_conn_query(db->conn, qry);
    if (result == NULL) {
        int ret = dbi_conn_error(db->conn, &errmsg);
        _logsrce = file;
        _logline = line;
        _LOG(LOG_ERR, "query failed: %s (%s)", errmsg, qry);
        if (ret == DBI_ERROR_NOCONN) {
            dbi_conn_close(db->conn);
            db->conn = NULL;
            sleep(3);
            goto retry;
        }
    }
    return(result);
}
예제 #3
0
파일: sql.c 프로젝트: rowhit/Tagsistant
/**
 * 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);
}