예제 #1
0
파일: db.c 프로젝트: agilebarbecue/csync2
void csync_db_fin(void *vmx, const char *err)
{
        db_stmt_p stmt = (db_stmt_p) vmx;
	int rc, busyc = 0;

	if (vmx == NULL)
	   return;

	csync_debug(2, "SQL Query finished.\n");

	while (1) {
	  rc = db_stmt_close(stmt);
	  if ( rc != DB_BUSY ) 
	    break;
	  if (busyc++ > get_dblock_timeout()) { db = 0; csync_fatal(DEADLOCK_MESSAGE); }
	  csync_debug(2, "Database is busy, sleeping a sec.\n");
	  sleep(1);
	}

	if ( rc != DB_OK && err )
		csync_fatal("Database Error: %s [%d]: %s\n", err, rc, db_errmsg(db));

	csync_db_maycommit();
	in_sql_query--;
}
예제 #2
0
파일: db.c 프로젝트: agilebarbecue/csync2
int csync_db_next(void *vmx, const char *err,
		int *pN, const char ***pazValue, const char ***pazColName)
{
	db_stmt_p stmt = vmx;
	int rc, busyc = 0;

	csync_debug(4, "Trying to fetch a row from the database.\n");

	while (1) {
		rc = db_stmt_next(stmt);
		if ( rc != DB_BUSY ) 
		  break;
		if (busyc++ > get_dblock_timeout()) { 
		  db = 0; 
		  csync_fatal(DEADLOCK_MESSAGE); 
		}
		csync_debug(2, "Database is busy, sleeping a sec.\n");
		sleep(1);
	}

	if ( rc != DB_OK && rc != DB_ROW &&
	     rc != DB_DONE && err )
		csync_fatal("Database Error: %s [%d]: %s\n", err, rc, db_errmsg(db));

	return rc == DB_ROW;
}
예제 #3
0
파일: db.c 프로젝트: agilebarbecue/csync2
void* csync_db_begin(const char *err, const char *fmt, ...)
{
	db_stmt_p stmt = NULL;
	char *sql;
	va_list ap;
	int rc, busyc = 0;
	char *ppTail; 
	va_start(ap, fmt);
	VASPRINTF(&sql, fmt, ap);
	va_end(ap);

	in_sql_query++;
	csync_db_maybegin();

	csync_debug(2, "SQL: %s\n", sql);
	while (1) {
	        rc = db_prepare_stmt(db, sql, &stmt, &ppTail);
		if ( rc != DB_BUSY ) break;
		if (busyc++ > get_dblock_timeout()) { db = 0; csync_fatal(DEADLOCK_MESSAGE); }
		csync_debug(2, "Database is busy, sleeping a sec.\n");
		sleep(1);
	}

	if ( rc != DB_OK && err )
		csync_fatal("Database Error: %s [%d]: %s on executing %s\n", err, rc, db_errmsg(db), sql);
	free(sql);

	return stmt;
}
예제 #4
0
int ListMgr_Insert(lmgr_t *p_mgr, entry_id_t *p_id, attr_set_t *p_info,
                   int update_if_exists)
{
    int rc;
    char buff[4096];

    /* retry the whole transaction when the error is retryable */
retry:
    rc = lmgr_begin(p_mgr);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc)
        return rc;

    rc = listmgr_batch_insert_no_tx(p_mgr, &p_id, &p_info, 1, update_if_exists);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc)
    {
        lmgr_rollback(p_mgr);
        DisplayLog(LVL_CRIT, LISTMGR_TAG,
                   "DB query failed in %s line %d: code=%d: %s",
                   __FUNCTION__, __LINE__, rc, db_errmsg(&p_mgr->conn, buff, 4096));
        return rc;
    }
    rc = lmgr_commit(p_mgr);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;

    /* success, count it */
    if (!rc)
        p_mgr->nbop[OPIDX_INSERT]++;
    return rc;
}
예제 #5
0
/**
 * Insert a batch of entries into the database.
 * All entries must have the same attr mask.
 */
