int find_text( db_t hdb, const char * textid, const char * locale ) { int rc = EXIT_FAILURE; db_result_t db_rc = DB_OK; db_row_t row; db_cursor_t c; db_table_cursor_t p = { STORAGE_PKEY_INDEX_NAME, //< No index DB_SCAN_FORWARD | DB_LOCK_EXCLUSIVE }; char en[MAX_TEXT_LEN + 1] = {0}; char tr[MAX_TEXT_LEN + 1] = {0}; int target_fno = EN_FNO; if( 0 == strncmp( "jp", locale, 2 ) ) { target_fno = JP_FNO; } else if( 0 == strncmp( "fr", locale, 2 ) ) { target_fno = FR_FNO; } else if( 0 == strncmp( "es", locale, 2 ) ) { target_fno = ES_FNO; } else if( 0 == strncmp( "ru", locale, 2 ) ) { target_fno = RU_FNO; } c = db_open_table_cursor(hdb, STORAGE_TABLE, &p); row = db_alloc_row( NULL, 2 ); if( NULL == row ) { print_error_message( "Couldn't pupulate 'storage' table\n" ); return EXIT_FAILURE; } dbs_bind_addr( row, ID_FNO, DB_VARTYPE_ANSISTR, (char*)textid, strlen(textid), NULL ); if( DB_OK == db_seek( c, DB_SEEK_FIRST_EQUAL, row, 0, 1 ) ) { db_unbind_field( row, ID_FNO ); dbs_bind_addr( row, EN_FNO, DB_VARTYPE_UTF8STR, en, MAX_TEXT_LEN, NULL ); if( target_fno != EN_FNO ) { dbs_bind_addr( row, target_fno, DB_VARTYPE_UTF8STR, tr, MAX_TEXT_LEN, NULL ); } if( DB_OK == db_fetch( c, row, 0 ) ) { fprintf( stdout, "Message. Id: %s, en: [%s], %s: [%s]\n", textid, en, locale, target_fno == EN_FNO ? "" : tr ); rc = EXIT_SUCCESS; } } if( rc != EXIT_SUCCESS ) { print_error_message( "Couldn't find translated text for messageid %s\n", textid ); } db_free_row( row ); db_close_cursor( c ); return rc; }
/** * Convert a row from the result query into db API representation */ int db_postgres_convert_row(const db_con_t* _h, db_res_t* _r, db_row_t* _row, char **row_buf) { int col, len; if (!_h || !_r || !_row) { LM_ERR("invalid parameter value\n"); return -1; } /* Save the number of columns in the ROW structure */ ROW_N(_row) = RES_COL_N(_r); /* For each column in the row */ for(col = 0; col < ROW_N(_row); col++) { /* compute the len of the value */ if ( row_buf[col]==NULL || row_buf[col][0]=='\0') len = 0; else len = strlen(row_buf[col]); /* Convert the string representation into the value representation */ if (db_postgres_str2val(RES_TYPES(_r)[col], &(ROW_VALUES(_row)[col]), row_buf[col], len) < 0) { LM_ERR("failed to convert value\n"); LM_DBG("free row at %pn", _row); db_free_row(_row); return -3; } } return 0; }
int load_data( db_t hdb ) { db_result_t rc = DB_OK; int i; db_row_t row; db_table_cursor_t p = { NULL, //< No index DB_CAN_MODIFY | DB_LOCK_EXCLUSIVE }; db_cursor_t c; c = db_open_table_cursor(hdb, STORAGE_TABLE, &p); row = db_alloc_row( binds_def, DB_ARRAY_DIM( binds_def ) ); if( NULL == row ) { print_error_message( "Couldn't allocate row to pupulate 'storage' table\n" ); return EXIT_FAILURE; } for( i = 0; i < DB_ARRAY_DIM(texts) && DB_OK == rc; ++i ) { rc = db_insert(c, row, &texts[i], 0); } db_free_row( row ); rc = DB_OK == rc ? db_commit_tx( hdb, 0 ) : rc; if( DB_OK != rc ) { print_error_message( "Couldn't pupulate 'storage' table\n" ); } db_close_cursor(c); return DB_OK == rc ? EXIT_SUCCESS : EXIT_FAILURE; }
/*! * \brief Convert a row from result into DB API representation * \param _h database connection * \param _res database result in the DB API representation * \param _r database result row * \return 0 on success, -1 on failure */ int db_mysql_convert_row(const db1_con_t* _h, db1_res_t* _res, db_row_t* _r) { unsigned long* lengths; int i; if ((!_h) || (!_res) || (!_r)) { LM_ERR("invalid parameter value\n"); return -1; } if (db_allocate_row(_res, _r) != 0) { LM_ERR("could not allocate row"); return -2; } lengths = mysql_fetch_lengths(CON_RESULT(_h)); for(i = 0; i < RES_COL_N(_res); i++) { if (db_str2val(RES_TYPES(_res)[i], &(ROW_VALUES(_r)[i]), ((MYSQL_ROW)CON_ROW(_h))[i], lengths[i], 0) < 0) { LM_ERR("failed to convert value\n"); LM_DBG("free row at %p\n", _r); db_free_row(_r); return -3; } } return 0; }
/*! * \brief Convert a row from the result query into db API representation * \param _h database connection * \param _r result set * \param _row row * \param row_buf row buffer * \return 0 on success, negative on error */ int db_postgres_convert_row(const db1_con_t* _h, db1_res_t* _r, db_row_t* _row, char **row_buf) { int col, col_len; if (!_h || !_r || !_row) { LM_ERR("invalid parameter value\n"); return -1; } if (db_allocate_row(_r, _row) != 0) { LM_ERR("could not allocate row\n"); return -2; } /* For each column in the row */ for(col = 0; col < ROW_N(_row); col++) { /* because it can contain NULL */ if (!row_buf[col]) { col_len = 0; } else { col_len = strlen(row_buf[col]); } /* Convert the string representation into the value representation */ if (db_postgres_str2val(RES_TYPES(_r)[col], &(ROW_VALUES(_row)[col]), row_buf[col], col_len) < 0) { LM_ERR("failed to convert value\n"); LM_DBG("free row at %p\n", _row); db_free_row(_row); return -3; } } return 0; }
int populate_data( db_t hdb ) { db_result_t rc = DB_OK; int i; /* Populate "storage" table using relative bounds fields. See ittiadb/manuals/users-guide/api-c-database-access.html#relative-bound-fields */ typedef struct { db_ansi_t f0[MAX_STRING_FIELD + 1]; /* Extra char for null termination. */ uint64_t f1; double f2; char f3[MAX_STRING_FIELD*2 + 1]; } storage_t; static const db_bind_t binds_def[] = { { 0, DB_VARTYPE_ANSISTR, DB_BIND_OFFSET( storage_t, f0 ), DB_BIND_SIZE( storage_t, f0 ), -1, DB_BIND_RELATIVE }, { 1, DB_VARTYPE_SINT64, DB_BIND_OFFSET( storage_t, f1 ), DB_BIND_SIZE( storage_t, f1 ), -1, DB_BIND_RELATIVE }, { 2, DB_VARTYPE_FLOAT64, DB_BIND_OFFSET( storage_t, f2 ), DB_BIND_SIZE( storage_t, f2 ), -1, DB_BIND_RELATIVE }, { 3, DB_VARTYPE_UTF8STR, DB_BIND_OFFSET( storage_t, f3 ), DB_BIND_SIZE( storage_t, f3 ), -1, DB_BIND_RELATIVE }, }; static storage_t rows2ins[] = { { "ansi_str1", 1, 1.231, "utf8" }, { "ansi_str2", 2, 2.231, "utf8" }, { "ansi_str3", 3, 3.231, "УТФ-8" }, { "ansi_str4", 4, 4.231, "utf8" }, { "ansi_str5", 5, 5.231, "utf8" }, }; db_row_t row; db_table_cursor_t p = { NULL, //< No index DB_CAN_MODIFY | DB_LOCK_EXCLUSIVE }; db_cursor_t c; row = db_alloc_row( binds_def, DB_ARRAY_DIM( binds_def ) ); if( NULL == row ) { print_error_message( "Couldn't pupulate 'storage' table\n" ); return EXIT_FAILURE; } c = db_open_table_cursor(hdb, STORAGE_TABLE, &p); for( i = 0; i < DB_ARRAY_DIM(rows2ins) && DB_OK == rc; ++i ) { rc = db_insert(c, row, &rows2ins[i], 0); } db_free_row( row ); rc = DB_OK == rc ? db_commit_tx( hdb, 0 ) : rc; if( DB_OK != rc ) { print_error_message( "Couldn't pupulate 'storage' table\n" ); } db_close_cursor(c); return DB_OK == rc ? EXIT_SUCCESS : EXIT_FAILURE; }
int perform_transactions( db_t hdb, trans_stat_t *stat ) { int i; db_row_t row; db_table_cursor_t p = { NULL, //< No index DB_CAN_MODIFY | DB_LOCK_EXCLUSIVE }; db_cursor_t c; db_result_t db_rc; storage_t row2ins = { "ansi_str1", 1, 1.231, "utf8" }; // Allocate row. binds_def see in db_schema.h row = db_alloc_row( binds_def, DB_ARRAY_DIM( binds_def ) ); if( NULL == row ) { print_error_message( "Couldn't allocate db_row_t\n", NULL ); return EXIT_FAILURE; } // Open cursor c = db_open_table_cursor(hdb, STORAGE_TABLE, &p); db_rc = DB_OK; for( i = 0; i < 100 && DB_OK == db_rc; ++i ) { int do_lazy_commit = i % 5; db_rc = db_begin_tx( hdb, 0 ); row2ins.f1 = i+1; row2ins.f2 = do_lazy_commit ? 50 : 16; db_rc = db_insert(c, row, &row2ins, 0); db_commit_tx( hdb, do_lazy_commit ? DB_LAZY_COMPLETION : DB_DEFAULT_COMPLETION ); if( do_lazy_commit ) { stat->lazy_tx++; } else { stat->forced_tx++; } if( i % 30 ) { db_flush_tx( hdb, DB_FLUSH_JOURNAL ); } } if( DB_OK != db_rc ) { print_error_message( "Error inserting or commiting\n", c ); } db_close_cursor( c ); db_free_row( row ); return DB_OK == db_rc ? EXIT_SUCCESS : EXIT_FAILURE; }
/** * Convert a row from result into db API representation */ int db_mysql_convert_row(const db_con_t* _h, db_res_t* _res, db_row_t* _r) { unsigned long* lengths; int i; if ((!_h) || (!_res) || (!_r)) { LM_ERR("invalid parameter value\n"); return -1; } /* Save the number of columns in the ROW structure */ ROW_N(_r) = RES_COL_N(_res); if (CON_HAS_PS(_h)) { for(i=0; i < CON_MYSQL_PS(_h)->cols_out; i++) { if (db_mysql_str2val(RES_TYPES(_res)[i], &(ROW_VALUES(_r)[i]), CON_PS_OUTCOL(_h, i).null?NULL:CON_PS_OUTCOL(_h, i).buf, CON_PS_OUTCOL(_h,i).len) < 0) { LM_ERR("failed to convert value from stmt\n"); db_free_row(_r); return -3; } } } else { lengths = mysql_fetch_lengths(CON_RESULT(_h)); for(i = 0; i < RES_COL_N(_res); i++) { if (db_mysql_str2val(RES_TYPES(_res)[i], &(ROW_VALUES(_r)[i]), ((MYSQL_ROW)CON_ROW(_h))[i], lengths[i]) < 0) { LM_ERR("failed to convert value\n"); LM_DBG("free row at %p\n", _r); db_free_row(_r); return -3; } } } return 0; }
/* * Release memory used by rows */ int db_free_rows(db_res_t* _r) { int i; if (!_r) { LM_ERR("invalid parameter value\n"); return -1; } LM_DBG("freeing %d rows\n", RES_ROW_N(_r)); if (RES_ROWS(_r)) { for(i = 0; i < RES_ROW_N(_r); i++) db_free_row(&(RES_ROWS(_r)[i])); LM_DBG("freeing rows at %p\n", RES_ROWS(_r)); pkg_free(RES_ROWS(_r)); RES_ROWS(_r) = NULL; } RES_ROW_N(_r) = 0; return 0; }
/* * Convert a row from result into db API representation */ int db_unixodbc_convert_row(const db_con_t* _h, const db_res_t* _res, db_row_t* _r, const unsigned long* lengths) { int i; if ((!_h) || (!_res) || (!_r)) { LM_ERR("invalid parameter value\n"); return -1; } /* Save the number of columns in the ROW structure */ ROW_N(_r) = RES_COL_N(_res); for(i = 0; i < RES_COL_N(_res); i++) { if (db_unixodbc_str2val(RES_TYPES(_res)[i], &(ROW_VALUES(_r)[i]), ((CON_ROW(_h))[i]), lengths[i]) < 0) { LM_ERR("failed to convert value\n"); LM_DBG("free row at %p\n", _r); db_free_row(_r); return -3; } } return 0; }
/* * Release memory used by rows */ inline int db_free_rows(db_res_t* _r) { int i; if (!_r) { LM_ERR("invalid parameter value\n"); return -1; } LM_DBG("freeing %d rows\n", RES_ROW_N(_r)); for(i = 0; i < RES_ROW_N(_r); i++) { LM_DBG("row[%d]=%p\n", i, &(RES_ROWS(_r)[i])); db_free_row(&(RES_ROWS(_r)[i])); } RES_ROW_N(_r) = 0; if (RES_ROWS(_r)) { LM_DBG("%p=pkg_free() RES_ROWS\n", RES_ROWS(_r)); pkg_free(RES_ROWS(_r)); RES_ROWS(_r) = NULL; } return 0; }
int check_data( db_t hdb, const trans_stat_t * stat ) { int rc = EXIT_FAILURE; db_result_t db_rc = DB_OK; db_row_t row; storage_t row_data; db_cursor_t c; // Cursor to scan table to check // Cursor parameters db_table_cursor_t p = { PKEY_INDEX_NAME, //< Index by which to sort the table DB_SCAN_FORWARD | DB_LOCK_DEFAULT }; // Open cursor c = db_open_table_cursor(hdb, STORAGE_TABLE, &p); row = db_alloc_row( binds_def, DB_ARRAY_DIM( binds_def ) ); db_rc = db_seek_first(c); // Scan table and check that pkey values are monotonically increase { int counter = 0; trans_stat_t s = { 0, 0 }; for(; !db_eof(c) && DB_OK == db_rc; db_rc = db_seek_next(c) ) { db_rc = db_fetch(c, row, &row_data); if( row_data.f1 != ++counter ) { break; } s.lazy_tx += row_data.f2 == 50 ? 1 : 0; s.forced_tx += row_data.f2 == 16 ? 1 : 0; } if( DB_OK != db_rc ) { print_error_message( "Error to scan table of backup db\n", c ); } else if( row_data.f1 != counter ) { fprintf( stderr, "Pkey field values sequence violation detected in backup db: (%" PRId64 ", %d)\n", row_data.f1, counter ); } else if( s.lazy_tx != stat->lazy_tx ) { fprintf( stderr, "Unexpected count of records which was commited in lazy-commit mode: %d, but expected %d.\n", s.lazy_tx, stat->lazy_tx ); } else if( s.forced_tx != stat->forced_tx ) { fprintf( stderr, "Unexpected count of records which was commited in force-commit mode: %d, but expected %d.\n", s.forced_tx, stat->forced_tx ); } else { fprintf( stdout, "%d records is inside\n", counter ); rc = EXIT_SUCCESS; } } db_close_cursor( c ); db_free_row( row ); db_shutdown(hdb, DB_SOFT_SHUTDOWN, NULL); return rc; }
static db_result_t upgrade_to_schema_v2( db_t hdb ) { db_result_t rc = DB_OK; /* 1. Convert string type v1's 'sex_title' column to int-type 'sex' column, as v2 schema declares */ /* 1.1. Append a new uint8 type 'sex' column */ db_fielddef_t sex = { CONTACT_NFIELDS, "sex", DB_COLTYPE_UINT8, 0, 0, DB_NULLABLE, 0 }; /* 1.2. Fill 'sex' column with data according to schema: Mr->0, Mrs->1,Other->2 */ // Use absolute bound fields ( see ittiadb/manuals/users-guide/api-c-database-access.html#absolute-bound-fields ) db_ansi_t sex_old[ MAX_SEX_TITLE + 1 ]; db_len_t sex_ind = DB_FIELD_NULL, sex_ind_new = DB_FIELD_NULL; uint8_t sex_new = 0; db_bind_t binds_def[] = { {CONTACT_SEX, DB_VARTYPE_ANSISTR, DB_BIND_ADDRESS(sex_old), sizeof(sex_old), DB_BIND_ADDRESS(&sex_ind), DB_BIND_ABSOLUTE}, {CONTACT_NFIELDS, DB_VARTYPE_UINT8, DB_BIND_ADDRESS(&sex_new), sizeof(sex_new), DB_BIND_ADDRESS(&sex_ind_new), DB_BIND_ABSOLUTE}, }; db_row_t row = db_alloc_row( binds_def, 2 ); db_table_cursor_t p = { NULL, //< No index DB_CAN_MODIFY | DB_LOCK_EXCLUSIVE }; db_cursor_t c; rc = db_add_field( hdb, CONTACT_TABLE, &sex ); if( DB_OK != rc ) { print_error_message( "Couldn't append 'sex' column on v1->v2 upgrade", 0 ); return DB_FAIL; } c = db_open_table_cursor(hdb, CONTACT_TABLE, &p); db_begin_tx( hdb, DB_DEFAULT_ISOLATION | DB_LOCK_DEFAULT ); for ( rc = db_seek_first( c ); DB_OK == rc && !db_eof( c ); db_seek_next( c ) ) { rc = db_fetch( c, row, 0 ); if( 0 == strcmp( "Mr", sex_old ) ) { sex_new = 0; } else if( 0 == strcmp( "Mrs", sex_old ) ) { sex_new = 1; } else { sex_new = 2; } sex_ind_new = 0; rc = db_update( c, row, 0 ); } db_commit_tx( hdb, DB_DEFAULT_COMPLETION ); if( DB_OK != rc ) { print_error_message( "Couldn't fill appended 'sex' column with data", c ); } db_free_row( row ); db_close_cursor( c ); /* 1.3 Drop v1 sex_title column. */ /* Note: Dropping columns isn't available in ITTIA evaluation version. */ rc = db_drop_field( hdb, CONTACT_TABLE, "sex_title" ); if( DB_OK != rc ) { if( DB_EEVALUATION == get_db_error() ) { rc = DB_OK; fprintf( stdout, "No db_drop_field() feature supported in ITTIA Evaluation version\n" ); } else { print_error_message( "Couldn't drop 'sex_title' v1 schema column", c ); } } /* 2. Indexes modifications */ // 2.1. drop old pkey rc = db_drop_index( hdb, CONTACT_TABLE, CONTACT_BY_ID ); if ( DB_OK != rc ) { print_error_message( "Couldn't drop v1 pkey index", c ); } // 2.2. create a new one // 2.2.1. Set NOT NULL property on ring_id field // Note: this feature isn't supported in evaluation version of ittiadb. { extern db_fielddef_t contact_fields[]; //< Defined in schema_upgrade_schema_v2.c rc = db_update_field( hdb, CONTACT_TABLE, "ring_id", &contact_fields[ CONTACT_RING_ID ] ); if ( DB_OK != rc ) { print_error_message( "Couldn't set not null on ring_id column", c ); } } // 2.2.2. Create PKey index { extern db_indexdef_t contact_indexes[]; //< Defined in schema_upgrade_schema_v2.c rc = db_create_index( hdb, CONTACT_TABLE, CONTACT_BY_ID_RING_ID, &contact_indexes[0] ); if ( DB_OK != rc ) { print_error_message( "Couldn't create v2 pkey index", c ); } } }
int init_data_cb( db_t hdb, int version ) { db_result_t rc = DB_OK; int i; /* Populate "contact" table using relative bounds fields. See ittiadb/manuals/users-guide/api-c-database-access.html#relative-bound-fields */ static const db_bind_t binds_def[] = { { CONTACT_ID, DB_VARTYPE_UINT64, DB_BIND_OFFSET( contact_t, id ), DB_BIND_SIZE( contact_t, id ), -1, DB_BIND_RELATIVE }, { CONTACT_NAME, DB_VARTYPE_WCHARSTR, DB_BIND_OFFSET( contact_t, name ), DB_BIND_SIZE( contact_t, name ), -1, DB_BIND_RELATIVE }, { CONTACT_RING_ID, DB_VARTYPE_UINT64, DB_BIND_OFFSET( contact_t, ring_id ), DB_BIND_SIZE( contact_t, ring_id ), -1, DB_BIND_RELATIVE }, { CONTACT_SEX, DB_VARTYPE_ANSISTR, DB_BIND_OFFSET( contact_t, sex ), DB_BIND_SIZE( contact_t, sex ), -1, DB_BIND_RELATIVE }, }; contact_t contacts2ins[] = { { 1, L"Bob", 1, "Mr" }, { 2, L"Alice", 1, "Mrs" }, { 3, L"Fred", 1, "Mr" }, { 4, L"Mary", 1, "Mrs" }, }; db_row_t row; db_table_cursor_t p = { NULL, //< No index DB_CAN_MODIFY | DB_LOCK_EXCLUSIVE }; db_cursor_t c; if( 1 > version || 2 < version ) { print_error_message("Wrong DB schema version. Can't insert data.", NULL); return -1; } fprintf( stdout, "Populating just creating DB v%d with data\n", version ); row = db_alloc_row( binds_def, DB_ARRAY_DIM( binds_def ) ); c = db_open_table_cursor(hdb, CONTACT_TABLE, &p); for( i = 0; i < DB_ARRAY_DIM(contacts2ins) && DB_OK == rc; ++i ) { if( 2 == version ) { if( 0 == strcmp( contacts2ins[i].sex, "Mrs" ) ) { strcpy( contacts2ins[i].sex, "1" ); } else if( 0 == strcmp( contacts2ins[i].sex, "Mr" ) ) { strcpy( contacts2ins[i].sex, "0" ); } else { strcpy( contacts2ins[i].sex, "2" ); } } rc = db_insert(c, row, &contacts2ins[i], 0); } db_free_row( row ); if( DB_OK != rc ) { print_error_message( "Couldn't pupulate 'contact' table\n", c ); } db_close_cursor(c); return DB_OK == rc ? 0 : -1; }