Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions cpp/DBHostObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ void DBHostObject::create_jsi_functions() {
});

function_map["close"] = HOSTFN("close") {
invalidated = true;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessarily a problem, but I discovered during hot reloads if the DB was already closed it would try to be invalidated again and sqlite does not like it.


#ifdef OP_SQLITE_USE_LIBSQL
opsqlite_libsql_close(db);
#else
Expand All @@ -248,6 +250,8 @@ void DBHostObject::create_jsi_functions() {
});

function_map["delete"] = HOSTFN("delete") {
invalidated = true;

std::string path = std::string(base_path);

if (count == 1) {
Expand Down Expand Up @@ -808,6 +812,10 @@ void DBHostObject::set(jsi::Runtime &_rt, const jsi::PropNameID &name,
}

void DBHostObject::invalidate() {
if(invalidated) {
return;
}

invalidated = true;
_thread_pool->restartPool();
#ifdef OP_SQLITE_USE_LIBSQL
Expand Down
63 changes: 48 additions & 15 deletions example/src/tests/dbsetup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,26 @@ export function dbSetupTests() {
'CREATE TABLE User ( id INT PRIMARY KEY, name TEXT NOT NULL, age INT, networth REAL) STRICT;',
);

await androidDb.close();
androidDb.close();
});

it('Creates db in external nested directory on Android', async () => {
let androidDb = open({
name: 'AndroidSDCardDB.sqlite',
location: `${ANDROID_EXTERNAL_FILES_PATH}/nested`,
encryptionKey: 'test',
});

await androidDb.execute('DROP TABLE IF EXISTS User;');
await androidDb.execute(
'CREATE TABLE User ( id INT PRIMARY KEY, name TEXT NOT NULL, age INT, networth REAL) STRICT;',
);

androidDb.close();
});
}

// Currently this only tests the function is there
it('Should load extension', async () => {
let db = open({
name: 'extensionDb',
Expand All @@ -112,13 +128,16 @@ export function dbSetupTests() {
});

it('Should delete db with absolute path', async () => {
let location =
Platform.OS === 'ios' ? IOS_LIBRARY_PATH : ANDROID_DATABASE_PATH;
let db = open({
name: 'deleteTest',
encryptionKey: 'test',
location:
Platform.OS === 'ios' ? IOS_LIBRARY_PATH : ANDROID_DATABASE_PATH,
location,
});

expect(db.getDbPath()).to.contain(location);

db.delete();
});

Expand All @@ -129,6 +148,20 @@ export function dbSetupTests() {
location: 'myFolder',
});

let path = db.getDbPath();
expect(path).to.contain('myFolder');
db.delete();
});

it('Should create nested folders', async () => {
let db = open({
name: 'nestedFolderTest.sqlite',
encryptionKey: 'test',
location: 'myFolder/nested',
});

let path = db.getDbPath();
expect(path).to.contain('myFolder/nested');
db.delete();
});

Expand All @@ -155,18 +188,17 @@ export function dbSetupTests() {
});

expect(copied).to.equal(true);
});

// it('Should fail creating in-memory with non-bool arg', async () => {
// try {
// open({
// name: 'inMemoryTest',
// });
// expect.fail('Should throw');
// } catch (e) {
// expect(!!e).to.equal(true);
// }
// });
let db = open({
name: 'sample2.sqlite',
encryptionKey: 'test',
location: 'sqlite',
});

let path = db.getDbPath();
expect(path).to.contain('sqlite/sample2.sqlite');
db.delete();
});

it('Creates new connections per query and closes them', async () => {
for (let i = 0; i < 100; i++) {
Expand Down Expand Up @@ -235,10 +267,11 @@ export function dbSetupTests() {
});

if (isSQLCipher()) {
it('Can open without encryption key', () => {
it('Can open SQLCipher db without encryption key', () => {
let db = open({
name: 'pathTest.sqlite',
});

db.close();
});
}
Expand Down
33 changes: 26 additions & 7 deletions example/src/tests/queries.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,6 @@ export function queriesTests() {

const countRes = await db.execute('SELECT COUNT(*) as count FROM User');

// console.log(countRes);

// expect(countRes.metadata?.[0]?.type).to.equal('UNKNOWN');
expect(countRes.rows?.length).to.equal(1);
expect(countRes.rows?.[0]?.count).to.equal(1);

Expand All @@ -257,18 +254,14 @@ export function queriesTests() {

const sumRes = await db.execute('SELECT SUM(age) as sum FROM User;');

// expect(sumRes.metadata?.[0]?.type).to.equal('UNKNOWN');
expect(sumRes.rows[0]!.sum).to.equal(age + age2);

// MAX(networth), MIN(networth)
const maxRes = await db.execute(
'SELECT MAX(networth) as `max` FROM User;',
);
const minRes = await db.execute(
'SELECT MIN(networth) as `min` FROM User;',
);
// expect(maxRes.metadata?.[0]?.type).to.equal('UNKNOWN');
// expect(minRes.metadata?.[0]?.type).to.equal('UNKNOWN');
const maxNetworth = Math.max(networth, networth2);
const minNetworth = Math.min(networth, networth2);

Expand Down Expand Up @@ -707,6 +700,32 @@ export function queriesTests() {
await db.execute('SELECT ?; ', [1]);
});

it('Handles concurrent transactions correctly', async () => {
const id = chance.integer();
const name = chance.name();
const age = chance.integer();
const networth = chance.floating();

const transaction1 = db.transaction(async tx => {
await tx.execute(
'INSERT INTO "User" (id, name, age, networth) VALUES(?, ?, ?, ?)',
[id, name, age, networth],
);
});

const transaction2 = db.transaction(async tx => {
await tx.execute(
'INSERT INTO "User" (id, name, age, networth) VALUES(?, ?, ?, ?)',
[id + 1, name, age, networth],
);
});

await Promise.all([transaction1, transaction2]);

const res = await db.execute('SELECT * FROM User');
expect(res.rows.length).to.equal(2);
});

it('Pragma user_version', () => {
const res = db.executeSync('PRAGMA user_version');
console.warn(res.rows);
Expand Down
Loading