@kubun/db-expo 0.3.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/driver.d.ts +1 -2
- package/lib/driver.js +1 -138
- package/lib/index.d.ts +7 -3
- package/lib/index.js +1 -12
- package/lib/serialize.d.ts +0 -1
- package/lib/serialize.js +1 -27
- package/package.json +5 -5
- package/lib/driver.d.ts.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/serialize.d.ts.map +0 -1
package/lib/driver.d.ts
CHANGED
|
@@ -48,7 +48,6 @@ declare class ExpoConnection implements DatabaseConnection {
|
|
|
48
48
|
closeConnection(): Promise<void>;
|
|
49
49
|
executeQuery<R>(compiledQuery: CompiledQuery): Promise<QueryResult<R>>;
|
|
50
50
|
directQuery<T>(query: string): Promise<Array<T>>;
|
|
51
|
-
streamQuery<R>(
|
|
51
|
+
streamQuery<R>(_compiledQuery: CompiledQuery, _chunkSize?: number): AsyncIterableIterator<QueryResult<R>>;
|
|
52
52
|
}
|
|
53
53
|
export {};
|
|
54
|
-
//# sourceMappingURL=driver.d.ts.map
|
package/lib/driver.js
CHANGED
|
@@ -1,138 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
// Adapted from https://github.com/mphill/kysely-expo/blob/main/src/driver.ts
|
|
3
|
-
import { SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler } from 'kysely';
|
|
4
|
-
import { serialize } from './serialize.js';
|
|
5
|
-
/**
|
|
6
|
-
* Expo dialect for Kysely.
|
|
7
|
-
*/ export class ExpoDialect {
|
|
8
|
-
config;
|
|
9
|
-
constructor(config){
|
|
10
|
-
this.config = {
|
|
11
|
-
...config,
|
|
12
|
-
disableStrictModeCreateTable: true
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
createDriver() {
|
|
16
|
-
return new ExpoDriver(this.config);
|
|
17
|
-
}
|
|
18
|
-
createQueryCompiler() {
|
|
19
|
-
return new SqliteQueryCompiler();
|
|
20
|
-
}
|
|
21
|
-
createAdapter() {
|
|
22
|
-
return new SqliteAdapter();
|
|
23
|
-
}
|
|
24
|
-
createIntrospector(db) {
|
|
25
|
-
return new SqliteIntrospector(db);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Expo driver for Kysely.
|
|
30
|
-
*/ export class ExpoDriver {
|
|
31
|
-
#connectionMutex = new ConnectionMutex();
|
|
32
|
-
#connection;
|
|
33
|
-
constructor(config){
|
|
34
|
-
this.#connection = new ExpoConnection(config);
|
|
35
|
-
}
|
|
36
|
-
async releaseConnection() {
|
|
37
|
-
this.#connectionMutex.unlock();
|
|
38
|
-
}
|
|
39
|
-
async init() {}
|
|
40
|
-
async acquireConnection() {
|
|
41
|
-
await this.#connectionMutex.lock();
|
|
42
|
-
return this.#connection;
|
|
43
|
-
}
|
|
44
|
-
async beginTransaction(connection) {
|
|
45
|
-
await connection.directQuery('begin transaction');
|
|
46
|
-
}
|
|
47
|
-
async commitTransaction(connection) {
|
|
48
|
-
await connection.directQuery('commit');
|
|
49
|
-
}
|
|
50
|
-
async rollbackTransaction(connection) {
|
|
51
|
-
await connection.directQuery('rollback');
|
|
52
|
-
}
|
|
53
|
-
async destroy() {
|
|
54
|
-
this.#connection.closeConnection();
|
|
55
|
-
}
|
|
56
|
-
async getDatabaseRuntimeVersion() {
|
|
57
|
-
try {
|
|
58
|
-
const res = await this.#connection.directQuery('select sqlite_version() as version;');
|
|
59
|
-
//@ts-ignore
|
|
60
|
-
return res[0].version;
|
|
61
|
-
} catch (e) {
|
|
62
|
-
console.error(e);
|
|
63
|
-
return 'unknown';
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Expo connection for Kysely.
|
|
69
|
-
*/ class ExpoConnection {
|
|
70
|
-
sqlite;
|
|
71
|
-
debug;
|
|
72
|
-
config;
|
|
73
|
-
constructor(config){
|
|
74
|
-
this.sqlite = SQLite.openDatabaseSync(config.database);
|
|
75
|
-
this.debug = config.debug ?? false;
|
|
76
|
-
this.config = config;
|
|
77
|
-
if (this.config.disableForeignKeys) {
|
|
78
|
-
this.sqlite.execSync('PRAGMA foreign_keys = OFF;');
|
|
79
|
-
} else {
|
|
80
|
-
this.sqlite.execSync('PRAGMA foreign_keys = ON;');
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
async closeConnection() {
|
|
84
|
-
return this.sqlite.closeAsync();
|
|
85
|
-
}
|
|
86
|
-
async executeQuery(compiledQuery) {
|
|
87
|
-
let { sql, parameters, query } = compiledQuery;
|
|
88
|
-
// Kysely uses varchar(255) as the default string type for migrations which is not supported by STRICT mode.
|
|
89
|
-
if (query.kind === 'CreateTableNode' && !sql.includes('kysely_migration') && !sql.includes('kysely_migration_lock') && !sql.includes('STRICT') && !this.config.disableStrictModeCreateTable) {
|
|
90
|
-
sql += ' STRICT';
|
|
91
|
-
}
|
|
92
|
-
const readonly = query.kind === 'SelectQueryNode' || query.kind === 'RawNode';
|
|
93
|
-
const transformedParameters = serialize([
|
|
94
|
-
...parameters
|
|
95
|
-
]);
|
|
96
|
-
if (this.debug) {
|
|
97
|
-
console.debug(`${query.kind}${readonly ? ' (readonly)' : ''}: ${sql}`);
|
|
98
|
-
}
|
|
99
|
-
if (readonly) {
|
|
100
|
-
const res = await this.sqlite.getAllAsync(sql, transformedParameters);
|
|
101
|
-
return {
|
|
102
|
-
rows: res
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
const res = await this.sqlite.runAsync(sql, transformedParameters);
|
|
106
|
-
const queryResult = {
|
|
107
|
-
numAffectedRows: BigInt(res.changes),
|
|
108
|
-
insertId: BigInt(res.lastInsertRowId),
|
|
109
|
-
rows: []
|
|
110
|
-
};
|
|
111
|
-
if (this.debug) console.log('queryResult', queryResult);
|
|
112
|
-
return queryResult;
|
|
113
|
-
}
|
|
114
|
-
async directQuery(query) {
|
|
115
|
-
return await this.sqlite.getAllAsync(query, []);
|
|
116
|
-
}
|
|
117
|
-
streamQuery(compiledQuery, chunkSize) {
|
|
118
|
-
throw new Error('Expo SQLite driver does not support iterate on prepared statements');
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
class ConnectionMutex {
|
|
122
|
-
#promise;
|
|
123
|
-
#resolve;
|
|
124
|
-
async lock() {
|
|
125
|
-
while(this.#promise){
|
|
126
|
-
await this.#promise;
|
|
127
|
-
}
|
|
128
|
-
this.#promise = new Promise((resolve)=>{
|
|
129
|
-
this.#resolve = resolve;
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
unlock() {
|
|
133
|
-
const resolve = this.#resolve;
|
|
134
|
-
this.#promise = undefined;
|
|
135
|
-
this.#resolve = undefined;
|
|
136
|
-
resolve?.();
|
|
137
|
-
}
|
|
138
|
-
}
|
|
1
|
+
import*as e from"expo-sqlite";import{SqliteAdapter as t,SqliteIntrospector as n,SqliteQueryCompiler as i}from"kysely";import{serialize as s}from"./serialize.js";export class ExpoDialect{config;constructor(e){this.config={...e,disableStrictModeCreateTable:!0}}createDriver(){return new ExpoDriver(this.config)}createQueryCompiler(){return new i}createAdapter(){return new t}createIntrospector(e){return new n(e)}}export class ExpoDriver{#e=new o;#t;constructor(e){this.#t=new r(e)}async releaseConnection(){this.#e.unlock()}async init(){}async acquireConnection(){return await this.#e.lock(),this.#t}async beginTransaction(e){await e.directQuery("begin transaction")}async commitTransaction(e){await e.directQuery("commit")}async rollbackTransaction(e){await e.directQuery("rollback")}async destroy(){this.#t.closeConnection()}async getDatabaseRuntimeVersion(){try{return(await this.#t.directQuery("select sqlite_version() as version;"))[0].version}catch(e){return console.error(e),"unknown"}}}class r{sqlite;debug;config;constructor(t){this.sqlite=e.openDatabaseSync(t.database),this.debug=t.debug??!1,this.config=t,this.config.disableForeignKeys?this.sqlite.execSync("PRAGMA foreign_keys = OFF;"):this.sqlite.execSync("PRAGMA foreign_keys = ON;")}async closeConnection(){return this.sqlite.closeAsync()}async executeQuery(e){let{sql:t,parameters:n,query:i}=e;"CreateTableNode"!==i.kind||t.includes("kysely_migration")||t.includes("kysely_migration_lock")||t.includes("STRICT")||this.config.disableStrictModeCreateTable||(t+=" STRICT");let r="SelectQueryNode"===i.kind||"RawNode"===i.kind,o=s([...n]);if(this.debug&&console.debug(`${i.kind}${r?" (readonly)":""}: ${t}`),r)return{rows:await this.sqlite.getAllAsync(t,o)};let c=await this.sqlite.runAsync(t,o),a={numAffectedRows:BigInt(c.changes),insertId:BigInt(c.lastInsertRowId),rows:[]};return this.debug&&console.log("queryResult",a),a}async directQuery(e){return await this.sqlite.getAllAsync(e,[])}streamQuery(e,t){throw Error("Expo SQLite driver does not support iterate on prepared statements")}}class o{#n;#i;async lock(){for(;this.#n;)await this.#n;this.#n=new Promise(e=>{this.#i=e})}unlock(){let e=this.#i;this.#n=void 0,this.#i=void 0,e?.()}}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { AbstractSQLiteAdapter } from '@kubun/db-adapter';
|
|
2
|
-
import type { Dialect } from 'kysely';
|
|
1
|
+
import { AbstractSQLiteAdapter, type SearchHit, type SearchIndexConfig, type SearchQuery } from '@kubun/db-adapter';
|
|
2
|
+
import type { Dialect, Kysely } from 'kysely';
|
|
3
3
|
import { type ExpoDialectParams } from './driver.js';
|
|
4
4
|
export type AdapterParams = ExpoDialectParams;
|
|
5
5
|
export declare class ExpoAdapter extends AbstractSQLiteAdapter {
|
|
6
6
|
#private;
|
|
7
7
|
constructor(params: AdapterParams);
|
|
8
8
|
get dialect(): Dialect;
|
|
9
|
+
createSearchIndex(_db: Kysely<unknown>, _config: SearchIndexConfig): Promise<void>;
|
|
10
|
+
dropSearchIndex(_db: Kysely<unknown>, _modelID: string): Promise<void>;
|
|
11
|
+
updateSearchEntry(_db: Kysely<unknown>, _modelID: string, _documentID: string, _fields: Record<string, string>, _fieldNames: Array<string>): Promise<void>;
|
|
12
|
+
removeSearchEntry(_db: Kysely<unknown>, _modelID: string, _documentID: string): Promise<void>;
|
|
13
|
+
searchIndex(_db: Kysely<unknown>, _params: SearchQuery): Promise<Array<SearchHit>>;
|
|
9
14
|
}
|
|
10
|
-
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.js
CHANGED
|
@@ -1,12 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { ExpoDialect } from './driver.js';
|
|
3
|
-
export class ExpoAdapter extends AbstractSQLiteAdapter {
|
|
4
|
-
#dialect;
|
|
5
|
-
constructor(params){
|
|
6
|
-
super();
|
|
7
|
-
this.#dialect = new ExpoDialect(params);
|
|
8
|
-
}
|
|
9
|
-
get dialect() {
|
|
10
|
-
return this.#dialect;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
1
|
+
import{AbstractSQLiteAdapter as e}from"@kubun/db-adapter";import{ExpoDialect as r}from"./driver.js";export class ExpoAdapter extends e{#e;#r=!1;constructor(e){super(),this.#e=new r(e)}get dialect(){return this.#e}#a(){this.#r||(console.warn("ExpoAdapter: full-text search is not supported in Expo environments"),this.#r=!0)}async createSearchIndex(e,r){this.#a()}async dropSearchIndex(e,r){}async updateSearchEntry(e,r,a,n,t){}async removeSearchEntry(e,r,a){}async searchIndex(e,r){return this.#a(),[]}}
|
package/lib/serialize.d.ts
CHANGED
package/lib/serialize.js
CHANGED
|
@@ -1,27 +1 @@
|
|
|
1
|
-
export function serialize(
|
|
2
|
-
return parameters.map((parameter)=>{
|
|
3
|
-
if (typeof parameter === 'string') {
|
|
4
|
-
return parameter.toString();
|
|
5
|
-
}
|
|
6
|
-
if (parameter instanceof Date) {
|
|
7
|
-
return parameter.toISOString();
|
|
8
|
-
}
|
|
9
|
-
if (typeof parameter === 'number') {
|
|
10
|
-
return parameter;
|
|
11
|
-
}
|
|
12
|
-
if (parameter instanceof Uint8Array) {
|
|
13
|
-
return parameter;
|
|
14
|
-
}
|
|
15
|
-
if (parameter === null || parameter === undefined) {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
if (typeof parameter === 'object') {
|
|
19
|
-
return JSON.stringify(parameter);
|
|
20
|
-
}
|
|
21
|
-
if (typeof parameter === 'boolean') {
|
|
22
|
-
return parameter ? 'true' : 'false' // SQLite booleans must be stored a strings.
|
|
23
|
-
;
|
|
24
|
-
}
|
|
25
|
-
throw new Error(`Unknown type: ${typeof parameter}`);
|
|
26
|
-
});
|
|
27
|
-
}
|
|
1
|
+
export function serialize(r){return r.map(r=>{if("string"==typeof r)return r.toString();if(r instanceof Date)return r.toISOString();if("number"==typeof r||r instanceof Uint8Array)return r;if(null==r)return null;if("object"==typeof r)return JSON.stringify(r);if("boolean"==typeof r)return r?"true":"false";throw Error(`Unknown type: ${typeof r}`)})}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubun/db-expo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"license": "see LICENSE.md",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"type": "module",
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
],
|
|
16
16
|
"sideEffects": false,
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"expo-sqlite": "~
|
|
19
|
-
"kysely": "^0.28.
|
|
20
|
-
"@kubun/db-adapter": "^0.
|
|
18
|
+
"expo-sqlite": "~16.0.10",
|
|
19
|
+
"kysely": "^0.28.11",
|
|
20
|
+
"@kubun/db-adapter": "^0.5.0"
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
23
|
"build:clean": "del lib",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"build:types:ci": "tsc --emitDeclarationOnly --declarationMap false",
|
|
27
27
|
"build": "pnpm run build:clean && pnpm run build:js && pnpm run build:types",
|
|
28
28
|
"test:types": "tsc --noEmit",
|
|
29
|
-
"test:unit": "
|
|
29
|
+
"test:unit": "vitest run",
|
|
30
30
|
"test": "pnpm run test:types && pnpm run test:unit"
|
|
31
31
|
}
|
|
32
32
|
}
|
package/lib/driver.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../src/driver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AAErC,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,WAAW,EAIjB,MAAM,QAAQ,CAAA;AAIf,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,4BAA4B,CAAC,EAAE,OAAO,CAAA;IACtC,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,IAAI,CAAA;CACxD,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,GAAG;IAClD,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,4BAA4B,CAAC,EAAE,OAAO,CAAA;CACvC,CAAA;AAED;;GAEG;AACH,qBAAa,WAAY,YAAW,OAAO;IACzC,MAAM,EAAE,iBAAiB,CAAA;gBAEb,MAAM,EAAE,iBAAiB;IAIrC,YAAY,IAAI,UAAU;IAI1B,mBAAmB,IAAI,aAAa;IAIpC,aAAa,IAAI,cAAc;IAI/B,kBAAkB,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,oBAAoB;CAG9D;AAED;;GAEG;AACH,qBAAa,UAAW,YAAW,MAAM;;gBAI3B,MAAM,EAAE,iBAAiB;IAI/B,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIlC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAErB,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC;IAK5C,gBAAgB,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D,iBAAiB,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5D,mBAAmB,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,yBAAyB;CAUhC;AAED;;GAEG;AACH,cAAM,cAAe,YAAW,kBAAkB;IAChD,MAAM,EAAE,MAAM,CAAC,cAAc,CAAA;IAC7B,KAAK,EAAE,OAAO,CAAA;IACd,MAAM,EAAE,iBAAiB,CAAA;gBAEb,MAAM,EAAE,iBAAiB;IAa/B,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhC,YAAY,CAAC,CAAC,EAAE,aAAa,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IA0CtE,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAItD,WAAW,CAAC,CAAC,EACX,aAAa,EAAE,aAAa,EAC5B,SAAS,CAAC,EAAE,MAAM,GACjB,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;CAGzC"}
|
package/lib/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAErC,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEjE,MAAM,MAAM,aAAa,GAAG,iBAAiB,CAAA;AAE7C,qBAAa,WAAY,SAAQ,qBAAqB;;gBAGxC,MAAM,EAAE,aAAa;IAKjC,IAAI,OAAO,IAAI,OAAO,CAErB;CACF"}
|
package/lib/serialize.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../src/serialize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,wBAAgB,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,eAAe,CAAC,CAyB5E"}
|