Skip to content

Commit

Permalink
removed lodash and uuid from requirements
Browse files Browse the repository at this point in the history
  • Loading branch information
stevensJourney committed May 9, 2024
1 parent 153b817 commit 450a0b2
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 114 deletions.
5 changes: 5 additions & 0 deletions .changeset/moody-terms-grin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@journeyapps/react-native-quick-sqlite': patch
---

Removed the requirement for `lodash` and `uuid` packages.
7 changes: 1 addition & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@
"homepage": "https://github.com/margelo/react-native-quick-sqlite#readme",
"devDependencies": {
"@changesets/cli": "^2.26.2",
"@types/lodash": "^4.14.200",
"@types/uuid": "^9.0.1",
"react": "18.2.0",
"react-native": "0.71.0",
"react-native-builder-bob": "^0.18.2",
Expand Down Expand Up @@ -80,8 +78,5 @@
]
]
},
"dependencies": {
"lodash": "^4.17.21",
"uuid": "^9.0.1"
}
"dependencies": {}
}
24 changes: 17 additions & 7 deletions src/DBListenerManager.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import _ from 'lodash';
import { registerTransactionHook, registerUpdateHook } from './table-updates';
import {
BatchedUpdateCallback,
BatchedUpdateNotification,
TransactionEvent,
UpdateCallback,
UpdateNotification
UpdateNotification,
} from './types';
import { BaseListener, BaseObserver } from './utils/BaseObserver';

