11const { PromiseDB } = require ( './promisedb' ) ;
2- const sqlstr = require ( '../util/sqlstr' ) ;
2+ const { accessError, asyncError } = require ( '../util/psql-error' ) ;
3+ const str = require ( '../util/string' ) ;
34const sp = require ( 'synchronized-promise' ) ;
45
56// Current database (undefined if not open)
67var db = undefined ;
78
89/**
910 * Opens a database file.
10- * @param {string } file Path to the database file
11+ * @param {string } file Relative path to the database file
1112 */
1213function open ( file ) {
1314 db = new PromiseDB ( file ) ;
@@ -21,10 +22,19 @@ function close() {
2122 db = undefined ;
2223}
2324
25+ /**
26+ * Retrieves the database, if open.
27+ * @returns {PromiseDB|never }
28+ */
29+ function get ( ) {
30+ if ( db instanceof PromiseDB ) return db ;
31+ accessError ( ) ;
32+ }
33+
2434/**
2535 * Dynamically opens and closes a database if a file is provided.
26- * @param {string } file
27- * @returns {void|Promise<Function > }
36+ * @param {string } file Relative path to the database file
37+ * @returns {void|Promise<void > }
2838 */
2939function dynamicAccess ( file ) {
3040 // If file is undefined or db is already open, do nothing
@@ -37,90 +47,104 @@ function dynamicAccess(file) {
3747 try {
3848 open ( file ) ;
3949 resolve ( { then : close } ) ;
40- } catch ( error ) {
50+ } catch ( error ) {
4151 reject ( error ) ;
4252 }
4353 } ) ;
4454}
4555
46- module . exports = {
47- // Export database open/close functions (synchronous!)
48- open, close,
56+ /* ================ QUERIES ================ */
4957
50- /**
51- * Retrieves the database, if open.
52- * @returns {PromiseDB }
53- */
54- getDatabase : function ( ) {
55- if ( db instanceof PromiseDB ) return db ;
56- throw new Error ( 'Database is not open.' ) ;
57- } ,
58+ /**
59+ * Asynchronous database query.
60+ * @param {RunOptions } options SQL statement
61+ * @returns {QueryPromise }
62+ */
63+ async function run ( options ) {
64+ dynamicAccess ( options . file ) ;
65+ return await db . query ( options . statement , options . args ) ;
66+ }
5867
59- /**
60- * Asynchronous database query.
61- * @param {RunOptions } options SQL statement
62- * @returns {QueryPromise }
63- */
64- run : async function ( options ) {
65- dynamicAccess ( options . file ) ;
66- return await db . query ( options . statement , options . args ) ;
67- } ,
68+ /**
69+ * Asynchronous instert query.
70+ * @param {InsertOptions } options
71+ * @returns {Promise<void> }
72+ */
73+ async function insert ( options ) {
74+ dynamicAccess ( options . file ) ;
75+ const sql = str . insertStr ( options ) ;
76+ await db . query ( sql , options . values ) ;
77+ }
6878
69- /**
70- * Asynchronous instert query.
71- * @param {InsertOptions } options
72- * @returns {Promise<void> }
73- */
74- insert : async function ( options ) {
75- dynamicAccess ( options . file ) ;
76- const sql = sqlstr . insertStr ( options ) ;
77- await db . query ( sql , options . values ) ;
78- } ,
79+ /**
80+ * Asynchronous selection query.
81+ * @param {SelectionOptions } options
82+ * @returns {SelectionPromise }
83+ */
84+ async function select ( options ) {
85+ dynamicAccess ( options . file ) ;
86+ const { sql, args } = str . selectStr ( options ) ;
87+ const data = await db . query ( sql , args ) ;
88+ return ( data . length > 0 && options . first ) ? data [ 0 ] : data ;
89+ }
7990
80- /**
81- * Asynchronous selection query.
82- * @param {SelectionOptions } options
83- * @returns {SelectionPromise }
84- */
85- select : async function ( options ) {
86- dynamicAccess ( options . file ) ;
87- const { sql, args } = sqlstr . selectStr ( options ) ;
88- const data = await db . query ( sql , args ) ;
89- return ( data . length > 0 && options . first ) ? data [ 0 ] : data ;
90- } ,
91+ /**
92+ * Asynchronous update query.
93+ * @param {UpdateOptions } options
94+ * @returns {Promise<void> }
95+ */
96+ async function update ( options ) {
97+ dynamicAccess ( options . file ) ;
98+ const { sql, args } = str . updateStr ( options ) ;
99+ await db . query ( sql , args ) ;
100+ }
91101
92- /**
93- * Asynchronous update query.
94- * @param {UpdateOptions } options
95- * @returns {Promise<void> }
96- */
97- update : async function ( options ) {
98- dynamicAccess ( options . file ) ;
99- const { sql, args } = sqlstr . updateStr ( options ) ;
100- await db . query ( sql , args ) ;
101- } ,
102+ /**
103+ * Asynchronous delete query.
104+ * @param {DeleteOptions } options
105+ * @returns {Promise<void> }
106+ */
107+ async function remove ( options ) {
108+ dynamicAccess ( options . file ) ;
109+ const { sql, args } = str . deleteStr ( options ) ;
110+ await db . query ( sql , args ) ;
111+ }
112+
113+ /**
114+ * Asynchronous upsert query.
115+ * @param {UpsertOptions } options
116+ * @returns {Promise<void> }
117+ */
118+ async function upsert ( options ) {
119+ await insert ( options ) . catch ( async error => {
120+ if ( error . code !== 'SQLITE_CONSTRAINT' ) throw new error ;
121+ if ( ! options . table ) options . table = options . into ;
122+ await update ( options ) ;
123+ } ) ;
124+ }
125+
126+ /**
127+ * Synchronous query.
128+ * @param {Function } query
129+ * @param {string[]|BaseOptions } options
130+ * @returns {QueryRetval }
131+ */
132+ function sync ( query , options = [ ] ) {
133+ if ( query . constructor . name !== 'AsyncFunction' ) asyncError ( ) ;
134+ return sp ( query ) ( options ) ;
135+ }
136+
137+ module . exports = {
138+ // Export database open/close functions (synchronous!)
139+ open, close, get,
140+
141+ // Queries
142+ run, insert, select, update, remove, upsert, sync,
102143
103144 /**
104- * Asynchronous delete query.
145+ * Asynchronous delete query. Optional overload, since 'delete' is reserved keyword.
105146 * @param {DeleteOptions } options
106147 * @returns {Promise<void> }
107148 */
108- delete : async function ( options ) {
109- dynamicAccess ( options . file ) ;
110- const { sql, args } = sqlstr . deleteStr ( options ) ;
111- await db . query ( sql , args ) ;
112- } ,
113-
114- /**
115- * Synchronous query.
116- * @param {function } query
117- * @param {string[]|BaseOptions } options
118- * @returns {QueryRetval }
119- */
120- sync : function ( query , options = [ ] ) {
121- if ( query . constructor . name !== 'AsyncFunction' )
122- throw new Error ( 'Function is not asynchronous.' ) ;
123-
124- return sp ( query ) ( options ) ;
125- }
149+ delete : async options => await remove ( options )
126150}
0 commit comments