Skip to content

Commit 3f53c53

Browse files
committed
Updates to SQLiteCETest for new editor functionality
1 parent 2f7e3ad commit 3f53c53

1 file changed

Lines changed: 230 additions & 0 deletions

File tree

src/sqlite-ce-test/test_main.c

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,221 @@ static int test_join(void) {
606606
return ok;
607607
}
608608

609+
/*============================================================================
610+
** Test Cases - Export/Import (0.2.0)
611+
**============================================================================*/
612+
613+
static int test_sql_quote_escape(void) {
614+
int ok;
615+
char **result;
616+
int nRow, nCol;
617+
ExecOK("CREATE TABLE q(s TEXT)");
618+
ExecOK("INSERT INTO q VALUES('it''s a test')");
619+
ExecOK("INSERT INTO q VALUES('say \"hello\"')");
620+
ok = (CountRows("SELECT * FROM q") == 2);
621+
/* Verify content */
622+
if (sqlite_get_table(g_db, "SELECT s FROM q WHERE s LIKE '%it''s%'", &result, &nRow, &nCol, NULL) == SQLITE_OK) {
623+
ok = ok && (nRow == 1);
624+
sqlite_free_table(result);
625+
}
626+
ExecOK("DROP TABLE q");
627+
return ok;
628+
}
629+
630+
static int test_sqlite_master_tables(void) {
631+
int ok;
632+
ExecOK("CREATE TABLE sm_t1(a INTEGER)");
633+
ExecOK("CREATE TABLE sm_t2(b TEXT)");
634+
ExecOK("CREATE TABLE sm_t3(c REAL)");
635+
ok = (CountRows("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'sm_t%'") == 3);
636+
ExecOK("DROP TABLE sm_t1");
637+
ExecOK("DROP TABLE sm_t2");
638+
ExecOK("DROP TABLE sm_t3");
639+
return ok;
640+
}
641+
642+
static int test_sqlite_master_indexes(void) {
643+
int ok;
644+
char **result;
645+
int nRow, nCol;
646+
ExecOK("CREATE TABLE idx_t(a INTEGER, b TEXT)");
647+
ExecOK("CREATE INDEX idx_a ON idx_t(a)");
648+
ok = (CountRows("SELECT name FROM sqlite_master WHERE type='index' AND name='idx_a'") == 1);
649+
/* Verify SQL is stored */
650+
if (sqlite_get_table(g_db, "SELECT sql FROM sqlite_master WHERE name='idx_a'", &result, &nRow, &nCol, NULL) == SQLITE_OK) {
651+
ok = ok && (nRow == 1) && (result[1] != NULL);
652+
sqlite_free_table(result);
653+
}
654+
ExecOK("DROP TABLE idx_t");
655+
return ok;
656+
}
657+
658+
static int test_export_db_schema(void) {
659+
const char *srcPath = "\\Temp\\exp_src.db";
660+
const char *dstPath = "\\Temp\\exp_dst.db";
661+
sqlite *srcDb, *dstDb;
662+
char **result;
663+
int nRow, nCol, ok = 0;
664+
665+
DeleteFileW(L"\\Temp\\exp_src.db");
666+
DeleteFileW(L"\\Temp\\exp_dst.db");
667+
668+
/* Create source with schema */
669+
srcDb = sqlite_open(srcPath, 0, NULL);
670+
if (!srcDb) return 0;
671+
sqlite_exec(srcDb, "CREATE TABLE t1(id INTEGER PRIMARY KEY, name TEXT)", NULL, NULL, NULL);
672+
sqlite_exec(srcDb, "CREATE TABLE t2(x REAL, y REAL)", NULL, NULL, NULL);
673+
674+
/* "Export" by copying schema */
675+
dstDb = sqlite_open(dstPath, 0, NULL);
676+
if (!dstDb) { sqlite_close(srcDb); return 0; }
677+
678+
if (sqlite_get_table(srcDb, "SELECT sql FROM sqlite_master WHERE type='table'", &result, &nRow, &nCol, NULL) == SQLITE_OK) {
679+
int i;
680+
for (i = 1; i <= nRow; i++) {
681+
if (result[i]) sqlite_exec(dstDb, result[i], NULL, NULL, NULL);
682+
}
683+
sqlite_free_table(result);
684+
}
685+
sqlite_close(srcDb);
686+
sqlite_close(dstDb);
687+
688+
/* Verify destination has both tables */
689+
dstDb = sqlite_open(dstPath, 0, NULL);
690+
if (dstDb) {
691+
ok = (CountRows("SELECT name FROM sqlite_master WHERE type='table'") >= 2);
692+
/* Temporarily use dstDb for count */
693+
{
694+
sqlite *saved = g_db;
695+
g_db = dstDb;
696+
ok = (CountRows("SELECT name FROM sqlite_master WHERE type='table'") == 2);
697+
g_db = saved;
698+
}
699+
sqlite_close(dstDb);
700+
}
701+
702+
DeleteFileW(L"\\Temp\\exp_src.db");
703+
DeleteFileW(L"\\Temp\\exp_dst.db");
704+
return ok;
705+
}
706+
707+
static int test_export_db_data(void) {
708+
const char *srcPath = "\\Temp\\expd_src.db";
709+
const char *dstPath = "\\Temp\\expd_dst.db";
710+
sqlite *srcDb, *dstDb;
711+
char **result;
712+
int nRow, nCol, ok = 0;
713+
714+
DeleteFileW(L"\\Temp\\expd_src.db");
715+
DeleteFileW(L"\\Temp\\expd_dst.db");
716+
717+
/* Create source with data */
718+
srcDb = sqlite_open(srcPath, 0, NULL);
719+
if (!srcDb) return 0;
720+
sqlite_exec(srcDb, "CREATE TABLE t(id INTEGER, val TEXT)", NULL, NULL, NULL);
721+
sqlite_exec(srcDb, "INSERT INTO t VALUES(1, 'one')", NULL, NULL, NULL);
722+
sqlite_exec(srcDb, "INSERT INTO t VALUES(2, 'two')", NULL, NULL, NULL);
723+
sqlite_exec(srcDb, "INSERT INTO t VALUES(3, 'three')", NULL, NULL, NULL);
724+
725+
/* Export schema */
726+
dstDb = sqlite_open(dstPath, 0, NULL);
727+
if (!dstDb) { sqlite_close(srcDb); return 0; }
728+
sqlite_exec(dstDb, "CREATE TABLE t(id INTEGER, val TEXT)", NULL, NULL, NULL);
729+
730+
/* Export data */
731+
if (sqlite_get_table(srcDb, "SELECT * FROM t", &result, &nRow, &nCol, NULL) == SQLITE_OK) {
732+
int i, j;
733+
for (i = 1; i <= nRow; i++) {
734+
char sql[256];
735+
char *p = sql;
736+
char *s;
737+
for (s = "INSERT INTO t VALUES("; *s; ) *p++ = *s++;
738+
for (s = result[i * nCol]; *s; ) *p++ = *s++; /* id */
739+
*p++ = ','; *p++ = '\'';
740+
for (s = result[i * nCol + 1]; *s; ) *p++ = *s++; /* val */
741+
*p++ = '\''; *p++ = ')'; *p = '\0';
742+
sqlite_exec(dstDb, sql, NULL, NULL, NULL);
743+
}
744+
sqlite_free_table(result);
745+
}
746+
sqlite_close(srcDb);
747+
sqlite_close(dstDb);
748+
749+
/* Verify destination has 3 rows */
750+
dstDb = sqlite_open(dstPath, 0, NULL);
751+
if (dstDb) {
752+
sqlite *saved = g_db;
753+
g_db = dstDb;
754+
ok = (CountRows("SELECT * FROM t") == 3);
755+
ok = ok && (GetInt("SELECT id FROM t WHERE val='two'") == 2);
756+
g_db = saved;
757+
sqlite_close(dstDb);
758+
}
759+
760+
DeleteFileW(L"\\Temp\\expd_src.db");
761+
DeleteFileW(L"\\Temp\\expd_dst.db");
762+
return ok;
763+
}
764+
765+
static int test_invalid_sql(void) {
766+
int rc;
767+
char *errmsg = NULL;
768+
rc = sqlite_exec(g_db, "SELEKT * FORM nowhere", NULL, NULL, &errmsg);
769+
if (errmsg) sqlite_freemem(errmsg);
770+
return (rc != SQLITE_OK); /* Should fail */
771+
}
772+
773+
static int test_missing_table(void) {
774+
int rc;
775+
char *errmsg = NULL;
776+
rc = sqlite_exec(g_db, "SELECT * FROM nonexistent_table_xyz", NULL, NULL, &errmsg);
777+
if (errmsg) sqlite_freemem(errmsg);
778+
return (rc != SQLITE_OK); /* Should fail */
779+
}
780+
781+
static int test_constraint_violation(void) {
782+
int rc;
783+
char *errmsg = NULL;
784+
ExecOK("CREATE TABLE cv(id INTEGER PRIMARY KEY)");
785+
ExecOK("INSERT INTO cv VALUES(1)");
786+
rc = sqlite_exec(g_db, "INSERT INTO cv VALUES(1)", NULL, NULL, &errmsg); /* Duplicate */
787+
if (errmsg) sqlite_freemem(errmsg);
788+
ExecOK("DROP TABLE cv");
789+
return (rc != SQLITE_OK); /* Should fail */
790+
}
791+
792+
static int test_memory_isolation(void) {
793+
sqlite *db1, *db2;
794+
int ok = 0;
795+
796+
db1 = sqlite_open(":memory:", 0, NULL);
797+
db2 = sqlite_open(":memory:", 0, NULL);
798+
if (!db1 || !db2) {
799+
if (db1) sqlite_close(db1);
800+
if (db2) sqlite_close(db2);
801+
return 0;
802+
}
803+
804+
sqlite_exec(db1, "CREATE TABLE t(x INTEGER)", NULL, NULL, NULL);
805+
sqlite_exec(db1, "INSERT INTO t VALUES(42)", NULL, NULL, NULL);
806+
807+
/* db2 should NOT see db1's table */
808+
{
809+
char **result;
810+
int nRow, nCol;
811+
if (sqlite_get_table(db2, "SELECT * FROM t", &result, &nRow, &nCol, NULL) != SQLITE_OK) {
812+
ok = 1; /* Expected: table doesn't exist in db2 */
813+
} else {
814+
sqlite_free_table(result);
815+
ok = 0; /* Unexpected: table exists in db2 */
816+
}
817+
}
818+
819+
sqlite_close(db1);
820+
sqlite_close(db2);
821+
return ok;
822+
}
823+
609824
/*============================================================================
610825
** Test Registry
611826
**============================================================================*/
@@ -649,6 +864,21 @@ static TestCase g_tests[] = {
649864
{ "MIN/MAX aggregate", test_min_max },
650865
{ "JOIN", test_join },
651866

867+
/* Export/Import (0.2.0) */
868+
{ "SQL quote escaping", test_sql_quote_escape },
869+
{ "sqlite_master tables", test_sqlite_master_tables },
870+
{ "sqlite_master indexes", test_sqlite_master_indexes },
871+
{ "Export DB schema", test_export_db_schema },
872+
{ "Export DB data", test_export_db_data },
873+
874+
/* Error handling */
875+
{ "Invalid SQL error", test_invalid_sql },
876+
{ "Missing table error", test_missing_table },
877+
{ "Constraint violation", test_constraint_violation },
878+
879+
/* Memory databases */
880+
{ "Memory DB isolation", test_memory_isolation },
881+
652882
{ NULL, NULL }
653883
};
654884

0 commit comments

Comments
 (0)