xref: /expo/packages/expo-sqlite/build/SQLite.js (revision 0002abea)
1import './polyfillNextTick';
2import zipObject from 'lodash.zipobject';
3import { Platform } from 'react-native';
4import { NativeModulesProxy } from '@unimodules/core';
5import customOpenDatabase from '@expo/websql/custom';
6const { ExponentSQLite } = NativeModulesProxy;
7class SQLiteDatabase {
8    constructor(name) {
9        this._closed = false;
10        this._name = name;
11    }
12    exec(queries, readOnly, callback) {
13        if (this._closed) {
14            throw new Error(`The SQLite database is closed`);
15        }
16        ExponentSQLite.exec(this._name, queries.map(_serializeQuery), readOnly).then(nativeResultSets => {
17            callback(null, nativeResultSets.map(_deserializeResultSet));
18        }, error => {
19            // TODO: make the native API consistently reject with an error, not a string or other type
20            callback(error instanceof Error ? error : new Error(error));
21        });
22    }
23    close() {
24        this._closed = true;
25        ExponentSQLite.close(this._name);
26    }
27}
28function _serializeQuery(query) {
29    return [query.sql, Platform.OS === 'android' ? query.args.map(_escapeBlob) : query.args];
30}
31function _deserializeResultSet(nativeResult) {
32    let [errorMessage, insertId, rowsAffected, columns, rows] = nativeResult;
33    // TODO: send more structured error information from the native module so we can better construct
34    // a SQLException object
35    if (errorMessage !== null) {
36        return { error: new Error(errorMessage) };
37    }
38    return {
39        insertId,
40        rowsAffected,
41        rows: rows.map(row => zipObject(columns, row)),
42    };
43}
44function _escapeBlob(data) {
45    if (typeof data === 'string') {
46        /* eslint-disable no-control-regex */
47        return data
48            .replace(/\u0002/g, '\u0002\u0002')
49            .replace(/\u0001/g, '\u0001\u0002')
50            .replace(/\u0000/g, '\u0001\u0001');
51        /* eslint-enable no-control-regex */
52    }
53    else {
54        return data;
55    }
56}
57const _openExpoSQLiteDatabase = customOpenDatabase(SQLiteDatabase);
58function addExecMethod(db) {
59    db.exec = db._db.exec;
60    return db;
61}
62export function openDatabase(name, version = '1.0', description = name, size = 1, callback) {
63    if (name === undefined) {
64        throw new TypeError(`The database name must not be undefined`);
65    }
66    const db = _openExpoSQLiteDatabase(name, version, description, size, callback);
67    const dbWithExec = addExecMethod(db);
68    return dbWithExec;
69}
70export default {
71    openDatabase,
72};
73//# sourceMappingURL=SQLite.js.map