#include #include #include #include #include #include #include void test_sqlite3_changes(); void test_sqlite3_bind_int64(); void test_sqlite3_bind_double(); void test_sqlite3_bind_parameter_name(); void test_sqlite3_bind_parameter_count(); void test_sqlite3_column_name(); void test_sqlite3_last_insert_rowid(); int main(void) { test_sqlite3_changes(); test_sqlite3_bind_int64(); test_sqlite3_bind_double(); test_sqlite3_bind_parameter_name(); test_sqlite3_bind_parameter_count(); test_sqlite3_column_name(); test_sqlite3_last_insert_rowid(); return 0; } void test_sqlite3_changes() { sqlite3 *db; char *err_msg = NULL; int rc; rc = sqlite3_open("../../testing/testing.db", &db); assert(rc == SQLITE_OK); rc = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS turso_test_changes (id INTEGER PRIMARY KEY, name TEXT);", NULL, NULL, &err_msg); assert(rc == SQLITE_OK); if (err_msg) { sqlite3_free(err_msg); err_msg = NULL; } rc = sqlite3_exec(db, "DELETE FROM turso_test_changes;", NULL, NULL, &err_msg); assert(rc == SQLITE_OK); if (err_msg) { sqlite3_free(err_msg); err_msg = NULL; } sqlite3_close(db); rc = sqlite3_open("../../testing/testing.db", &db); assert(rc == SQLITE_OK); assert(sqlite3_changes(db) == 0); rc = sqlite3_exec(db, "INSERT INTO turso_test_changes (name) VALUES ('abc');", NULL, NULL, &err_msg); assert(rc == SQLITE_OK); if (err_msg) { sqlite3_free(err_msg); err_msg = NULL; } assert(sqlite3_changes(db) == 1); rc = sqlite3_exec(db, "INSERT INTO turso_test_changes (name) VALUES ('def'),('ghi'),('jkl');", NULL, NULL, &err_msg); assert(rc == SQLITE_OK); if (err_msg) { sqlite3_free(err_msg); err_msg = NULL; } assert(sqlite3_changes(db) == 3); sqlite3_close(db); } void test_sqlite3_bind_int64() { sqlite3 *db; sqlite3_stmt *stmt; char *err_msg = NULL; int rc; rc = sqlite3_open("../../testing/testing.db", &db); assert(rc == SQLITE_OK); rc = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS turso_test_int64 (id INTEGER PRIMARY KEY, value INTEGER);", NULL, NULL, &err_msg); assert(rc == SQLITE_OK); if (err_msg) { sqlite3_free(err_msg); err_msg = NULL; } rc = sqlite3_exec(db, "DELETE FROM turso_test_int64;", NULL, NULL, &err_msg); assert(rc == SQLITE_OK); if (err_msg) { sqlite3_free(err_msg); err_msg = NULL; } rc = sqlite3_prepare_v2(db, "INSERT INTO turso_test_int64 (value) VALUES (?);", -1, &stmt, NULL); assert(rc == SQLITE_OK); sqlite_int64 big_value = (sqlite_int64)9223372036854775807LL; rc = sqlite3_bind_int64(stmt, 1, big_value); assert(rc == SQLITE_OK); rc = sqlite3_step(stmt); assert(rc == SQLITE_DONE); rc = sqlite3_finalize(stmt); assert(rc == SQLITE_OK); rc = sqlite3_prepare_v2(db, "SELECT value FROM turso_test_int64 LIMIT 1;", -1, &stmt, NULL); assert(rc == SQLITE_OK); rc = sqlite3_step(stmt); assert(rc == SQLITE_ROW); sqlite_int64 fetched = sqlite3_column_int64(stmt, 0); assert(fetched == big_value); printf("Inserted value: %lld, Fetched value: %lld\n", (long long)big_value, (long long)fetched); sqlite3_finalize(stmt); sqlite3_close(db); } void test_sqlite3_bind_double() { sqlite3 *db; sqlite3_stmt *stmt; char *err_msg = NULL; int rc; rc = sqlite3_open("../../testing/testing.db", &db); assert(rc == SQLITE_OK); rc = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS turso_test_double (id INTEGER PRIMARY KEY, value REAL);", NULL, NULL, &err_msg); assert(rc == SQLITE_OK); if (err_msg) { sqlite3_free(err_msg); err_msg = NULL; } rc = sqlite3_exec(db, "DELETE FROM turso_test_double;", NULL, NULL, &err_msg); assert(rc == SQLITE_OK); if (err_msg) { sqlite3_free(err_msg); err_msg = NULL; } rc = sqlite3_prepare_v2(db, "INSERT INTO turso_test_double (value) VALUES (?);", -1, &stmt, NULL); assert(rc == SQLITE_OK); double big_value = 1234567890.123456; rc = sqlite3_bind_double(stmt, 1, big_value); assert(rc == SQLITE_OK); rc = sqlite3_step(stmt); assert(rc == SQLITE_DONE); rc = sqlite3_finalize(stmt); assert(rc == SQLITE_OK); rc = sqlite3_prepare_v2(db, "SELECT value FROM turso_test_double LIMIT 1;", -1, &stmt, NULL); assert(rc == SQLITE_OK); rc = sqlite3_step(stmt); assert(rc == SQLITE_ROW); double fetched = sqlite3_column_double(stmt, 0); assert(fabs(fetched - big_value) < 1e-9); printf("Inserted value: %.15f, Fetched value: %.15f\n", big_value, fetched); sqlite3_finalize(stmt); sqlite3_close(db); } void test_sqlite3_bind_parameter_name() { sqlite3 *db; sqlite3_stmt *stmt; int rc; rc = sqlite3_open(":memory:", &db); assert(rc == SQLITE_OK); const char *sql = "INSERT INTO test_parameter_name (value) VALUES (:val);"; rc = sqlite3_exec(db, "CREATE TABLE test_parameter_name (id INTEGER PRIMARY KEY, value INTEGER);", NULL, NULL, NULL); assert(rc == SQLITE_OK); rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); assert(rc == SQLITE_OK); const char *param_name = sqlite3_bind_parameter_name(stmt, 1); assert(param_name != NULL); printf("Parameter name: %s\n", param_name); assert(strcmp(param_name, ":val") == 0); const char *invalid_name = sqlite3_bind_parameter_name(stmt, 99); assert(invalid_name == NULL); sqlite3_finalize(stmt); sqlite3_close(db); } void test_sqlite3_bind_parameter_count() { sqlite3 *db; sqlite3_stmt *stmt; int rc; rc = sqlite3_open(":memory:", &db); assert(rc == SQLITE_OK); rc = sqlite3_exec(db, "CREATE TABLE test_parameter_count (id INTEGER PRIMARY KEY, value TEXT);", NULL, NULL, NULL); assert(rc == SQLITE_OK); const char *sql = "INSERT INTO test_parameter_count (id, value) VALUES (?1, ?2);"; rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); assert(rc == SQLITE_OK); int param_count = sqlite3_bind_parameter_count(stmt); printf("Parameter count: %d\n", param_count); assert(param_count == 2); sqlite3_finalize(stmt); rc = sqlite3_prepare_v2(db, "SELECT * FROM test_parameter_count;", -1, &stmt, NULL); assert(rc == SQLITE_OK); param_count = sqlite3_bind_parameter_count(stmt); printf("Parameter count (no params): %d\n", param_count); assert(param_count == 0); sqlite3_finalize(stmt); sqlite3_close(db); } void test_sqlite3_column_name() { sqlite3 *db; sqlite3_stmt *stmt; int rc; rc = sqlite3_open(":memory:", &db); assert(rc == SQLITE_OK); rc = sqlite3_exec(db, "CREATE TABLE test_column_name (id INTEGER PRIMARY KEY, name TEXT, age INTEGER);", NULL, NULL, NULL); assert(rc == SQLITE_OK); const char *sql = "SELECT id, name AS full_name, age FROM test_column_name;"; rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); assert(rc == SQLITE_OK); int col_count = sqlite3_column_count(stmt); assert(col_count == 3); const char *col0 = sqlite3_column_name(stmt, 0); const char *col1 = sqlite3_column_name(stmt, 1); const char *col2 = sqlite3_column_name(stmt, 2); printf("Column 0 name: %s\n", col0); printf("Column 1 name: %s\n", col1); printf("Column 2 name: %s\n", col2); assert(strcmp(col0, "id") == 0); assert(strcmp(col1, "full_name") == 0); assert(strcmp(col2, "age") == 0); const char *invalid_col = sqlite3_column_name(stmt, 99); assert(invalid_col == NULL); sqlite3_finalize(stmt); sqlite3_close(db); } void test_sqlite3_last_insert_rowid() { sqlite3 *db; sqlite3_stmt *stmt; int rc; rc = sqlite3_open(":memory:", &db); assert(rc == SQLITE_OK); rc = sqlite3_exec(db, "CREATE TABLE test_last_insert (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT);", NULL, NULL, NULL); assert(rc == SQLITE_OK); rc = sqlite3_prepare_v2(db, "INSERT INTO test_last_insert (name) VALUES ('first');", -1, &stmt, NULL); assert(rc == SQLITE_OK); rc = sqlite3_step(stmt); assert(rc == SQLITE_DONE); sqlite3_finalize(stmt); sqlite3_int64 rowid1 = sqlite3_last_insert_rowid(db); printf("first: %lld\n", (long long)rowid1); assert(rowid1 == 1); rc = sqlite3_prepare_v2(db, "INSERT INTO test_last_insert (name) VALUES ('second');", -1, &stmt, NULL); assert(rc == SQLITE_OK); rc = sqlite3_step(stmt); assert(rc == SQLITE_DONE); sqlite3_finalize(stmt); sqlite3_int64 rowid2 = sqlite3_last_insert_rowid(db); printf("second: %lld\n", (long long)rowid2); assert(rowid2 == 2); sqlite3_close(db); }