cordova-plugin-unvired-universal-sdk 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +59 -0
  2. package/aar/README.md +3 -0
  3. package/aar/Unvired_Kernel_Android.aar +0 -0
  4. package/aar/Unvired_Kernel_HTML5_Android.aar +0 -0
  5. package/package.json +69 -0
  6. package/plugin.xml +23 -0
  7. package/src/android/build.gradle +35 -0
  8. package/src/android/xml/provider_paths.xml +21 -0
  9. package/src/browser/UnviredPluginProxy.js +2430 -0
  10. package/src/browser/bootstrap.min.js +17 -0
  11. package/src/browser/codemirror.js +9755 -0
  12. package/src/browser/jquery-3.2.1.js +10253 -0
  13. package/src/browser/sql-wasm.wasm +0 -0
  14. package/src/browser/sql.js +203 -0
  15. package/src/browser/src_index_worker_js.unvired-db-worker.js +231 -0
  16. package/src/browser/unvired-db-worker.js +166 -0
  17. package/src/browser/vendors-node_modules_comlink_dist_esm_comlink_mjs.unvired-db-worker.js +22 -0
  18. package/src/ios/AttachmentPlugin.h +21 -0
  19. package/src/ios/AttachmentPlugin.m +180 -0
  20. package/src/ios/DataStructureHelper.h +28 -0
  21. package/src/ios/DataStructureHelper.m +188 -0
  22. package/src/ios/IOSAuthPlugin.h +14 -0
  23. package/src/ios/IOSAuthPlugin.m +13 -0
  24. package/src/ios/IOSDatabasePlugin.h +28 -0
  25. package/src/ios/IOSDatabasePlugin.m +253 -0
  26. package/src/ios/IOSFWSettingsPlugin.h +65 -0
  27. package/src/ios/IOSFWSettingsPlugin.m +363 -0
  28. package/src/ios/IOSLoggerPlugin.h +34 -0
  29. package/src/ios/IOSLoggerPlugin.m +198 -0
  30. package/src/ios/IOSLoginPlugin.h +29 -0
  31. package/src/ios/IOSLoginPlugin.m +480 -0
  32. package/src/ios/IOSProxyPlugin.h +21 -0
  33. package/src/ios/IOSProxyPlugin.m +172 -0
  34. package/src/ios/IOSSyncEnginePlugin.h +54 -0
  35. package/src/ios/IOSSyncEnginePlugin.m +847 -0
  36. package/src/ios/PluginConstants.h +195 -0
  37. package/src/ios/PluginHelper.h +29 -0
  38. package/src/ios/PluginHelper.m +74 -0
  39. package/src/ios/SyncHTML5Response.h +50 -0
  40. package/src/ios/SyncHTML5Response.m +68 -0
  41. package/www/applicationMeta/applicationMetadataParser.ts +285 -0
  42. package/www/applicationMeta/fieldConstants.ts +92 -0
  43. package/www/attachment/attachmentHelper.ts +326 -0
  44. package/www/attachment/attachmentQHelper.ts +158 -0
  45. package/www/attachment/attachmentService.ts +259 -0
  46. package/www/authenticationService.ts +746 -0
  47. package/www/bootstrap.min.js +17 -0
  48. package/www/codemirror.js +9755 -0
  49. package/www/database/appDatabaseManager.ts +54 -0
  50. package/www/database/databaseManager.ts +616 -0
  51. package/www/helper/dbCreateTablesManager.ts +354 -0
  52. package/www/helper/frameworkHelper.ts +127 -0
  53. package/www/helper/frameworkSettingsManager.ts +287 -0
  54. package/www/helper/getMessageTimerManager.ts +81 -0
  55. package/www/helper/httpConnection.ts +1051 -0
  56. package/www/helper/logger.ts +312 -0
  57. package/www/helper/notificationListnerHelper.ts +56 -0
  58. package/www/helper/passcodeGenerator.ts +61 -0
  59. package/www/helper/reconciler.ts +1062 -0
  60. package/www/helper/serverResponseHandler.ts +677 -0
  61. package/www/helper/serviceConstants.ts +254 -0
  62. package/www/helper/settingsHelper.ts +386 -0
  63. package/www/helper/status.ts +83 -0
  64. package/www/helper/syncInputDataManager.ts +205 -0
  65. package/www/helper/unviredAccount.ts +104 -0
  66. package/www/helper/unviredAccountManager.ts +120 -0
  67. package/www/helper/urlService.ts +43 -0
  68. package/www/helper/userSettingsManager.ts +172 -0
  69. package/www/helper/utils.ts +110 -0
  70. package/www/inbox/downloadMessageService.ts +270 -0
  71. package/www/inbox/inboxHelper.ts +132 -0
  72. package/www/inbox/inboxService.ts +223 -0
  73. package/www/jquery-3.2.1.js +10253 -0
  74. package/www/kernel.js +1380 -0
  75. package/www/outbox/outboxAttachmentManager.ts +152 -0
  76. package/www/outbox/outboxHelper.ts +67 -0
  77. package/www/outbox/outboxService.ts +519 -0
  78. package/www/sql-wasm.wasm +0 -0
  79. package/www/sql.js +209 -0
  80. package/www/subtract.ts +5 -0
  81. package/www/sum.ts +4 -0
  82. package/www/syncEngine.ts +687 -0
