@egi/smart-db 2.4.3 → 2.4.6
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.
- package/helpers/extract-db-api.js +1 -1
- package/package.json +11 -11
- package/smart-db-log.js +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import fs from"fs";import _ from"lodash";import process from"process";import{SmartDbBetterSqlite3}from"../drivers/smart-db-better-sqlite3";import{SmartDbCoreTableModel}from"../models/smart-db-core-table-model";import{SqliteMasterModel}from"../models/sqlite-master-model";import{IN,NE}from"../smart-db-globals";function getType(e){let t;return t=e?e.match(/varchar/i)||e.match(/text/i)?"string":e.match(/integer\(1\)/i)?"boolean":e.match(/date/i)?"Date":e.match(/integer/i)||e.match(/number/i)?"number":e||"SqlValueType":"SqlValueType",t}function extractDbApi(e){console.log(`extract interface from '${e.db.getDbConnector()}' to '${e.modelDirectory}'`),fs.existsSync(e.modelDirectory)||fs.mkdirSync(e.modelDirectory,{recursive:!0});const t=e.db.getAllSync(SqliteMasterModel,{type:IN(["table","view"]),name:NE("sqlite_sequence")});if(!1===t)console.error(e.db.getLastError()),process.abort();else{let r=[];if(!e.includeCoreTables&&e.db.existsSync(SmartDbCoreTableModel)){const t=e.db.getAllSync(SmartDbCoreTableModel);if(!1===t)throw e.db.getLastError();t.forEach(e=>{r.push(e.name)})}const n=[];t.forEach(t=>{if(!r.includes(t.name)){const r=t.name[0].toUpperCase()+_.camelCase(t.name.substr(1))+"Model";n.push(r);const a=[];e.db.getTableInfo(t.name).then(n=>{const s=n.fields;let o=!1,i="",l="",c="",m="",p="";const b=t.name.replace(/[^[a-z0-9]/g,"-")+"-model";if(i+="/* eslint-disable @typescript-eslint/member-ordering */\n",i+="// noinspection JSUnusedGlobalSymbols\n",s){e.abstractModelModule==e.smartDbInterfaces?e.separateApi?(c+=`import {GenericModelData} from "${e.abstractModelModule}";\n`,p+=`import {AbstractModel, ModelAttributeMap} from "${e.abstractModelModule}";\n`,p+=`import {${r}Data} from "./${b}-api";\n`):p+=`import {AbstractModel, GenericModelData, ModelAttributeMap} from "${e.abstractModelModule}";\n`:e.separateApi?(c+=`import {GenericModelData} from "${e.smartDbInterfaces}";\n`,p+=`import {ModelAttributeMap} from "${e.smartDbInterfaces}";\n`,p+=`import {AbstractModel} from "${e.abstractModelModule}";\n`,p+=`import {${r}Data} from "./${b}-api";\n`):(p+=`import {GenericModelData, ModelAttributeMap} from "${e.smartDbInterfaces}";\n`,p+=`import {AbstractModel} from "${e.abstractModelModule}";\n`),l+=`export interface ${r}Data extends GenericModelData {\n`;let n,d="",u="",f=!1;const h=[];s.forEach(e=>{const t=e.name.match(/([a-z0-9]{1,4})_/i);e.isPk&&(d=e.name,t&&(u=t[1])),t?h.includes(t[1])||h.push(t[1]):f=!0}),u||f||1!=h.length||(u=h[0]),u&&(n=new RegExp(`^${u}_(.*)$`));const $={};s.forEach(r=>{const s=getType(r.type);let i;o||"SqlValueType"!=s||(p+=`import {SqlValueType} from "${e.smartDbInterfaces}";\n`,o=!0);const
|
|
1
|
+
import fs from"fs";import _ from"lodash";import process from"process";import{SmartDbBetterSqlite3}from"../drivers/smart-db-better-sqlite3";import{SmartDbCoreTableModel}from"../models/smart-db-core-table-model";import{SqliteMasterModel}from"../models/sqlite-master-model";import{IN,NE}from"../smart-db-globals";function getType(e){let t;return t=e?e.match(/varchar/i)||e.match(/text/i)?"string":e.match(/integer\(1\)/i)?"boolean":e.match(/date/i)?"Date":e.match(/integer/i)||e.match(/number/i)?"number":e||"SqlValueType":"SqlValueType",t}function extractDbApi(e){console.log(`extract interface from '${e.db.getDbConnector()}' to '${e.modelDirectory}'`),fs.existsSync(e.modelDirectory)||fs.mkdirSync(e.modelDirectory,{recursive:!0});const t=e.db.getAllSync(SqliteMasterModel,{type:IN(["table","view"]),name:NE("sqlite_sequence")});if(!1===t)console.error(e.db.getLastError()),process.abort();else{let r=[];if(!e.includeCoreTables&&e.db.existsSync(SmartDbCoreTableModel)){const t=e.db.getAllSync(SmartDbCoreTableModel);if(!1===t)throw e.db.getLastError();t.forEach(e=>{r.push(e.name)})}const n=[];t.forEach(t=>{if(!r.includes(t.name)){const r=t.name[0].toUpperCase()+_.camelCase(t.name.substr(1))+"Model";n.push(r);const a=[];e.db.getTableInfo(t.name).then(n=>{const s=n.fields;let o=!1,i="",l="",c="",m="",p="";const b=t.name.replace(/[^[a-z0-9]/g,"-")+"-model";if(i+="/* eslint-disable @typescript-eslint/member-ordering */\n",i+="// noinspection JSUnusedGlobalSymbols\n",s){e.abstractModelModule==e.smartDbInterfaces?e.separateApi?(c+=`import {GenericModelData} from "${e.abstractModelModule}";\n`,p+=`import {AbstractModel, ModelAttributeMap} from "${e.abstractModelModule}";\n`,p+=`import {${r}Data} from "./${b}-api";\n`):p+=`import {AbstractModel, GenericModelData, ModelAttributeMap} from "${e.abstractModelModule}";\n`:e.separateApi?(c+=`import {GenericModelData} from "${e.smartDbInterfaces}";\n`,p+=`import {ModelAttributeMap} from "${e.smartDbInterfaces}";\n`,p+=`import {AbstractModel} from "${e.abstractModelModule}";\n`,p+=`import {${r}Data} from "./${b}-api";\n`):(p+=`import {GenericModelData, ModelAttributeMap} from "${e.smartDbInterfaces}";\n`,p+=`import {AbstractModel} from "${e.abstractModelModule}";\n`),l+=`export interface ${r}Data extends GenericModelData {\n`;let n,d="",u="",f=!1;const h=[];s.forEach(e=>{const t=e.name.match(/([a-z0-9]{1,4})_/i);e.isPk&&(d=e.name,t&&(u=t[1])),t?h.includes(t[1])||h.push(t[1]):f=!0}),u||f||1!=h.length||(u=h[0]),u&&(n=new RegExp(`^${u}_(.*)$`));const $={};s.forEach(r=>{const s=getType(r.type);let i;o||"SqlValueType"!=s||(c+=`import {SqlValueType} from "${e.smartDbInterfaces}";\n`,p+=`import {SqlValueType} from "${e.smartDbInterfaces}";\n`,o=!0);const m=n&&r.name.match(n);i=m?_.camelCase(m[1]):_.camelCase(r.name);let b=!0;i!=r.name&&(a.push({name:i,attribute:i,type:s,typeScriptStyle:b,alias:r.name}),b=!1),a.push({name:r.name,attribute:i,type:s,physical:void 0!==r.cid,typeScriptStyle:b}),$[i]=s,"user"==t.name&&"name"==i&&(l+=" // @ts-ignore"),l+=` ${i}?: ${s};\n`}),l+="}\n",m+=`export class ${r} extends AbstractModel<${r}, ${r}Data> {\n`,_.forEach($,(e,t)=>{m+=` private _${t}?: ${e};\n`}),"user"==t.name&&(m+=" private _hash?: string;\n",m+=" private _privileges?: string[];\n"),m+="\n",m+=" static readonly attributeMap: ModelAttributeMap = {\n",a.forEach((e,t)=>{t>0&&(m+=",\n"),m+=` ${e.name}: {\n`,e.physical&&(m+=" physical: true,\n"),e.alias&&(m+=` alias: "${e.alias}",\n`),e.virtual&&(m+=" virtual: true,\n"),e.typeScriptStyle&&(m+=" typeScriptStyle: true,\n"),m+=` type: "${e.type}",\n`,m+=` attribute: "_${e.attribute}"\n`,m+=" }"}),m+="\n",m+=" };\n",m+="\n",m+=" static getClassName(): string {\n",m+=` return "${r}";\n`,m+=" }\n",m+="\n",m+=" static getTableName(): string {\n",m+=` return "${t.name}";\n`,m+=" }\n",m+="\n",m+=" static getPrimaryKey(): string {\n",m+=` return "${d}";\n`,m+=" }\n",m+="\n",m+=` static from(other: ${r} | ${r}Data): ${r} {\n`,m+=` let value: ${r} = null;\n`,m+=" if (other) {\n",m+=` value = new ${r}();\n`,m+=` if (other instanceof ${r}) {\n`,m+=" Object.assign(value, other);\n",m+=" } else {\n",m+=" value.assign(other);\n",m+=" }\n",m+=" }\n",m+=" return value;\n",m+=" }\n",m+="\n",m+=` constructor(data?: ${r} | ${r}Data) {\n`,m+=" super();\n",m+=" if (data) {\n",m+=" this.assign(data);\n",m+=" }\n",m+=" }\n",m+="\n",m+=` public clone(): ${r} {\n`,m+=` return ${r}.from(this);\n`,m+=" }\n",m+="\n",m+=" public getClassName(): string {\n",m+=` return "${r}";\n`,m+=" }\n",m+="\n",m+=" public getTableName(): string {\n",m+=` return "${t.name}";\n`,m+=" }\n",m+="\n",m+=" public getPrimaryKey(): string {\n",m+=` return "${d}";\n`,m+=" }\n",m+="\n",m+=" public getAttributeMap(): ModelAttributeMap {\n",m+=` return ${r}.attributeMap;\n`,m+=" }\n",a.forEach(e=>{let t;m+="\n",t=e.name.length<3||e.name.match(/_/)?"FunctionNamingConventionJS":"",""!==t&&(m+=` // noinspection ${t}\n`),m+=` get ${e.name}(): ${e.type} {\n`,m+=` return this._${e.attribute};\n`,m+=" }\n\n",""!==t&&(m+=` // noinspection ${t}\n`),m+=` set ${e.name}(${e.attribute}: ${e.type}) {\n`,m+=` this._${e.attribute} = ${e.attribute};\n`,m+=" }\n"}),"user"==t.name&&(m+="\n",m+=" get hash(): string {\n",m+=" return this._hash;\n",m+=" }\n\n",m+=" set hash(hash: string) {\n",m+=" this._hash = hash;\n",m+=" }\n",m+="\n",m+=" get privileges(): string[] {\n",m+=" return this._privileges;\n",m+=" }\n\n",m+=" set privileges(p: string[]) {\n",m+=" this._privileges = p;\n",m+=" }\n"),m+="}\n",e.separateApi?(l=i+"\n"+c+"\n"+l,fs.writeFileSync(`${e.modelDirectory}/${b+"-api.ts"}`,l),m=i+"\n"+p+"\n"+m):m=i+"\n"+p+"\n"+l+"\n"+m,fs.writeFileSync(`${e.modelDirectory}/${b+".ts"}`,m)}else console.log("error: table has no fields")}).catch(e=>{console.error(e),process.abort()})}});let a=`import {AbstractModel} from "${e.abstractModelModule}";\n`;_.forEach(n,e=>{a+=`import {${e}} from "./${_.kebabCase(e)}";\n`}),a+="\n",a+="interface SmartDbDictionaryEntry {\n",a+=" cls: "+n.map(e=>"typeof "+e).join(" |\n "),a+=";\n",a+="}\n\n",a+="export class SmartDbDictionary {\n",a+=" static models: { [relation: string]: SmartDbDictionaryEntry; } = {\n",_.forEach(n,e=>{a+=` ${e}: {\n`,a+=` cls: ${e}\n`,a+=" },\n"}),a=a.substring(0,a.length-2)+"\n",a+=" };\n",a+="}\n",fs.writeFileSync(e.modelDirectory+"/smart-db-dictionary.ts",a)}e.db.closeSync()}(()=>{let e=!1;const t=Array.from(process.argv);if("--separate-api"==t[2]&&(e=!0,t.splice(2,1)),4==t.length){extractDbApi({modelDirectory:t[3],smartDbInterfaces:"@egi/smart-db",abstractModelModule:"@egi/smart-db",separateApi:e,db:new SmartDbBetterSqlite3(t[2],{verbose:(e,...t)=>{console.log("DB LOG",e,...t)}})})}else if(2==t.length&&fs.existsSync("src/helpers/extract-db-api.ts")){const t=`/tmp/smart-db-core.${process.pid}.sqlite3`,r={includeCoreTables:!0,modelDirectory:"src/models",smartDbInterfaces:"../smart-db-interfaces",abstractModelModule:"./abstract-model",separateApi:e,db:new SmartDbBetterSqlite3(t,{verbose:(e,...t)=>{console.log("DB LOG",e,...t)}})};r.db.initDb({module:"smart-db-core",sqlFilesDirectory:"assets/sqlite3"}).then(()=>{extractDbApi(r),fs.unlinkSync(t),r.db.closeSync()})}else console.log("usage: extract-db-api {db-connector|path-to-db} {target-models-directory}")})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@egi/smart-db",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.6",
|
|
4
4
|
"description": "Unified Smart DB Access",
|
|
5
5
|
"author": "Marcel Egloff",
|
|
6
6
|
"type": "module",
|
|
@@ -59,21 +59,21 @@
|
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"lodash": "^4.17.21",
|
|
62
|
-
"sqlite3": "^5.
|
|
62
|
+
"sqlite3": "^5.1.4"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@types/better-sqlite3": "^
|
|
66
|
-
"@types/glob": "^
|
|
67
|
-
"@types/lodash": "^4.14.
|
|
65
|
+
"@types/better-sqlite3": "^7.6.3",
|
|
66
|
+
"@types/glob": "^8.0.1",
|
|
67
|
+
"@types/lodash": "^4.14.191",
|
|
68
68
|
"@types/mysql": "^2.15.18",
|
|
69
|
-
"@types/node": "^
|
|
69
|
+
"@types/node": "^18.11.18",
|
|
70
70
|
"@types/sqlite3": "^3.1.7",
|
|
71
|
-
"@types/uglify-js": "^3.
|
|
72
|
-
"glob": "^
|
|
73
|
-
"mocha": "^
|
|
71
|
+
"@types/uglify-js": "^3.17.1",
|
|
72
|
+
"glob": "^8.1.0",
|
|
73
|
+
"mocha": "^10.2.0",
|
|
74
74
|
"npm-run-all": "^4.1.5",
|
|
75
|
-
"terser": "^
|
|
76
|
-
"uglify-js": "^3.
|
|
75
|
+
"terser": "^5.16.1",
|
|
76
|
+
"uglify-js": "^3.17.4"
|
|
77
77
|
},
|
|
78
78
|
"optionalDependencies": {
|
|
79
79
|
"better-sqlite3": "^7.1.0",
|
package/smart-db-log.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import _ from"lodash";import{SmartDbLogModel}from"./models/smart-db-log-model";import{SmartDbDateRegexp,SmartDbTimestampRegexp,toSmartDbTimestamp}from"./smart-db-globals";export const SmartDbLogLocation={Frontend:"frontend",Backend:"backend",Database:"database",UpgradeManager:"upgrade-manager",Other:"other"};export const SeverityCode={Fatal:"F",Error:"E",Warning:"W",Info:"I",Debug:"D",Local:"L"};export const SeverityLevel={None:0,Fatal:1,Error:2,Warning:3,Info:4,Debug:5,All:9};export class SmartDbLog{constructor(e){this.userId=null,this.dbLogging=!0,this.isLogging=!1,this.db=e,this.dbLogLevel=SeverityLevel.Info,this.consoleLogLevel=SeverityLevel.Info}getConsoleLogLevel(){return this.consoleLogLevel}setConsoleLogLevel(e){this.consoleLogLevel=e}getDbLogLevel(){return this.dbLogLevel}setDbLogLevel(e){this.dbLogLevel=e}setDb(e){this.db=e,this.db?this.db.exists(SmartDbLogModel).then(e=>{this.dbLogging=e}).catch(e=>{throw e}):this.dbLogging=!1}setUserId(e){this.userId=e}setDbLogging(e){this.dbLogging=e}getDbLogging(){return this.dbLogging}logFatal(e,t,o,r){this.writeLog(e,t,SeverityCode.Fatal,o,r)}logError(e,t,o,r){this.writeLog(e,t,SeverityCode.Error,o,r)}logWarning(e,t,o,r){this.writeLog(e,t,SeverityCode.Warning,o,r)}logInfo(e,t,o,r){this.writeLog(e,t,SeverityCode.Info,o,r)}logDebug(e,t,o,r){this.writeLog(e,t,SeverityCode.Debug,o,r)}writeLog(e,t,o,r,i,s){try{if(this.isLogging)console.error("recursive logging error:",e,t,o,r,i);else{this.isLogging=!0;let a,g,n=SeverityLevel.None;switch(o){case SeverityCode.Fatal:a=console.error,n=SeverityLevel.Fatal;break;case SeverityCode.Error:a=console.error,n=SeverityLevel.Error;break;case SeverityCode.Warning:a=console.warn,n=SeverityLevel.Warning;break;case SeverityCode.Info:a=console.info,n=SeverityLevel.Info;break;case SeverityCode.Debug:a=console.debug,n=SeverityLevel.Debug}if(_.isString(s)){const e=s.match(SmartDbTimestampRegexp),t=e&&s.match(SmartDbDateRegexp);g=e?e[1]:t?t[1]+".000":toSmartDbTimestamp(new Date)}else g=_.isDate(s)?toSmartDbTimestamp(s):_.isNumber(s)?toSmartDbTimestamp(new Date(s)):toSmartDbTimestamp(new Date);if(_.isObjectLike(r))if(r instanceof Error)i||(i=r),r=r.message;else try{r=JSON.stringify(r)}catch(e){r=r.toString()}else"boolean"==typeof r&&(r=r?"<true>":"<false>");if(i){if(i instanceof Error)i=i.stack;else if(_.isObject(i))try{i=JSON.stringify(i)}catch(e){i=i.toString(),this.db&&this.dbLogLevel>=n&&console.error("unable to stringify log data",i)}else i.toString?i=i.toString():(i=null,this.db&&this.dbLogLevel>=n&&console.error("unable to store log data",i));i&&(r+=` (${i})`)}if(this.consoleLogLevel>=n){const s=e.
|
|
1
|
+
import _ from"lodash";import{SmartDbLogModel}from"./models/smart-db-log-model";import{SmartDbDateRegexp,SmartDbTimestampRegexp,toSmartDbTimestamp}from"./smart-db-globals";export const SmartDbLogLocation={Frontend:"frontend",Backend:"backend",Database:"database",UpgradeManager:"upgrade-manager",Other:"other"};export const SeverityCode={Fatal:"F",Error:"E",Warning:"W",Info:"I",Debug:"D",Local:"L"};export const SeverityLevel={None:0,Fatal:1,Error:2,Warning:3,Info:4,Debug:5,All:9};export class SmartDbLog{constructor(e){this.userId=null,this.dbLogging=!0,this.isLogging=!1,this.db=e,this.dbLogLevel=SeverityLevel.Info,this.consoleLogLevel=SeverityLevel.Info}getConsoleLogLevel(){return this.consoleLogLevel}setConsoleLogLevel(e){this.consoleLogLevel=e}getDbLogLevel(){return this.dbLogLevel}setDbLogLevel(e){this.dbLogLevel=e}setDb(e){this.db=e,this.db?this.db.exists(SmartDbLogModel).then(e=>{this.dbLogging=e}).catch(e=>{throw e}):this.dbLogging=!1}setUserId(e){this.userId=e}setDbLogging(e){this.dbLogging=e}getDbLogging(){return this.dbLogging}logFatal(e,t,o,r){this.writeLog(e,t,SeverityCode.Fatal,o,r)}logError(e,t,o,r){this.writeLog(e,t,SeverityCode.Error,o,r)}logWarning(e,t,o,r){this.writeLog(e,t,SeverityCode.Warning,o,r)}logInfo(e,t,o,r){this.writeLog(e,t,SeverityCode.Info,o,r)}logDebug(e,t,o,r){this.writeLog(e,t,SeverityCode.Debug,o,r)}writeLog(e,t,o,r,i,s){try{if(this.isLogging)console.error("recursive logging error:",e,t,o,r,i);else{this.isLogging=!0;let a,g,n=SeverityLevel.None;switch(o){case SeverityCode.Fatal:a=console.error,n=SeverityLevel.Fatal;break;case SeverityCode.Error:a=console.error,n=SeverityLevel.Error;break;case SeverityCode.Warning:a=console.warn,n=SeverityLevel.Warning;break;case SeverityCode.Info:a=console.info,n=SeverityLevel.Info;break;case SeverityCode.Debug:a=console.debug,n=SeverityLevel.Debug}if(_.isString(s)){const e=s.match(SmartDbTimestampRegexp),t=e&&s.match(SmartDbDateRegexp);g=e?e[1]:t?t[1]+".000":toSmartDbTimestamp(new Date)}else g=_.isDate(s)?toSmartDbTimestamp(s):_.isNumber(s)?toSmartDbTimestamp(new Date(s)):toSmartDbTimestamp(new Date);if(_.isObjectLike(r))if(r instanceof Error)i||(i=r),r=r.message;else try{r=JSON.stringify(r)}catch(e){r=r.toString()}else"boolean"==typeof r&&(r=r?"<true>":"<false>");if(i){if(i instanceof Error)i=i.stack;else if(_.isObject(i))try{i=JSON.stringify(i)}catch(e){i=i.toString(),this.db&&this.dbLogLevel>=n&&console.error("unable to stringify log data",i)}else i.toString?i=i.toString():(i=null,this.db&&this.dbLogLevel>=n&&console.error("unable to store log data",i));i&&(r+=` (${i})`)}if(this.consoleLogLevel>=n){const s=e.substring(0,1).toUpperCase();if(e==SmartDbLogLocation.Database&&this.db&&a(`${o}-${s}-${g}: last statement:`,this.db.getLastBuildData()),a(`${o}-${s}-${g}: ${r}`),this.dbLogging)try{e==SmartDbLogLocation.Database&&(i||(i=JSON.stringify(this.db.getLastBuildData()))),this.db.insertSync(SmartDbLogModel,{severity:o,type:e,location:t,info:r||"<empty>",data:i,user:this.userId,timestamp:new Date(g)})}catch(e){console.error(`F-B-${g}: unable to write the log statement below to database`,e,e.code,e.name,e.message);try{a(`F-B-${g}: last statement:`,this.db.getLastBuildData())}catch{a(`F-B-${g}: last statement not available`)}}}}this.isLogging=!1}catch(e){this.isLogging=!1,console.error("fatal logging error",e)}}}export const smartDbLog=new SmartDbLog;
|