library/src/databases/sqlite/BP-DBSqlite.cc
// Run all queries that are currently in the stack. Run all within
// a transaction.
Run all queries that are currently in the stack. Run all within
a transaction.
Run all queries that are currently in the stack . Run all within a transaction .
BP_ERROR_T BP_SQLiteRunQueries
(
	P_BP_DB_SQLITE sqli
)
{
	if(!sqli)
		return ERR_FAILURE;
	if(!sqli->db)
		return ERR_FAILURE;
	if(!sqli->queries)
		return ERR_FAILURE;
	sqli->last_query_results = NULL;
	sqli->last_result_query_uuid = NULL;
	sqli->last_result_retrieved_n = 0;
	sqli->last_transaction_record_count_retrieved = 0;
	BP_HASH_TABLE_ENTER_CRITICAL_SECTION(sqli->system_hreg);
	char * query_table_path[] = {"queries", NULL};
	P_BP_HASH_TABLE_KEYED_ENTRY query_table = BP_HashRegLookupTableByPath(sqli->queries, query_table_path);
	if(!query_table)
	{
		BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC(sqli->system_hreg, ERR_FAILURE);
	}
	if(!query_table->data)
	{
		BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC(sqli->system_hreg, ERR_FAILURE);
	}
	P_BP_HASH_TABLE_KEYED_ENTRY entry = NULL;
	P_BP_HASH_TABLE_KEYED_ENTRY tmp   = NULL;
	P_BP_HASH_TABLE_KEYED_ENTRY query_table_inner = (P_BP_HASH_TABLE_KEYED_ENTRY) query_table->data;
	BP_BOOL transaction_opened = BP_FALSE;
	P_BP_HASH_TABLE_KEYED_ENTRY last_entry = NULL;
	for
	(
		last_entry = query_table_inner;
		last_entry->hh.next;
		last_entry = (P_BP_HASH_TABLE_KEYED_ENTRY) last_entry->hh.next
	){}
	HASH_ITER(hh, query_table_inner, entry, tmp)
	{
		if(!transaction_opened)
		{
			sqlite3_exec(sqli->db, "BEGIN", 0,0,0);
			transaction_opened = BP_TRUE;
		}
		if(!entry->data)
			continue;
		P_BP_HASH_TABLE_KEYED_ENTRY sql_entry = BP_HashRegLookupEntryFromHashKeyViaRelativePosition
		(
				sqli->queries,
				(P_BP_HASH_TABLE_KEYED_ENTRY) entry,
				"sql"
		);
		if(!sql_entry)
		{
			continue;
		}
		char * sql = (char *) sql_entry->data;
		int rc = sqlite3_prepare_v2(sqli->db, sql, bpstrlen(sql), &sqli->stmt, NULL);
		if(rc != SQLITE_OK)
		{
			printf("\n [!!] Error: Couldn't prepare sqlite query %s - %s", sql, sqlite3_errmsg(sqli->db));
			continue;
		}
		char * lookup_param_table_path[] =
		{
				"queries",
				entry->key,
				"params",
				NULL
		};
		P_BP_HASH_TABLE_KEYED_ENTRY parameters_table = BP_HashRegLookupTableByPath
		(
				sqli->queries,
				(char **) &lookup_param_table_path
		);
		if(parameters_table)
		if(parameters_table->data)
		{
			size_t param_n = 0;
			char param_n_buff[128];
			do
			{
				BP_ZERO_STACK(param_n_buff);
				sprintf((char *) &param_n_buff, "%u", param_n);
				P_BP_HASH_TABLE_KEYED_ENTRY parm_entry = BP_HashRegLookupEntryFromHashKeyViaRelativePosition
				(
						sqli->queries,
						(P_BP_HASH_TABLE_KEYED_ENTRY) parameters_table,
						(char *) &param_n_buff
				);
				if(!parm_entry)
					break;
				if(!parm_entry->data)
					break;
				P_BP_SQLITE_QUERY_PARAM param = (P_BP_SQLITE_QUERY_PARAM) parm_entry->data;
				unsigned long key_as_ul = strtoul(parm_entry->key, NULL, 10);
				key_as_ul++;
				int parm_as_int     = 0;
				double parm_as_double = 0;
				switch(param->type)
				{
					case BP_DB_SQLITE_QUERY_PARAM_TYPE_UNSET:
						break;
					case BP_DB_SQLITE_QUERY_PARAM_TYPE_NULL:
						sqlite3_bind_null(sqli->stmt, key_as_ul);
						break;
					case BP_DB_SQLITE_QUERY_PARAM_TYPE_INTEGER:
						memcpy(&parm_as_int, param->data, sizeof(parm_as_int));
						sqlite3_bind_int(sqli->stmt, key_as_ul, parm_as_int);
						break;
					case BP_DB_SQLITE_QUERY_PARAM_TYPE_REAL:
						memcpy(&parm_as_double, param->data, sizeof(parm_as_double));
						sqlite3_bind_double(sqli->stmt, key_as_ul, parm_as_double);
						break;
					case BP_DB_SQLITE_QUERY_PARAM_TYPE_TEXT:
						sqlite3_bind_text(sqli->stmt, key_as_ul,(char *) param->data, bpstrlen((char *) param->data), SQLITE_STATIC);
						break;
					case BP_DB_SQLITE_QUERY_PARAM_TYPE_BLOB:
						sqlite3_bind_blob(sqli->stmt, key_as_ul, param->data, param->data_size, SQLITE_STATIC);
						break;
					default:
						break;
				}
				param_n++;
			} while(1);
		}
		%%%%%%%%%%%%
		%%%%%%%%%%%%
		size_t result_idx = 0;
		while(BP_SQLiteFetchResult(sqli, entry->key, result_idx))
		{
			result_idx++;
		}
		char * query_results_iter_path[] =
		{
			"results",
			entry->key,
			(char *) &result_idx,
			NULL
		};
		P_BP_HASH_TABLE_KEYED_ENTRY last_query_result_lookup = BP_HashRegLookupTableByPath
		(
				sqli->query_result_cache,
				(char **) &query_results_iter_path
		);
		sqli->last_query_results = last_query_result_lookup;
		sqli->last_result_query_uuid = entry->key;
		sqli->last_result_retrieved_n = result_idx;
		sqli->last_transaction_record_count_retrieved += result_idx;
		sqlite3_finalize(sqli->stmt);
	}
	if(transaction_opened)
	{
		sqlite3_exec(sqli->db, "COMMIT", 0,0,0);
	}
	BP_HASH_TABLE_LEAVE_CRITICAL_SECTION(sqli->system_hreg);
	return ERR_SUCCESS;
}
BP_ERROR_T BP_SQLiteRunQueries ( P_BP_DB_SQLITE sqli ) { if ( ! sqli ) return ERR_FAILURE ; if ( ! sqli -> db ) return ERR_FAILURE ; if ( ! sqli -> queries ) return ERR_FAILURE ; sqli -> last_query_results = NULL ; sqli -> last_result_query_uuid = NULL ; sqli -> last_result_retrieved_n = 0 ; sqli -> last_transaction_record_count_retrieved = 0 ; BP_HASH_TABLE_ENTER_CRITICAL_SECTION ( sqli -> system_hreg ) ; char * query_table_path [ ] = { " " , NULL } ; P_BP_HASH_TABLE_KEYED_ENTRY query_table = BP_HashRegLookupTableByPath ( sqli -> queries , query_table_path ) ; if ( ! query_table ) { BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC ( sqli -> system_hreg , ERR_FAILURE ) ; } if ( ! query_table -> data ) { BP_HASH_TABLE_LEAVE_CRITICAL_SECTION_AND_RETURN_FROM_FUNC ( sqli -> system_hreg , ERR_FAILURE ) ; } P_BP_HASH_TABLE_KEYED_ENTRY entry = NULL ; P_BP_HASH_TABLE_KEYED_ENTRY tmp = NULL ; P_BP_HASH_TABLE_KEYED_ENTRY query_table_inner = ( P_BP_HASH_TABLE_KEYED_ENTRY ) query_table -> data ; BP_BOOL transaction_opened = BP_FALSE ; P_BP_HASH_TABLE_KEYED_ENTRY last_entry = NULL ; for ( last_entry = query_table_inner ; last_entry -> hh . next ; last_entry = ( P_BP_HASH_TABLE_KEYED_ENTRY ) last_entry -> hh . next ) { } HASH_ITER ( hh , query_table_inner , entry , tmp ) { if ( ! transaction_opened ) { sqlite3_exec ( sqli -> db , " " , 0 , 0 , 0 ) ; transaction_opened = BP_TRUE ; } if ( ! entry -> data ) continue ; P_BP_HASH_TABLE_KEYED_ENTRY sql_entry = BP_HashRegLookupEntryFromHashKeyViaRelativePosition ( sqli -> queries , ( P_BP_HASH_TABLE_KEYED_ENTRY ) entry , " " ) ; if ( ! sql_entry ) { continue ; } char * sql = ( char * ) sql_entry -> data ; int rc = sqlite3_prepare_v2 ( sqli -> db , sql , bpstrlen ( sql ) , & sqli -> stmt , NULL ) ; if ( rc != SQLITE_OK ) { printf ( " \n " , sql , sqlite3_errmsg ( sqli -> db ) ) ; continue ; } char * lookup_param_table_path [ ] = { " " , entry -> key , " " , NULL } ; P_BP_HASH_TABLE_KEYED_ENTRY parameters_table = BP_HashRegLookupTableByPath ( sqli -> queries , ( char * * ) & lookup_param_table_path ) ; if ( parameters_table ) if ( parameters_table -> data ) { size_t param_n = 0 ; char param_n_buff [ 128 ] ; do { BP_ZERO_STACK ( param_n_buff ) ; sprintf ( ( char * ) & param_n_buff , " " , param_n ) ; P_BP_HASH_TABLE_KEYED_ENTRY parm_entry = BP_HashRegLookupEntryFromHashKeyViaRelativePosition ( sqli -> queries , ( P_BP_HASH_TABLE_KEYED_ENTRY ) parameters_table , ( char * ) & param_n_buff ) ; if ( ! parm_entry ) break ; if ( ! parm_entry -> data ) break ; P_BP_SQLITE_QUERY_PARAM param = ( P_BP_SQLITE_QUERY_PARAM ) parm_entry -> data ; unsigned long key_as_ul = strtoul ( parm_entry -> key , NULL , 10 ) ; key_as_ul ++ ; int parm_as_int = 0 ; double parm_as_double = 0 ; switch ( param -> type ) { case BP_DB_SQLITE_QUERY_PARAM_TYPE_UNSET : break ; case BP_DB_SQLITE_QUERY_PARAM_TYPE_NULL : sqlite3_bind_null ( sqli -> stmt , key_as_ul ) ; break ; case BP_DB_SQLITE_QUERY_PARAM_TYPE_INTEGER : memcpy ( & parm_as_int , param -> data , sizeof ( parm_as_int ) ) ; sqlite3_bind_int ( sqli -> stmt , key_as_ul , parm_as_int ) ; break ; case BP_DB_SQLITE_QUERY_PARAM_TYPE_REAL : memcpy ( & parm_as_double , param -> data , sizeof ( parm_as_double ) ) ; sqlite3_bind_double ( sqli -> stmt , key_as_ul , parm_as_double ) ; break ; case BP_DB_SQLITE_QUERY_PARAM_TYPE_TEXT : sqlite3_bind_text ( sqli -> stmt , key_as_ul , ( char * ) param -> data , bpstrlen ( ( char * ) param -> data ) , SQLITE_STATIC ) ; break ; case BP_DB_SQLITE_QUERY_PARAM_TYPE_BLOB : sqlite3_bind_blob ( sqli -> stmt , key_as_ul , param -> data , param -> data_size , SQLITE_STATIC ) ; break ; default : break ; } param_n ++ ; } while ( 1 ) ; } size_t result_idx = 0 ; while ( BP_SQLiteFetchResult ( sqli , entry -> key , result_idx ) ) { result_idx ++ ; } char * query_results_iter_path [ ] = { " " , entry -> key , ( char * ) & result_idx , NULL } ; P_BP_HASH_TABLE_KEYED_ENTRY last_query_result_lookup = BP_HashRegLookupTableByPath ( sqli -> query_result_cache , ( char * * ) & query_results_iter_path ) ; sqli -> last_query_results = last_query_result_lookup ; sqli -> last_result_query_uuid = entry -> key ; sqli -> last_result_retrieved_n = result_idx ; sqli -> last_transaction_record_count_retrieved += result_idx ; sqlite3_finalize ( sqli -> stmt ) ; } if ( transaction_opened ) { sqlite3_exec ( sqli -> db , " " , 0 , 0 , 0 ) ; } BP_HASH_TABLE_LEAVE_CRITICAL_SECTION ( sqli -> system_hreg ) ; return ERR_SUCCESS ; }
Run all queries that are currently in the stack.
Run all queries that are currently in the stack .
// ensure we have a sqli pointer // ensure we have a database // ensure we have queries // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Reset Danglers %%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // set last query results if necessary // query uuid // total number of last results retrieved // set increase the record count // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Enter Critical Section and Add Param %%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // enter critical section // general steps: //    begin transaction; //    run queries; //    rollback if failed; //    exit transaction; // query table path // attempt to lookup // check to ensure we have query table // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Iterate Queries and Run %%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // temporary iterator values used during the HASH_ITER loop below // inner hash table // transaction open marker // calculate the last entry // query_table // for(entry = last_entry; entry; entry = (P_BP_HASH_TABLE_KEYED_ENTRY) entry->hh.prev) // printf("\n Got Key?: %s", entry->key); // if the transaction isn't opened, open it // open the transaction // ensure the transaction is opened // ensure we have data // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Lookup Sql Entry %%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // get sql from relative table // ensure we have sql // set sql from query entry data // prepare sql statement // printf("\n SQL Prepared OK!: %s", sql); // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Lookup Parameters Table %%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // set lookup path // get parameters table // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Iterate Parameters and Add %%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // add parameters if necessary // parameter position index // parmeter buffer (converts to char[]) // zero the parameter buffer // copy in numeric index // get sql from relative table // break loop if we can't look up parameter at index // printf("\n Got parameter?: %p - %s", parm_entry, parm_entry->key); // set parameter from data // get the key as an unsigned long (used in bind) // since we start at zero in the parameter stack, and since columns in // sqlite start at 1, we need to increment the key_as_ul variable here // before it gets into the switch. // space to hold parameter as integer // space to hold parameter as a double (float) // printf("\n Got parameter type?: %u", param->type); // bind parameter based on types // printf("\n Adding text parameter?: %u - %s", key_as_ul, (char *) param->data); // increment the position index // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Gather Query Results %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // step the statement // printf("\n Adding result"); // increment the index // set query results path // lookup table after entry and set last results // set last query results if necessary // query uuid // total number of last results retrieved // set increase the record count // finalize (write) // if the transaction was opened, close it here // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Leave Critical Section and Exit %%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // leave critical section // return indicating success