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