Expand Down Expand Up @@ -50,21 +49,23 @@ export class DBListenerManagerInternal extends DBListenerManager {
constructor(protected options: DBListenerManagerOptions) {
super();
this.updateBuffer = [];
registerUpdateHook(this.options.dbName, (update) => this.handleTableUpdates(update));
registerUpdateHook(this.options.dbName, (update) =>
this.handleTableUpdates(update)
);
registerTransactionHook(this.options.dbName, (eventType) => {
switch (eventType) {
/**
* COMMIT hooks occur before the commit is completed. This leads to race conditions.
* Only use the rollback event to clear updates.
*/
*/
case TransactionEvent.ROLLBACK:
this.transactionReverted();
break;
}

this.iterateListeners((l) =>
l.writeTransaction?.({
type: eventType
type: eventType,
})
);
});
Expand All @@ -75,11 +76,20 @@ export class DBListenerManagerInternal extends DBListenerManager {
return;
}

const groupedUpdates = _.groupBy(this.updateBuffer, (update) => update.table);
const groupedUpdates = this.updateBuffer.reduce(
(grouping: Record<string, UpdateNotification[]>, update) => {
const { table } = update;
const updateGroup = grouping[table] || (grouping[table] = []);
updateGroup.push(update);
return grouping;
},
{}
);

const batchedUpdate: BatchedUpdateNotification = {
groupedUpdates,
rawUpdates: this.updateBuffer,
tables: _.keys(groupedUpdates)
tables: Object.keys(groupedUpdates),
};
this.updateBuffer = [];
this.iterateListeners((l) => l.tablesUpdated?.(batchedUpdate));
Expand Down
113 changes: 81 additions & 32 deletions src/setup-open.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ import {
UpdateCallback,
SQLBatchTuple,
OpenOptions,
QueryResult
QueryResult,
} from './types';

import { v4 } from 'uuid';
import _ from 'lodash';
import { enhanceQueryResult } from './utils';
import { DBListenerManagerInternal } from './DBListenerManager';
import { LockHooks } from './lock-hooks';
Expand All @@ -25,7 +23,7 @@ type LockCallbackRecord = {

enum TransactionFinalizer {
COMMIT = 'commit',
ROLLBACK = 'rollback'
ROLLBACK = 'rollback',
}

const DEFAULT_READ_CONNECTIONS = 4;
Expand All @@ -49,7 +47,10 @@ function closeContextLock(dbName: string, id: ContextLockID) {
* @param lockId
* @returns
*/
global.onLockContextIsAvailable = async (dbName: string, lockId: ContextLockID) => {
global.onLockContextIsAvailable = async (
dbName: string,
lockId: ContextLockID
) => {
// Don't hold C++ bridge side up waiting to complete
setImmediate(async () => {
try {
Expand All @@ -61,10 +62,15 @@ global.onLockContextIsAvailable = async (dbName: string, lockId: ContextLockID)
// @ts-expect-error This is not part of the public interface, but is used internally
_contextId: lockId,
execute: async (sql: string, args?: any[]) => {
const result = await proxy.executeInContext(dbName, lockId, sql, args);
const result = await proxy.executeInContext(
dbName,
lockId,
sql,
args
);
enhanceQueryResult(result);
return result;
}
},
});
} catch (ex) {
console.error(ex);
Expand All @@ -87,15 +93,28 @@ export function setupOpen(QuickSQLite: ISQLite) {
* By default opens DB in WAL mode with 4 Read connections and a single
* write connection
*/
open: (dbName: string, options: OpenOptions = {}): QuickSQLiteConnection => {
open: (
dbName: string,
options: OpenOptions = {}
): QuickSQLiteConnection => {
// Opens the connection
QuickSQLite.open(dbName, {
...options,
numReadConnections: options?.numReadConnections ?? DEFAULT_READ_CONNECTIONS
numReadConnections:
options?.numReadConnections ?? DEFAULT_READ_CONNECTIONS,
});

const listenerManager = new DBListenerManagerInternal({ dbName });

// A incrementing integer ID for tracking lock requests
let requestIdCounter = 1;
const getRequestId = () => {
requestIdCounter++;
if (requestIdCounter >= Number.MAX_SAFE_INTEGER) {
requestIdCounter = 0;
}
return `${requestIdCounter}`;
};
/**
* Wraps lock requests and their callbacks in order to resolve the lock
* request with the callback result once triggered from the connection pool.
Expand All @@ -106,7 +125,7 @@ export function setupOpen(QuickSQLite: ISQLite) {
options?: LockOptions,
hooks?: LockHooks
): Promise<T> => {
const id = v4(); // TODO maybe do this in C++
const id = getRequestId();
// Wrap the callback in a promise that will resolve to the callback result
return new Promise<T>((resolve, reject) => {
// Add callback to the queue for timing
Expand All @@ -117,14 +136,14 @@ export function setupOpen(QuickSQLite: ISQLite) {
const res = await callback(context);

closeContextLock(dbName, id);
resolve(res)
resolve(res);
} catch (ex) {
closeContextLock(dbName, id);
reject(ex)
reject(ex);
} finally {
hooks?.lockReleased?.()
hooks?.lockReleased?.();
}
}
},
} as LockCallbackRecord);

try {
Expand All @@ -145,15 +164,20 @@ export function setupOpen(QuickSQLite: ISQLite) {
});
};

const readLock = <T>(callback: (context: LockContext) => Promise<T>, options?: LockOptions): Promise<T> =>
requestLock(ConcurrentLockType.READ, callback, options);
const readLock = <T>(
callback: (context: LockContext) => Promise<T>,
options?: LockOptions
): Promise<T> => requestLock(ConcurrentLockType.READ, callback, options);

const writeLock = <T>(callback: (context: LockContext) => Promise<T>, options?: LockOptions): Promise<T> =>
const writeLock = <T>(
callback: (context: LockContext) => Promise<T>,
options?: LockOptions
): Promise<T> =>
requestLock(ConcurrentLockType.WRITE, callback, options, {
lockReleased: async () => {
// flush updates once a write lock has been released
listenerManager.flushUpdates();
}
},
});

const wrapTransaction = async <T>(
Expand All @@ -174,17 +198,23 @@ export function setupOpen(QuickSQLite: ISQLite) {
return action();
};

const commit = finalizedStatement(async () => context.execute('COMMIT'));
const commit = finalizedStatement(async () =>
context.execute('COMMIT')
);

const rollback = finalizedStatement(async () => context.execute('ROLLBACK'));
const rollback = finalizedStatement(async () =>
context.execute('ROLLBACK')
);

const wrapExecute =
<T>(
method: (sql: string, params?: any[]) => Promise<QueryResult>
): ((sql: string, params?: any[]) => Promise<QueryResult>) =>
async (sql: string, params?: any[]) => {
if (finalized) {
throw new Error(`Cannot execute in transaction after it has been finalized with commit/rollback.`);
throw new Error(
`Cannot execute in transaction after it has been finalized with commit/rollback.`
);
}
return method(sql, params);
};
Expand All @@ -194,7 +224,7 @@ export function setupOpen(QuickSQLite: ISQLite) {
...context,
commit,
rollback,
execute: wrapExecute(context.execute)
execute: wrapExecute(context.execute),
});
switch (defaultFinalizer) {
case TransactionFinalizer.COMMIT:
Expand All @@ -214,26 +244,45 @@ export function setupOpen(QuickSQLite: ISQLite) {
// Return the concurrent connection object
return {
close: () => QuickSQLite.close(dbName),
execute: (sql: string, args?: any[]) => writeLock((context) => context.execute(sql, args)),
execute: (sql: string, args?: any[]) =>
writeLock((context) => context.execute(sql, args)),
readLock,
readTransaction: async <T>(callback: (context: TransactionContext) => Promise<T>, options?: LockOptions) =>
readLock((context) => wrapTransaction(context, callback)),
readTransaction: async <T>(
callback: (context: TransactionContext) => Promise<T>,
options?: LockOptions
) => readLock((context) => wrapTransaction(context, callback)),
writeLock,
writeTransaction: async <T>(callback: (context: TransactionContext) => Promise<T>, options?: LockOptions) =>
writeLock((context) => wrapTransaction(context, callback, TransactionFinalizer.COMMIT), options),
writeTransaction: async <T>(
callback: (context: TransactionContext) => Promise<T>,
options?: LockOptions
) =>
writeLock(
(context) =>
wrapTransaction(context, callback, TransactionFinalizer.COMMIT),
options
),
delete: () => QuickSQLite.delete(dbName, options?.location),
executeBatch: (commands: SQLBatchTuple[]) =>
writeLock((context) => QuickSQLite.executeBatch(dbName, commands, (context as any)._contextId)),
writeLock((context) =>
QuickSQLite.executeBatch(
dbName,
commands,
(context as any)._contextId
)
),
attach: (dbNameToAttach: string, alias: string, location?: string) =>
QuickSQLite.attach(dbName, dbNameToAttach, alias, location),
detach: (alias: string) => QuickSQLite.detach(dbName, alias),
loadFile: (location: string) =>
writeLock((context) => QuickSQLite.loadFile(dbName, location, (context as any)._contextId)),
writeLock((context) =>
QuickSQLite.loadFile(dbName, location, (context as any)._contextId)
),
listenerManager,
registerUpdateHook: (callback: UpdateCallback) =>
listenerManager.registerListener({ rawTableChange: callback }),
registerTablesChangedHook: (callback) => listenerManager.registerListener({ tablesUpdated: callback })
registerTablesChangedHook: (callback) =>
listenerManager.registerListener({ tablesUpdated: callback }),
};
}
},
};
}
}
16 changes: 11 additions & 5 deletions src/type-orm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
// | | | | | | | |___| |__| | | \ \| | | | / ____ \| | _| |_
// |_| |_| |_| |______\____/|_| \_\_| |_| /_/ \_\_| |_____|

import _ from 'lodash';
import { QueryResult, TransactionContext, Open } from './types';

/**
Expand Down Expand Up @@ -38,7 +37,9 @@ export const setupTypeORMDriver = (open: Open) => ({
fail(e);
}
},
transaction: (fn: (tx: TransactionContext) => Promise<void>): Promise<void> => {
transaction: (
fn: (tx: TransactionContext) => Promise<void>
): Promise<void> => {
return _con.writeTransaction(fn);
},
close: (ok: any, fail: any) => {
Expand All @@ -49,14 +50,19 @@ export const setupTypeORMDriver = (open: Open) => ({
fail(e);
}
},
attach: (dbNameToAttach: string, alias: string, location: string | undefined, callback: () => void) => {
attach: (
dbNameToAttach: string,
alias: string,
location: string | undefined,
callback: () => void
) => {
_con.attach(dbNameToAttach, alias, location);
callback();
},
detach: (alias, callback: () => void) => {
_con.detach(alias);
callback();
}
},
};

ok(connection);
Expand All @@ -65,5 +71,5 @@ export const setupTypeORMDriver = (open: Open) => ({
} catch (e) {
fail(e);
}
}
},
});
Loading

0 comments on commit 450a0b2

Please sign in to comment.