int            ListMgr_BatchInsert(lmgr_t * p_mgr, entry_id_t ** p_ids,
                                   attr_set_t ** p_attrs,
                                   unsigned int count,
                                   int update_if_exists)
{
    int rc;
    char buff[4096];

    if (count == 0)
        return DB_SUCCESS;
    else if (p_ids == NULL || p_attrs == NULL)
        RBH_BUG("NULL pointer argument");

    /* read only fields in info mask? */
    if (readonly_attr_set & p_attrs[0]->attr_mask)
    {
        DisplayLog(LVL_MAJOR, LISTMGR_TAG, "Error: trying to insert read only values: attr_mask=%#x",
                   readonly_attr_set & p_attrs[0]->attr_mask);
        return DB_INVALID_ARG;
    }

    /* retry the whole transaction when the error is retryable */
retry:
    /* We want insert operation set to be atomic */
    rc = lmgr_begin(p_mgr);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc)
        return rc;

    rc = listmgr_batch_insert_no_tx(p_mgr, p_ids, p_attrs, count, update_if_exists);

    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    else if (rc)
    {
        lmgr_rollback(p_mgr);
        DisplayLog(LVL_CRIT, LISTMGR_TAG,
                   "DB query failed in %s line %d: code=%d: %s",
                   __FUNCTION__, __LINE__, rc, db_errmsg(&p_mgr->conn, buff, 4096));
        return rc;
    }

    rc = lmgr_commit(p_mgr);
    if (lmgr_delayed_retry(p_mgr, rc))
        goto retry;
    /* success, count it */
    if (!rc)
    {
        if (update_if_exists)
            p_mgr->nbop[OPIDX_UPDATE] += count;
        else
            p_mgr->nbop[OPIDX_INSERT] += count;
    }
    return rc;
}
예제 #6
0
int insert_stripe_info( lmgr_t * p_mgr, PK_ARG_T pk, 
                        int validator, const stripe_info_t * p_stripe,
                        const stripe_items_t * p_items,
                        int update_if_exists )
{
    int            i, rc;
    int            created = FALSE;

    if ( p_stripe == NULL )
        return DB_INVALID_ARG;

    do
    {
        char short_query[4096];
        /* First insert info into STRIPE_INFO_TABLE,
         * so if a file is already present with the same id,
         * we will remove its previous stripe info */

        sprintf( short_query, "INSERT INTO " STRIPE_INFO_TABLE
                 "(id,validator, stripe_count,stripe_size,pool_name) "
                 "VALUES ("DPK",%u,%u,%u,'%s')", pk, validator,
                 p_stripe->stripe_count, ( unsigned int ) p_stripe->stripe_size,
                 p_stripe->pool_name );

        if ( update_if_exists )
            rc = db_exec_sql_quiet( &p_mgr->conn, short_query, NULL );
        else
            rc = db_exec_sql( &p_mgr->conn, short_query, NULL );

        if ( rc == 0 )
        {
            created = TRUE;
        }
        else if ( (rc == DB_ALREADY_EXISTS) && update_if_exists )
        {
            /* remove previous stripe info */
            DisplayLog( LVL_EVENT, LISTMGR_TAG,
                        "A stripe info already exists with this identifier, removing it" );
            rc = delete_stipe_info( p_mgr, pk );
        }

        if ( rc != 0 )
        {
            DisplayLog( LVL_CRIT, LISTMGR_TAG,
                        "DB query failed in %s line %d: code=%d: %s",
                        __FUNCTION__, __LINE__, rc, db_errmsg( &p_mgr->conn, short_query, 4096 ) );
            return rc;
        }

    }
    while ( !created );         /* retry loop in case a similar entry already exists */

    /* then insert stripe items */
    if ( (p_items != NULL) && (p_items->count > 0) )
    {
        ssize_t         len;
        unsigned int    est_len;
        char            *query = NULL;
        
        /* estimate query size = fix part + stripe_count * ( 4 + pklen + ost_idx_len )
         *                     = ~64(oversize to 128) + stripe_count * 4 + 128
         */
        est_len = 128 + p_items->count * 128;
        DisplayLog( LVL_FULL, LISTMGR_TAG, "Estimated query size for %u stripe = %u",  p_items->count, est_len );
        query = MemAlloc(est_len);
        if (query == NULL) {
            DisplayLog( LVL_CRIT, LISTMGR_TAG, "Not enough memory to build SQL query (length = %u)", est_len );
            return DB_NO_MEMORY;
        }

        strcpy( query, "INSERT INTO " STRIPE_ITEMS_TABLE "(id, storage_item) VALUES " );
        len = strlen( query );

        /* first stripe item */
        len += snprintf( query + len, est_len - len, "("DPK",%u)", pk, p_items->stripe_units[0] );

        /* next items */
        for ( i = 1; i < p_items->count; i++ )
        {
            len += snprintf( query + len, est_len - len, ",("DPK",%u)", pk, p_items->stripe_units[i] );

            if ( len >= est_len )
            {
                DisplayLog( LVL_CRIT, LISTMGR_TAG,
                            "Error in %s(): query too long (>%u bytes long), stripe_count=%d",
                            __FUNCTION__, est_len, p_items->count );
                MemFree( query );
                return DB_BUFFER_TOO_SMALL;
            }
        }

        rc = db_exec_sql( &p_mgr->conn, query, NULL );
        if ( rc )
        {
            DisplayLog( LVL_CRIT, LISTMGR_TAG,
                        "DB query failed in %s line %d: code=%d: %s",
                        __FUNCTION__, __LINE__, rc, db_errmsg( &p_mgr->conn, query, 4096 ) );
            MemFree( query );
            return rc;
        }
        MemFree( query );
    }

    return 0;
}
예제 #7
0
파일: db.c 프로젝트: agilebarbecue/csync2
void csync_db_open(const char *file)
{
        int rc = db_open(file, db_type, &db);
	if ( rc != DB_OK )
		csync_fatal("Can't open database: %s\n", file);

	db_set_logger(db, csync_debug);

	/* ignore errors on table creation */
	in_sql_query++;

	if (db_schema_version(db) < DB_SCHEMA_VERSION)
		if (db_upgrade_to_schema(db, DB_SCHEMA_VERSION) != DB_OK)
			csync_fatal("Cannot create database tables (version requested = %d): %s\n", DB_SCHEMA_VERSION, db_errmsg(db));

	if (!db_sync_mode)
		db_exec(db, "PRAGMA synchronous = OFF");
	in_sql_query--;
	// return db;
}