11const { PromiseDB } = require ( './promisedb' ) ;
22const { accessError, asyncError } = require ( '../util/psql-error' ) ;
3+ const { simplifyArray, simplifyObject } = require ( '../util/helpers' ) ;
34const str = require ( '../util/string' ) ;
45const sp = require ( 'synchronized-promise' ) ;
56
67// Current database (undefined if not open)
78var db = undefined ;
9+ var simplify = false ;
810
911/**
1012 * Opens a database file.
1113 * @param {string } file Relative path to the database file
14+ * @returns {void|never }
1215 */
1316function open ( file ) {
17+ if ( db instanceof PromiseDB ) {
18+ close ( ) ;
19+ accessError ( true ) ;
20+ }
21+
1422 db = new PromiseDB ( file ) ;
1523}
1624
1725/**
1826 * Closes an open database.
27+ * @returns {void|never }
1928 */
2029function close ( ) {
21- db . close ( ) ;
30+ db instanceof PromiseDB ? db . close ( ) : accessError ( ) ;
2231 db = undefined ;
2332}
2433
@@ -55,72 +64,72 @@ function dynamicAccess(file) {
5564
5665/* ================ QUERIES ================ */
5766
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- }
67+ class Query {
68+ /**
69+ * Query constructor - handles dynamic database access
70+ * @param { BaseOptions } options
71+ */
72+ constructor ( options ) {
73+ this . options = options ;
74+ dynamicAccess ( options . file ) ;
75+ }
6776
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- }
77+ /**
78+ * Asynchronous database query.
79+ * @returns {QueryPromise }
80+ */
81+ async run ( ) {
82+ return await db . query ( this . options . statement , this . options . args ) ;
83+ }
7884
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- }
85+ /**
86+ * Asynchronous instert query.
87+ * @returns {Promise<void> }
88+ */
89+ async insert ( ) {
90+ const sql = str . insertStr ( this . options ) ;
91+ await db . query ( sql , this . options . values ) ;
92+ }
9093
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- }
94+ /**
95+ * Asynchronous selection query.
96+ * @returns {SelectionPromise }
97+ */
98+ async select ( ) {
99+ const { sql, args } = str . selectStr ( this . options ) ;
100+ const data = await db . query ( sql , args ) ;
101+ return ( data . length > 0 && this . options . first ) ? data [ 0 ] : data ;
102+ }
101103
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- }
104+ /**
105+ * Asynchronous update query.
106+ * @returns {Promise<void> }
107+ */
108+ async update ( ) {
109+ const { sql, args } = str . updateStr ( this . options ) ;
110+ await db . query ( sql , args ) ;
111+ }
112112
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- } ) ;
113+ /**
114+ * Asynchronous delete query.
115+ * @returns {Promise<void> }
116+ */
117+ async remove ( ) {
118+ const { sql, args } = str . deleteStr ( this . options ) ;
119+ await db . query ( sql , args ) ;
120+ }
121+
122+ /**
123+ * Asynchronous upsert query.
124+ * @returns {Promise<void> }
125+ */
126+ async upsert ( ) {
127+ await this . insert ( this . options ) . catch ( async error => {
128+ if ( error . code !== 'SQLITE_CONSTRAINT' ) throw new error ;
129+ if ( ! this . options . table ) this . options . table = this . options . into ;
130+ await this . update ( this . options ) ;
131+ } ) ;
132+ }
124133}
125134
126135/**
@@ -134,17 +143,30 @@ function sync(query, options = []) {
134143 return sp ( query ) ( options ) ;
135144}
136145
146+ const queryNames = Object . getOwnPropertyNames ( Query . prototype ) . filter ( name => name !== 'constructor' ) , queries = new Object ( ) ;
147+
148+ queryNames . forEach ( name => {
149+ queries [ name ] = async options => {
150+ const query = new Query ( options ) ;
151+ const run = query [ name ] ( ) ;
152+ if ( simplify ) run . then ( data => Array . isArray ( data ) ? simplifyArray ( data ) : simplifyObject ( data ) ) ;
153+ return await run ;
154+ }
155+ } ) ;
156+
137157module . exports = {
158+ simplifyOutput : ( bit = undefined ) => typeof bit === 'boolean' ? simplify = bit : simplify = ! simplify ,
159+
138160 // Export database open/close functions (synchronous!)
139161 open, close, get,
140162
141163 // Queries
142- run , insert , select , update , remove , upsert , sync,
164+ ... queries , sync,
143165
144166 /**
145167 * Asynchronous delete query. Optional overload, since 'delete' is reserved keyword.
146168 * @param {DeleteOptions } options
147169 * @returns {Promise<void> }
148170 */
149- delete : async options => await remove ( options )
171+ delete : async options => await queries . remove ( options )
150172}
0 commit comments