@@ -0,0 +1,54 @@
1
+ import { DatabaseManager, DatabaseType } from "./databaseManager";
2
+
3
+ export class AppDatabaseManager {
4
+ public async select(tableName: string, whereClause: string = ""): Promise<any> {
5
+ return await DatabaseManager.getInstance().select(DatabaseType.AppDb, tableName, whereClause)
6
+ }
7
+
8
+ public async insert(tableName: string, structureObject: any, isHeader: boolean): Promise<any> {
9
+ return await DatabaseManager.getInstance().insert(DatabaseType.AppDb, tableName, structureObject, isHeader, true)
10
+ }
11
+
12
+ public async insertOrUpdate(tableName: string, structureObject: any, isHeader: boolean): Promise<any> {
13
+ return await DatabaseManager.getInstance().insertOrUpdate(DatabaseType.AppDb, tableName, structureObject, isHeader)
14
+ }
15
+
16
+ public async delete(tableName: string, whereClause: string = ""): Promise<any> {
17
+ return await DatabaseManager.getInstance().delete(DatabaseType.AppDb, tableName, whereClause)
18
+ }
19
+
20
+ public async update(tableName: string, updatedObject: any, whereClause: any): Promise<any> {
21
+ return await DatabaseManager.getInstance().update(DatabaseType.AppDb, tableName, updatedObject, whereClause, true)
22
+ }
23
+
24
+ public async executeStatement(query: string): Promise<any> {
25
+ return await DatabaseManager.getInstance().executeStatement(DatabaseType.AppDb, query)
26
+ }
27
+
28
+ public async createSavePoint(savePoint: string): Promise<void> {
29
+ return await DatabaseManager.getInstance().createSavePoint(DatabaseType.AppDb, savePoint)
30
+ }
31
+
32
+ public async releaseSavePoint(savePoint: string): Promise<void> {
33
+ return await DatabaseManager.getInstance().releaseSavePoint(DatabaseType.AppDb, savePoint)
34
+ }
35
+
36
+ public async rollbackToSavePoint(savePoint: string): Promise<void> {
37
+ return await DatabaseManager.getInstance().rollbackToSavePoint(DatabaseType.AppDb, savePoint)
38
+ }
39
+
40
+ public async beginTransaction(): Promise<void> {
41
+ return await DatabaseManager.getInstance().beginTransaction(DatabaseType.AppDb)
42
+ }
43
+
44
+
45
+ public async endTransaction(): Promise<void> {
46
+ return await DatabaseManager.getInstance().endTransaction(DatabaseType.AppDb)
47
+ }
48
+
49
+ public async rollbackTransaction(): Promise<void> {
50
+ return await DatabaseManager.getInstance().rollbackTransaction(DatabaseType.AppDb)
51
+ }
52
+ }
53
+
54
+ export default new AppDatabaseManager()
@@ -0,0 +1,616 @@
1
+ import { FieldMeta, StructureMeta } from "../applicationMeta/applicationMetadataParser";
2
+ import FrameworkHelper from "../helper/frameworkHelper";
3
+ import { Logger } from "../helper/logger";
4
+ import { AttachmentBE } from "../helper/serviceConstants";
5
+ import { ObjectStatus, SyncStatus } from "../helper/utils";
6
+ import * as FieldConstants from '../applicationMeta/fieldConstants';
7
+ import { UnviredAccountManager } from "../helper/unviredAccountManager";
8
+ import * as ServiceConstants from '../helper/serviceConstants';
9
+ import AttachmentHelper from "../attachment/attachmentHelper";
10
+ import DbCreateTablesManager from "../helper/dbCreateTablesManager";
11
+
12
+ const constantFields = [
13
+ FieldConstants.FieldLid,
14
+ FieldConstants.FieldFid,
15
+ FieldConstants.FieldConflict,
16
+ FieldConstants.FieldTimestamp,
17
+ FieldConstants.FieldObjectStatus,
18
+ FieldConstants.FieldSyncStatus,
19
+ FieldConstants.FieldInfoMsgCat
20
+ ];
21
+
22
+ export enum DatabaseType {
23
+ AppDb = "AppDb",
24
+ FrameworkDb = "FrameworkDb"
25
+ }
26
+
27
+ export class DatabaseManager {
28
+ private fileName = 'DatabaseManager'
29
+ private static instance: DatabaseManager | null = null;
30
+ private fieldMetas: FieldMeta[] = [];
31
+ private isDbCreated: boolean = false;
32
+
33
+ private constructor() {
34
+ this.initializeDatabase()
35
+ }
36
+
37
+ private async initializeDatabase(): Promise<any> {
38
+ return new Promise((resolve, reject) => {
39
+ try {
40
+ const account = UnviredAccountManager.getInstance().getLastLoggedInAccount();
41
+ if (account == null) {
42
+ Logger.logInfo(this.fileName, "initializeDatabase", "Account not initialized");
43
+ resolve(false);
44
+ return;
45
+ }
46
+ if (this.isDbCreated) {
47
+ resolve(true);
48
+ return;
49
+ }
50
+ window.UnviredDB.create({
51
+ userId: account.getAccountId()
52
+ }, (result: any) => {
53
+ Logger.logDebug(this.fileName, "initializeDatabase", "return data: " + JSON.stringify(result));
54
+ Logger.logInfo(this.fileName, "initializeDatabase", "Database created successfully. ");
55
+ this.isDbCreated = true;
56
+ resolve(true);
57
+ }, (error: any) => {
58
+ Logger.logError(this.fileName, "initializeDatabase", "Error: " + error);
59
+ resolve(false);
60
+ });
61
+ }
62
+ catch(e) {
63
+ Logger.logError(this.fileName, 'initializeDatabase', e);
64
+ resolve(false);
65
+ }
66
+ });
67
+ }
68
+
69
+ public static getInstance(): DatabaseManager {
70
+ if (!DatabaseManager.instance) {
71
+ DatabaseManager.instance = new DatabaseManager();
72
+ }
73
+ return DatabaseManager.instance;
74
+ }
75
+
76
+ public async createTables(): Promise<boolean> {
77
+ const dbCreateTablesManager = new DbCreateTablesManager();
78
+ return await dbCreateTablesManager.createTables();
79
+ }
80
+
81
+ public select(dbType:DatabaseType, tableName: string, whereClause: string = ""): Promise<any> {
82
+ const newThis = this
83
+ return new Promise(async (resolve, reject) => {
84
+ if (!this.isDbCreated) {
85
+ const isInitialized = await newThis.initializeDatabase();
86
+ if (!isInitialized) {
87
+ reject('Database not initialized');
88
+ return;
89
+ }
90
+ }
91
+ var sqlQuery = `SELECT * FROM ${tableName}`
92
+ if (whereClause != null && whereClause != "") {
93
+ sqlQuery += ` WHERE ${whereClause}`
94
+ }
95
+ Logger.logDebug(newThis.fileName, 'select', 'sqlQuery: ' + sqlQuery);
96
+ try {
97
+ const result = await newThis.executeStatement(dbType, sqlQuery);
98
+ resolve(result);
99
+ }
100
+ catch(e) {
101
+ Logger.logError(newThis.fileName, 'select', e);
102
+ reject(e);
103
+ }
104
+ });
105
+ }
106
+
107
+
108
+ public insert(dbType: DatabaseType, tableName: string, structureObject: any, isHeader: boolean, isFromApp: boolean = false): Promise<any> {
109
+ const newThis = this
110
+ return new Promise(async (resolve, reject) => {
111
+ if (!this.isDbCreated) {
112
+ const isInitialized = await newThis.initializeDatabase();
113
+ if (!isInitialized) {
114
+ reject('Database not initialized');
115
+ return;
116
+ }
117
+ }
118
+ const sqlQuery = await newThis.constructInsertOrReplaceQuery(tableName, structureObject, "INSERT", isHeader, dbType == DatabaseType.FrameworkDb, newThis, isFromApp);
119
+ Logger.logDebug(newThis.fileName, 'insert', 'sqlQuery: ' + sqlQuery);
120
+ try {
121
+ const result = await newThis.executeStatement(dbType, sqlQuery);
122
+ resolve(result);
123
+ }
124
+ catch(e) {
125
+ Logger.logError(newThis.fileName, 'insert', e);
126
+ reject(e);
127
+ }
128
+ });
129
+ }
130
+
131
+ public insertOrUpdate(dbType: DatabaseType, tableName: string, structureObject: any, isHeader: boolean): Promise<any> {
132
+ const newThis = this
133
+ return new Promise(async (resolve, reject) => {
134
+ if (!this.isDbCreated) {
135
+ const isInitialized = await newThis.initializeDatabase();
136
+ if (!isInitialized) {
137
+ reject('Database not initialized');
138
+ return;
139
+ }
140
+ }
141
+
142
+ const fieldMetas = await this.getFieldMetaDataList(newThis);
143
+
144
+ const gidFieldMetas = fieldMetas.filter(element => element.structureName === tableName && element.isGid == "1");
145
+ var whereClause = ""
146
+ for (const fieldMeta of gidFieldMetas) {
147
+ if (structureObject[fieldMeta.fieldName] != null) {
148
+ if (whereClause != "") {
149
+ whereClause += ` AND `
150
+ }
151
+ whereClause += `${fieldMeta.fieldName} = '${this.escapeSqlString(structureObject[fieldMeta.fieldName])}'`
152
+ }
153
+ }
154
+
155
+ const existingObject = await newThis.select(dbType, tableName, whereClause);
156
+ var sqlQuery = ""
157
+ if (existingObject.length > 0) {
158
+ sqlQuery = await newThis.constructUpdateQuery(tableName, structureObject, `${FieldConstants.FieldLid} = '${structureObject[FieldConstants.FieldLid]}'`, dbType == DatabaseType.FrameworkDb, newThis);
159
+ }
160
+ else {
161
+ sqlQuery = await newThis.constructInsertOrReplaceQuery(tableName, structureObject, "INSERT", isHeader, dbType == DatabaseType.FrameworkDb, newThis);
162
+ }
163
+ Logger.logDebug(newThis.fileName, 'insertOrUpdate', 'sqlQuery: ' + sqlQuery);
164
+ try {
165
+ const result = await newThis.executeStatement(dbType, sqlQuery);
166
+ resolve(result);
167
+ }
168
+ catch(e) {
169
+ Logger.logError(newThis.fileName, 'insertOrUpdate', e);
170
+ reject(e);
171
+ }
172
+ });
173
+ }
174
+
175
+ public delete(dbType: DatabaseType, tableName: string, whereClause: string = ""): Promise<any> {
176
+ const newThis = this
177
+ return new Promise(async (resolve, reject) => {
178
+ if (!this.isDbCreated) {
179
+ const isInitialized = await newThis.initializeDatabase();
180
+ if (!isInitialized) {
181
+ reject('Database not initialized');
182
+ return;
183
+ }
184
+ }
185
+ var sqlQuery = `DELETE FROM ${tableName}`
186
+ if (whereClause != null && whereClause != "") {
187
+ sqlQuery += ` WHERE ${whereClause}`
188
+ }
189
+ Logger.logDebug(newThis.fileName, 'delete', 'sqlQuery: ' + sqlQuery);
190
+ try {
191
+ const result = await newThis.executeStatement(dbType, sqlQuery);
192
+ resolve(result);
193
+ }
194
+ catch(e) {
195
+ Logger.logError(newThis.fileName, 'delete', e);
196
+ reject(e);
197
+ }
198
+ });
199
+ }
200
+
201
+ public update(dbType: DatabaseType, tableName: string, updatedObject: any, whereClause: any, isFromApp: boolean = false): Promise<any> {
202
+ const newThis = this
203
+ return new Promise(async (resolve, reject) => {
204
+ if (!this.isDbCreated) {
205
+ const isInitialized = await newThis.initializeDatabase();
206
+ if (!isInitialized) {
207
+ reject('Database not initialized');
208
+ return;
209
+ }
210
+ }
211
+ const sqlQuery = await newThis.constructUpdateQuery(tableName, updatedObject, whereClause, dbType == DatabaseType.FrameworkDb, newThis, isFromApp);
212
+ Logger.logDebug(newThis.fileName, 'update', 'sqlQuery: ' + sqlQuery);
213
+ try {
214
+ const result = await newThis.executeStatement(dbType, sqlQuery);
215
+ resolve(result);
216
+ }
217
+ catch(e) {
218
+ Logger.logError(newThis.fileName, 'update', e);
219
+ reject(e);
220
+ }
221
+ });
222
+ }
223
+
224
+ public executeStatement(dbType: DatabaseType, sqlQuery: string): Promise<any> {
225
+ const newThis = this
226
+ return new Promise(async (resolve, reject) => {
227
+ if (!this.isDbCreated) {
228
+ const isInitialized = await newThis.initializeDatabase();
229
+ if (!isInitialized) {
230
+ reject('Database not initialized');
231
+ return;
232
+ }
233
+ }
234
+ try {
235
+ const result = await newThis.execute(dbType, sqlQuery);
236
+ resolve(result);
237
+ }
238
+ catch(e) {
239
+ Logger.logError(newThis.fileName, 'executeStatement', e);
240
+ reject(e);
241
+ }
242
+ });
243
+ }
244
+
245
+ private execute(dbType: DatabaseType, query: string): Promise<any> {
246
+ const newThis = this
247
+ return new Promise(async (resolve, reject) => {
248
+ const account = UnviredAccountManager.getInstance().getLastLoggedInAccount();
249
+ if (account == null) {
250
+ Logger.logInfo(newThis.fileName, "execute", "Account not initialized");
251
+ resolve("");
252
+ return;
253
+ }
254
+ window.UnviredDB.execute({
255
+ dbType: dbType,
256
+ query: query,
257
+ userId: account.getAccountId()
258
+ }, (result: any) => {
259
+ Logger.logDebug(newThis.fileName, "execute", "return data: " + JSON.stringify(result));
260
+ Logger.logInfo(newThis.fileName, "execute", "Execute successfull. ");
261
+ resolve(result);
262
+ }, (error: any) => {
263
+ Logger.logError(newThis.fileName, "execute", "Error: " + error);
264
+ reject(error);
265
+ });
266
+ });
267
+ }
268
+
269
+ public createSavePoint(dbType: DatabaseType, savePoint: string): Promise<void> {
270
+ const newThis = this
271
+ return new Promise(async (resolve, reject) => {
272
+ if (!this.isDbCreated) {
273
+ const isInitialized = await newThis.initializeDatabase();
274
+ if (!isInitialized) {
275
+ reject('Database not initialized');
276
+ return;
277
+ }
278
+ }
279
+ const sqlQuery = `SAVEPOINT ${savePoint}`
280
+ try {
281
+ const result = await newThis.execute(dbType, sqlQuery);
282
+ Logger.logInfo(newThis.fileName, "createSavePoint", "Result: " + JSON.stringify(result));
283
+ resolve(result);
284
+ }
285
+ catch(e) {
286
+ Logger.logError(newThis.fileName, 'createSavePoint', e);
287
+ reject(e);
288
+ }
289
+ });
290
+ }
291
+
292
+ public releaseSavePoint(dbType: DatabaseType, savePoint: string): Promise<void> {
293
+ const newThis = this
294
+ return new Promise(async (resolve, reject) => {
295
+ if (!this.isDbCreated) {
296
+ const isInitialized = await newThis.initializeDatabase();
297
+ if (!isInitialized) {
298
+ reject('Database not initialized');
299
+ return;
300
+ }
301
+ }
302
+
303
+ const sqlQuery = `RELEASE SAVEPOINT ${savePoint}`
304
+ try {
305
+ const result = await newThis.execute(dbType, sqlQuery);
306
+ Logger.logInfo(newThis.fileName, "releaseSavePoint", "Result: " + JSON.stringify(result));
307
+ resolve(result);
308
+ }
309
+ catch(e) {
310
+ Logger.logError(newThis.fileName, 'releaseSavePoint', e);
311
+ reject(e);
312
+ }
313
+ });
314
+ }
315
+
316
+ public rollbackToSavePoint(dbType: DatabaseType, savePoint: string): Promise<void> {
317
+ const newThis = this
318
+ return new Promise(async (resolve, reject) => {
319
+ if (!this.isDbCreated) {
320
+ const isInitialized = await newThis.initializeDatabase();
321
+ if (!isInitialized) {
322
+ reject('Database not initialized');
323
+ return;
324
+ }
325
+ }
326
+
327
+ const sqlQuery = `ROLLBACK TO SAVEPOINT ${savePoint}`
328
+ try {
329
+ const result = await newThis.execute(dbType, sqlQuery);
330
+ Logger.logInfo(newThis.fileName, "rollbackToSavePoint", "Result: " + JSON.stringify(result));
331
+ resolve(result);
332
+ }
333
+ catch(e) {
334
+ Logger.logError(newThis.fileName, 'rollbackToSavePoint', e);
335
+ reject(e);
336
+ }
337
+ });
338
+ }
339
+
340
+ public beginTransaction(dbType: DatabaseType): Promise<void> {
341
+ const newThis = this
342
+ return new Promise(async (resolve, reject) => {
343
+ if (!this.isDbCreated) {
344
+ const isInitialized = await newThis.initializeDatabase();
345
+ if (!isInitialized) {
346
+ reject('Database not initialized');
347
+ return;
348
+ }
349
+ }
350
+
351
+ const sqlQuery = `BEGIN TRANSACTION;`
352
+ try {
353
+ const result = await newThis.execute(dbType, sqlQuery);
354
+ Logger.logInfo(newThis.fileName, "beginTransaction", "Result: " + JSON.stringify(result));
355
+ resolve(result);
356
+ }
357
+ catch(e) {
358
+ Logger.logError(newThis.fileName, 'beginTransaction', e);
359
+ reject(e);
360
+ }
361
+ });
362
+ }
363
+
364
+ public endTransaction(dbType: DatabaseType): Promise<void> {
365
+ const newThis = this
366
+ return new Promise(async (resolve, reject) => {
367
+ if (!this.isDbCreated) {
368
+ const isInitialized = await newThis.initializeDatabase();
369
+ if (!isInitialized) {
370
+ reject('Database not initialized');
371
+ return;
372
+ }
373
+ }
374
+
375
+ const sqlQuery = `END TRANSACTION;`
376
+ try {
377
+ const result = await newThis.execute(dbType, sqlQuery);
378
+ Logger.logInfo(newThis.fileName, "endTransaction", "Result: " + JSON.stringify(result));
379
+ resolve(result);
380
+ }
381
+ catch(e) {
382
+ Logger.logError(newThis.fileName, 'endTransaction', e);
383
+ reject(e);
384
+ }
385
+ });
386
+ }
387
+
388
+ public rollbackTransaction(dbType: DatabaseType): Promise<void> {
389
+ const newThis = this
390
+ return new Promise(async (resolve, reject) => {
391
+ if (!this.isDbCreated) {
392
+ const isInitialized = await newThis.initializeDatabase();
393
+ if (!isInitialized) {
394
+ reject('Database not initialized');
395
+ return;
396
+ }
397
+ }
398
+
399
+ const sqlQuery = `ROLLBACK;`
400
+ try {
401
+ const result = await newThis.execute(dbType, sqlQuery);
402
+ Logger.logInfo(newThis.fileName, "rollbackTransaction", "Result: " + JSON.stringify(result));
403
+ resolve(result);
404
+ }
405
+ catch(e) {
406
+ Logger.logError(newThis.fileName, 'rollbackTransaction', e);
407
+ reject(e);
408
+ }
409
+ });
410
+ }
411
+
412
+ public async count(dbType: DatabaseType, tableName: string, whereClause: string = ""): Promise<number> {
413
+ try {
414
+ let sqlQuery = `SELECT COUNT(*) FROM ${tableName}`
415
+ if (whereClause != null && whereClause != "") {
416
+ sqlQuery += ` WHERE ${whereClause}`
417
+ }
418
+ const result = await this.executeStatement(dbType, sqlQuery);
419
+ return result.length > 0 ? result[0]["COUNT(*)"] : 0;
420
+ } catch (error) {
421
+ Logger.logError(this.fileName, "count", "Error while counting records in table: ${tableName}. Error: " + error);
422
+ return 0;
423
+ }
424
+ }
425
+
426
+ public async getFirstEntity(dbType: DatabaseType, tableName: string): Promise<any> {
427
+ try {
428
+ const result = await this.executeStatement(dbType, `SELECT * FROM ${tableName} ORDER BY timestamp ASC LIMIT 1`);
429
+ return result.length > 0 ? result[0] : null;
430
+ } catch (error) {
431
+ Logger.logError(this.fileName, "getFirstEntity", `Error while getting first record in table: ${tableName}. Error: ${error}`);
432
+ return null;
433
+ }
434
+ }
435
+
436
+ private async getFieldMetaDataList(classRef: any): Promise<FieldMeta[]> {
437
+ if (classRef.fieldMetas.length === 0) {
438
+ const fieldMetas = await this.select(DatabaseType.FrameworkDb, "FieldMeta");
439
+ classRef.fieldMetas = (fieldMetas == null || fieldMetas.length === 0) ? [] : fieldMetas;
440
+ }
441
+ return classRef.fieldMetas;
442
+ }
443
+
444
+ private async constructInsertOrReplaceQuery(tableName: string, jsonData: any, prefixString: string, isHeader: boolean, isFwTable: boolean, classRef: any, isFromApp: boolean = false): Promise<string> {
445
+ if (jsonData[FieldConstants.FieldLid] == null || jsonData[FieldConstants.FieldLid] === "") {
446
+ jsonData[FieldConstants.FieldLid] = FrameworkHelper.getUUID();
447
+ }
448
+
449
+ if (!isHeader && (jsonData[FieldConstants.FieldFid] == null || jsonData[FieldConstants.FieldFid] === "")) {
450
+ Logger.logError("DatabaseManager", "constructInsertOrReplaceQueries",
451
+ `${tableName} FID field is not set.`);
452
+ throw new Error(`${tableName} FID field is not set.`);
453
+ }
454
+
455
+ const fieldMetas = await this.getFieldMetaDataList(classRef);
456
+
457
+ if (!isFwTable) {
458
+ if (fieldMetas.length === 0) {
459
+ Logger.logError("DatabaseManager", "constructInsertOrReplaceQueries",
460
+ `${tableName} fields are not found in Framework DB in FieldMeta table.`);
461
+ throw new Error(`${tableName} fields are not found in Framework DB in FieldMeta table.`);
462
+ }
463
+
464
+ jsonData[FieldConstants.FieldTimestamp] = Date.now();
465
+
466
+ if (isFromApp) {
467
+ if (jsonData[FieldConstants.FieldObjectStatus] == null) {
468
+ if (prefixString === "INSERT") {
469
+ jsonData[FieldConstants.FieldObjectStatus] = ObjectStatus.add;
470
+ } else {
471
+ jsonData[FieldConstants.FieldObjectStatus] = ObjectStatus.modify;
472
+ }
473
+ }
474
+ if (jsonData[FieldConstants.FieldSyncStatus] == null) {
475
+ jsonData[FieldConstants.FieldSyncStatus] = SyncStatus.none;
476
+ }
477
+ }
478
+ }
479
+
480
+ const entityFieldMetas = fieldMetas.filter(element => element.structureName === tableName);
481
+
482
+ if (tableName.endsWith(AttachmentBE)) {
483
+ jsonData = await this.copyAttachmentToApplicationFolder(jsonData);
484
+ }
485
+ let fieldsString = "";
486
+ let valuesString = "";
487
+ const jsonDataKeys = Object.keys(jsonData);
488
+ for (const key of jsonDataKeys) {
489
+ let value = jsonData[key];
490
+ if (!isFwTable && entityFieldMetas.findIndex(element => element.fieldName === key) === -1 && !constantFields.includes(key)) {
491
+ continue;
492
+ }
493
+ if (value !== null) {
494
+ if (typeof value === 'string') {
495
+ value = this.escapeSqlString(value);
496
+ }
497
+ fieldsString += (fieldsString.length === 0 ? "" : ", ") + key;
498
+ valuesString += (valuesString.length === 0 ? "" : ", ") + `'${value}'`;
499
+ }
500
+ }
501
+ const queryString = `${prefixString} INTO ${tableName} (${fieldsString}) VALUES (${valuesString})`;
502
+ return queryString;
503
+ }
504
+
505
+ private async constructUpdateQuery(tableName: string, jsonData: any, whereClause: string, isFwTable: boolean, classRef: any, isFromApp: boolean = false): Promise<string> {
506
+
507
+ const fieldMetas = await this.getFieldMetaDataList(classRef);
508
+
509
+ if (!isFwTable && fieldMetas.length === 0) {
510
+ Logger.logError("DatabaseManager", "constructInsertOrReplaceQueries",
511
+ `${tableName} fields are not found in Framework DB in FieldMeta table.`);
512
+ throw new Error(`${tableName} fields are not found in Framework DB in FieldMeta table.`);
513
+ }
514
+
515
+ const entityFieldMetas = fieldMetas.filter(element => element.structureName === tableName);
516
+ if (!isFwTable && entityFieldMetas.length === 0) {
517
+ Logger.logError("DatabaseManager", "constructInsertOrReplaceQueries",
518
+ `${tableName} fields are not found for structure name: ${tableName}.`);
519
+ throw new Error(`${tableName} fields are not found for structure name: ${tableName}.`);
520
+ }
521
+
522
+ jsonData[FieldConstants.FieldTimestamp] = Date.now();
523
+ if (!isFwTable && isFromApp) {
524
+ jsonData[FieldConstants.FieldObjectStatus] = ObjectStatus.modify;
525
+ }
526
+ if (tableName.endsWith(AttachmentBE)) {
527
+ jsonData = await this.copyAttachmentToApplicationFolder(jsonData);
528
+ }
529
+ let updateString = "";
530
+ const jsonDataKeys = Object.keys(jsonData);
531
+ for (const key of jsonDataKeys) {
532
+ let value = jsonData[key];
533
+ if (!isFwTable && entityFieldMetas.findIndex(element => element.fieldName === key) === -1 && !constantFields.includes(key)) {
534
+ continue;
535
+ }
536
+ if (value !== null) {
537
+ if (typeof value === 'string') {
538
+ value = this.escapeSqlString(value);
539
+ }
540
+ updateString += (updateString.length == 0 ? "" : ", ") + `${key}='${value}'`;
541
+ }
542
+ }
543
+ if (!isFwTable && !isFromApp) {
544
+ // Add missing fields with null values
545
+ for (const fieldMeta of entityFieldMetas) {
546
+ if (!jsonDataKeys.includes(fieldMeta.fieldName) &&
547
+ !constantFields.includes(fieldMeta.fieldName) &&
548
+ fieldMeta.fieldName !== FieldConstants.FieldLid &&
549
+ fieldMeta.fieldName !== FieldConstants.FieldFid) {
550
+ updateString += (updateString.length === 0 ? "" : ", ") +
551
+ `${fieldMeta.fieldName}=NULL`;
552
+ }
553
+ }
554
+ }
555
+ var queryString = `UPDATE ${tableName} SET ${updateString}`;
556
+ if (whereClause != null && whereClause != "") {
557
+ queryString += ` WHERE ${whereClause}`
558
+ }
559
+ return queryString;
560
+ }
561
+
562
+ private async copyAttachmentToApplicationFolder(attachmentItem: any): Promise<any> {
563
+ if (attachmentItem[ServiceConstants.AttachmentItemFieldLocalPath] == null) {
564
+ await Logger.logInfo("Attachment", "copyAttachmentToApplicationFolder",
565
+ `${ServiceConstants.AttachmentItemFieldLocalPath} is null. Nothing to copy.`);
566
+ return attachmentItem;
567
+ }
568
+
569
+ const localPath: string = attachmentItem[ServiceConstants.AttachmentItemFieldLocalPath];
570
+ const uid: string = FrameworkHelper.getUUID();
571
+
572
+ // if fileName is missing, then Use the UID for the fileName and No Extension
573
+ let fileName: string = "";
574
+ if (attachmentItem[ServiceConstants.AttachmentItemFieldFileName] != null) {
575
+ fileName = attachmentItem[ServiceConstants.AttachmentItemFieldFileName];
576
+ } else if (attachmentItem[ServiceConstants.AttachmentItemFieldLocalPath] != null) {
577
+ let tempLocalPath: string = localPath;
578
+ if (tempLocalPath.endsWith('/')) {
579
+ tempLocalPath = tempLocalPath.substring(0, tempLocalPath.length - 1);
580
+ }
581
+ const pathArray: string[] = tempLocalPath.split("/");
582
+ if (pathArray.length > 0) {
583
+ fileName = pathArray[pathArray.length - 1];
584
+ } else {
585
+ fileName = uid;
586
+ }
587
+ } else {
588
+ fileName = uid;
589
+ }
590
+
591
+ try {
592
+ const arrayBuffer = await AttachmentHelper.readFileAsArrayBuffer(localPath);
593
+ if (arrayBuffer == null) {
594
+ Logger.logError("Attachment", "copyAttachmentToApplicationFolder",
595
+ `Unable to read attachment from ${localPath}`);
596
+ return attachmentItem;
597
+ }
598
+ const attachmentPath = await AttachmentHelper.addAttachment(fileName, arrayBuffer);
599
+ attachmentItem[ServiceConstants.AttachmentItemFieldLocalPath] = attachmentPath;
600
+ } catch (e) {
601
+ await Logger.logInfo("Attachment", "copyAttachmentToApplicationFolder",
602
+ `Unable to copy attachment from ${localPath} to application folder.`);
603
+ }
604
+ return attachmentItem;
605
+ }
606
+
607
+ public escapeSqlString(value: string): string {
608
+ if (value === null || value === undefined) {
609
+ return value;
610
+ }
611
+ const regex = /'/g;
612
+ return value.replace(regex, "''");
613
+ }
614
+ }
615
+
616
+ export default DatabaseManager;