#include "../src/sqliteInt.h" #include "time.h" #define eprintf(...) fprintf(stderr, __VA_ARGS__) #define ensure(condition, ...) { if (!(condition)) { eprintf(__VA_ARGS__); exit(1); } } int main(int argc, char* argv[]) { ensure(argc == 6, "provide path to the db file, blob open flags(read|write), blob open strategy(simple|reopen), amount of rows, size of the blob\n"); sqlite3* db; int rc = sqlite3_open(argv[1], &db); ensure(rc == 0, "failed to open db: rc=%d\n", rc); printf("open sqlite db at '%s'\n", argv[1]); int openFlags = argv[2][0] == 'w'; int openStrategy = argv[3][0] == 'r'; int nRows = atoi(argv[4]); int nBlobSize = atoi(argv[5]); printf("blob table: ready to prepare\n"); ensure(sqlite3_exec(db, "CREATE TABLE x ( id INTEGER PRIMARY KEY, blob BLOB )", 0, 0, NULL) == SQLITE_OK, "unable to create table: %s\n", sqlite3_errmsg(db)); sqlite3_stmt *pStmt; ensure(sqlite3_prepare(db, "INSERT INTO x VALUES (?, ?)", -1, &pStmt, NULL) == SQLITE_OK, "unable to prepare statement: %s\n", sqlite3_errmsg(db)); char *pTrash = malloc(nBlobSize); for(int i = 0; i < nRows; i++){ ensure(sqlite3_reset(pStmt) == SQLITE_OK, "unable to reset statement: %s\n", sqlite3_errmsg(db)); ensure(sqlite3_bind_int(pStmt, 1, i) == SQLITE_OK, "unable to bind int: %s\n", sqlite3_errmsg(db)); ensure(sqlite3_bind_blob(pStmt, 2, pTrash, nBlobSize, 0) == SQLITE_OK, "unable to bind blob: %s\n", sqlite3_errmsg(db)); ensure(sqlite3_step(pStmt) == SQLITE_DONE, "unexpected result of step: %s\n", sqlite3_errmsg(db)); } sqlite3_finalize(pStmt); printf("blob table: prepared\n"); time_t start_time = clock(); int total = 0; sqlite3_blob *pBlob; if( openStrategy == 1 ){ ensure(sqlite3_blob_open(db, db->aDb[0].zDbSName, "x", "blob", 0, openFlags, &pBlob) == SQLITE_OK, "unable to open blob: %s\n", sqlite3_errmsg(db)); } for(int i = 0; i < nRows; i++){ int rowid = rand() % nRows; total++; if( openStrategy == 1 ){ ensure(sqlite3_blob_reopen(pBlob, rowid) == SQLITE_OK, "unable to reopen blob: %s\n", sqlite3_errmsg(db)); }else{ ensure(sqlite3_blob_open(db, db->aDb[0].zDbSName, "x", "blob", rowid, openFlags, &pBlob) == SQLITE_OK, "unable to reopen blob: %s\n", sqlite3_errmsg(db)); } ensure(sqlite3_blob_read(pBlob, pTrash, nBlobSize, 0) == SQLITE_OK, "unable to read blob: %s\n", sqlite3_errmsg(db)); if( openStrategy == 0 ){ ensure(sqlite3_blob_close(pBlob) == SQLITE_OK, "unable to close blob: %s\n", sqlite3_errmsg(db)); } } if( openStrategy == 1 ){ ensure(sqlite3_blob_close(pBlob) == SQLITE_OK, "unable to close blob: %s\n", sqlite3_errmsg(db)); } double total_time = (clock() - start_time) * 1.0 / CLOCKS_PER_SEC; printf("time: %.2f micros (avg.), %d (count)\n", total_time / total * 1000000, total); free(pTrash); sqlite3_close(db); return 0; }