1
1
import fs from 'fs' ;
2
2
import path from 'path' ;
3
+
3
4
import Database from 'better-sqlite3' ;
4
5
import { app , ipcMain } from 'electron' ;
6
+
5
7
import logger from './log' ;
6
8
7
9
const isDevelopment = process . env . NODE_ENV === 'development' ;
@@ -11,51 +13,53 @@ const registry = new Map();
11
13
* Open or retrieve an existing SQLite database.
12
14
*/
13
15
const openDatabase = ( name : string ) => {
14
- // Check registry first
15
- if ( registry . has ( name ) ) {
16
- return { name } ;
17
- }
16
+ // Check registry first
17
+ if ( registry . has ( name ) ) {
18
+ return { name } ;
19
+ }
18
20
19
- try {
20
- const dbFolder = isDevelopment
21
- ? path . resolve ( 'databases' )
22
- : path . resolve ( app . getPath ( 'userData' ) , 'wcpos_dbs' ) ;
21
+ try {
22
+ const dbFolder = isDevelopment
23
+ ? path . resolve ( 'databases' )
24
+ : path . resolve ( app . getPath ( 'userData' ) , 'wcpos_dbs' ) ;
23
25
24
- // Create folder if it doesn't exist
25
- if ( ! fs . existsSync ( dbFolder ) ) {
26
- try {
27
- fs . mkdirSync ( dbFolder , { recursive : true } ) ;
28
- logger . info ( `Created database folder: ${ dbFolder } ` ) ;
29
- } catch ( err ) {
30
- logger . error ( `Failed to create database folder: ${ dbFolder } ` , err ) ;
31
- }
32
- }
26
+ // Create folder if it doesn't exist
27
+ if ( ! fs . existsSync ( dbFolder ) ) {
28
+ try {
29
+ fs . mkdirSync ( dbFolder , { recursive : true } ) ;
30
+ logger . info ( `Created database folder: ${ dbFolder } ` ) ;
31
+ } catch ( err ) {
32
+ logger . error ( `Failed to create database folder: ${ dbFolder } ` , err ) ;
33
+ }
34
+ }
33
35
34
- logger . info ( 'Opening SQLite database' , name ) ;
35
- const db = new Database ( path . resolve ( dbFolder , `${ name } .sqlite3` ) , { verbose : logger . debug } ) ;
36
- logger . info ( 'Opened SQLite database' , db ) ;
36
+ logger . info ( 'Opening SQLite database' , name ) ;
37
+ const db = new Database ( path . resolve ( dbFolder , `${ name } .sqlite3` ) , {
38
+ verbose : isDevelopment ? logger . silly : undefined ,
39
+ } ) ;
40
+ logger . info ( 'Opened SQLite database' , db ) ;
37
41
38
- registry . set ( name , db ) ;
39
- return { name } ;
40
- } catch ( error ) {
41
- logger . error ( 'Failed to open database' , error ) ;
42
- throw error ;
43
- }
42
+ registry . set ( name , db ) ;
43
+ return { name } ;
44
+ } catch ( error ) {
45
+ logger . error ( 'Failed to open database' , error ) ;
46
+ throw error ;
47
+ }
44
48
} ;
45
49
46
50
export const closeAll = ( ) => {
47
- registry . forEach ( ( db , name ) => {
48
- db . close ( ) ;
49
- registry . delete ( name ) ;
50
- logger . info ( `Closed and removed ${ name } from registry.` ) ;
51
- } ) ;
51
+ registry . forEach ( ( db , name ) => {
52
+ db . close ( ) ;
53
+ registry . delete ( name ) ;
54
+ logger . info ( `Closed and removed ${ name } from registry.` ) ;
55
+ } ) ;
52
56
} ;
53
57
54
58
/**
55
59
* Convert boolean values in parameters to numbers (SQLite doesn't support booleans).
56
60
*/
57
61
function convertBooleansToNumbers ( params : ( string | number | boolean ) [ ] ) : ( string | number ) [ ] {
58
- return params . map ( param => ( typeof param === 'boolean' ? ( param ? 1 : 0 ) : param ) ) ;
62
+ return params . map ( ( param ) => ( typeof param === 'boolean' ? ( param ? 1 : 0 ) : param ) ) ;
59
63
}
60
64
61
65
/**
@@ -67,51 +71,51 @@ function convertBooleansToNumbers(params: (string | number | boolean)[]): (strin
67
71
* - All others: use .run()
68
72
*/
69
73
function executeSql ( db , sql , params ) {
70
- if ( / ^ \s * S E L E C T / i. test ( sql ) ) {
71
- return db . prepare ( sql ) . all ( params ) ;
72
- }
73
- // PRAGMA assignments like "PRAGMA synchronous = normal" do not return data.
74
- if ( / ^ \s * P R A G M A \s + \w + \s * = \s * / i. test ( sql ) ) {
75
- return db . prepare ( sql ) . run ( params ) ;
76
- }
77
- if ( / ^ \s * P R A G M A / i. test ( sql ) ) {
78
- return db . prepare ( sql ) . all ( params ) ;
79
- }
80
- return db . prepare ( sql ) . run ( params ) ;
74
+ if ( / ^ \s * S E L E C T / i. test ( sql ) ) {
75
+ return db . prepare ( sql ) . all ( params ) ;
76
+ }
77
+ // PRAGMA assignments like "PRAGMA synchronous = normal" do not return data.
78
+ if ( / ^ \s * P R A G M A \s + \w + \s * = \s * / i. test ( sql ) ) {
79
+ return db . prepare ( sql ) . run ( params ) ;
80
+ }
81
+ if ( / ^ \s * P R A G M A / i. test ( sql ) ) {
82
+ return db . prepare ( sql ) . all ( params ) ;
83
+ }
84
+ return db . prepare ( sql ) . run ( params ) ;
81
85
}
82
86
83
87
/**
84
88
* Handle SQLite IPC requests.
85
89
*/
86
90
ipcMain . handle ( 'sqlite' , ( event , obj ) => {
87
- logger . silly ( 'SQL request' , JSON . stringify ( obj , null , 2 ) ) ;
88
- try {
89
- let db ;
90
- switch ( obj . type ) {
91
- case 'open' :
92
- return openDatabase ( obj . name ) ;
93
- case 'close' :
94
- db = registry . get ( obj . name ) ;
95
- if ( ! db ) throw new Error ( `Database connection "${ obj . name } " not found` ) ;
96
- db . close ( ) ;
97
- registry . delete ( obj . name ) ;
98
- logger . info ( `Closed and removed ${ obj . name } from registry.` ) ;
99
- return ;
100
- case 'quit' :
101
- closeAll ( ) ;
102
- return ;
103
- case 'all' :
104
- case 'run' : {
105
- db = registry . get ( obj . name ) ;
106
- if ( ! db ) throw new Error ( `Database connection "${ obj . name } " not found` ) ;
107
- const convertedParams = convertBooleansToNumbers ( obj . sql . params ) ;
108
- return executeSql ( db , obj . sql . query , convertedParams ) ;
109
- }
110
- default :
111
- throw new Error ( 'Unknown type' ) ;
112
- }
113
- } catch ( err ) {
114
- logger . error ( 'SQLite error' , err , obj ) ;
115
- throw err ;
116
- }
117
- } ) ;
91
+ logger . silly ( 'SQL request' , JSON . stringify ( obj , null , 2 ) ) ;
92
+ try {
93
+ let db ;
94
+ switch ( obj . type ) {
95
+ case 'open' :
96
+ return openDatabase ( obj . name ) ;
97
+ case 'close' :
98
+ db = registry . get ( obj . name ) ;
99
+ if ( ! db ) throw new Error ( `Database connection "${ obj . name } " not found` ) ;
100
+ db . close ( ) ;
101
+ registry . delete ( obj . name ) ;
102
+ logger . info ( `Closed and removed ${ obj . name } from registry.` ) ;
103
+ return ;
104
+ case 'quit' :
105
+ closeAll ( ) ;
106
+ return ;
107
+ case 'all' :
108
+ case 'run' : {
109
+ db = registry . get ( obj . name ) ;
110
+ if ( ! db ) throw new Error ( `Database connection "${ obj . name } " not found` ) ;
111
+ const convertedParams = convertBooleansToNumbers ( obj . sql . params ) ;
112
+ return executeSql ( db , obj . sql . query , convertedParams ) ;
113
+ }
114
+ default :
115
+ throw new Error ( 'Unknown type' ) ;
116
+ }
117
+ } catch ( err ) {
118
+ logger . error ( 'SQLite error' , err , obj ) ;
119
+ throw err ;
120
+ }
121
+ } ) ;
0 commit comments