chore(db-compare): port to TypeScript

This commit is contained in:
Elian Doran 2025-05-03 03:50:06 +03:00
parent 4b38eda827
commit 7b25592cc5
No known key found for this signature in database
6 changed files with 223 additions and 36 deletions

160
apps/db-compare/package-lock.json generated Normal file
View File

@ -0,0 +1,160 @@
{
"name": "@triliumnext/db-compare",
"version": "0.0.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@triliumnext/db-compare",
"version": "0.0.1",
"dependencies": {
"colors": "1.4.0",
"diff": "5.0.0",
"sqlite": "4.0.23",
"sqlite3": "5.0.2"
},
"devDependencies": {
"@types/diff": "^7.0.2"
}
},
"../../node_modules/.pnpm/colors@1.4.0/node_modules/colors": {
"version": "1.4.0",
"license": "MIT",
"devDependencies": {
"eslint": "^5.2.0",
"eslint-config-google": "^0.11.0"
},
"engines": {
"node": ">=0.1.90"
}
},
"../../node_modules/.pnpm/diff@5.0.0/node_modules/diff": {
"version": "5.0.0",
"license": "BSD-3-Clause",
"devDependencies": {
"@babel/cli": "^7.2.3",
"@babel/core": "^7.2.2",
"@babel/plugin-transform-modules-commonjs": "^7.2.0",
"@babel/preset-env": "^7.2.3",
"@babel/register": "^7.0.0",
"babel-eslint": "^10.0.1",
"babel-loader": "^8.0.5",
"chai": "^4.2.0",
"colors": "^1.3.3",
"eslint": "^5.12.0",
"grunt": "^1.0.3",
"grunt-babel": "^8.0.0",
"grunt-cli": "^1.3.2",
"grunt-contrib-clean": "^2.0.0",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-uglify": "^5.0.0",
"grunt-contrib-watch": "^1.1.0",
"grunt-eslint": "^23.0.0",
"grunt-exec": "^3.0.0",
"grunt-karma": "^4.0.0",
"grunt-mocha-istanbul": "^5.0.2",
"grunt-mocha-test": "^0.13.3",
"grunt-webpack": "^3.1.3",
"istanbul": "github:kpdecker/istanbul",
"karma": "^5.1.1",
"karma-chrome-launcher": "^3.1.0",
"karma-mocha": "^2.0.1",
"karma-mocha-reporter": "^2.0.0",
"karma-sauce-launcher": "^4.1.5",
"karma-sourcemap-loader": "^0.3.6",
"karma-webpack": "^4.0.2",
"mocha": "^6.0.0",
"rollup": "^1.0.2",
"rollup-plugin-babel": "^4.2.0",
"semver": "^7.3.2",
"webpack": "^4.28.3",
"webpack-dev-server": "^3.1.14"
},
"engines": {
"node": ">=0.3.1"
}
},
"../../node_modules/.pnpm/sqlite@4.0.23/node_modules/sqlite": {
"version": "4.0.23",
"license": "MIT",
"devDependencies": {
"@theo.gravity/changelog-version": "2.1.10",
"@theo.gravity/version-bump": "2.0.12",
"@types/jest": "26.0.22",
"@types/node": "^14.14.37",
"@types/sqlite3": "^3.1.7",
"@typescript-eslint/eslint-plugin": "^4.20.0",
"@typescript-eslint/parser": "^4.20.0",
"eslint": "7.23.0",
"git-commit-stamper": "^1.0.9",
"jest": "26.6.3",
"jest-cli": "26.6.3",
"jest-junit-reporter": "1.1.0",
"lint-staged": "10.5.4",
"pre-commit": "1.2.2",
"prettier-standard": "16.4.1",
"sql-template-strings": "^2.2.2",
"sqlite3": "^5.0.2",
"sqlite3-offline": "^4.3.1",
"standardx": "^7.0.0",
"toc-md-alt": "^0.4.1",
"ts-jest": "26.5.4",
"ts-node": "9.1.1",
"ts-node-dev": "1.1.6",
"typedoc": "^0.20.34",
"typedoc-plugin-markdown": "^3.6.0",
"typescript": "4.2.3",
"version-bump-plugin-git": "^2.0.1"
}
},
"../../node_modules/.pnpm/sqlite3@5.0.2/node_modules/sqlite3": {
"version": "5.0.2",
"hasInstallScript": true,
"license": "BSD-3-Clause",
"dependencies": {
"node-addon-api": "^3.0.0",
"node-pre-gyp": "^0.11.0"
},
"devDependencies": {
"@mapbox/cloudfriend": "^1.9.0",
"aws-sdk": "2.x",
"eslint": "3.5.0",
"mocha": "^5.2.0"
},
"optionalDependencies": {
"node-gyp": "3.x"
},
"peerDependencies": {
"node-gyp": "3.x"
},
"peerDependenciesMeta": {
"node-gyp": {
"optional": true
}
}
},
"node_modules/@types/diff": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/@types/diff/-/diff-7.0.2.tgz",
"integrity": "sha512-JSWRMozjFKsGlEjiiKajUjIJVKuKdE3oVy2DNtK+fUo8q82nhFZ2CPQwicAIkXrofahDXrWJ7mjelvZphMS98Q==",
"dev": true,
"license": "MIT"
},
"node_modules/colors": {
"resolved": "../../node_modules/.pnpm/colors@1.4.0/node_modules/colors",
"link": true
},
"node_modules/diff": {
"resolved": "../../node_modules/.pnpm/diff@5.0.0/node_modules/diff",
"link": true
},
"node_modules/sqlite": {
"resolved": "../../node_modules/.pnpm/sqlite@4.0.23/node_modules/sqlite",
"link": true
},
"node_modules/sqlite3": {
"resolved": "../../node_modules/.pnpm/sqlite3@5.0.2/node_modules/sqlite3",
"link": true
}
}
}

View File

@ -67,5 +67,9 @@
} }
} }
} }
},
"devDependencies": {
"@types/colors": "1.2.4",
"@types/diff": "^7.0.2"
} }
} }

View File

@ -1,12 +1,13 @@
"use strict"; "use strict";
require('colors'); import jsDiff from "diff";
const jsDiff = require('diff'); import * as sqlite from "sqlite";
const sqlite = require('sqlite'); import * as sqlite3 from "sqlite3";
const sqlite3 = require('sqlite3'); import sql from "./sql.js";
const sql = require('./sql');
function printDiff(one, two) { import "colors";
function printDiff(one: string, two: string) {
const diff = jsDiff.diffChars(one, two); const diff = jsDiff.diffChars(one, two);
diff.forEach(function(part){ diff.forEach(function(part){
@ -20,7 +21,7 @@ function printDiff(one, two) {
console.log(""); console.log("");
} }
function checkMissing(table, name, ids1, ids2) { function checkMissing(table: string, name: string, ids1: string[], ids2: string[]) {
const missing = ids1.filter(item => ids2.indexOf(item) < 0); const missing = ids1.filter(item => ids2.indexOf(item) < 0);
if (missing.length > 0) { if (missing.length > 0) {
@ -28,7 +29,7 @@ function checkMissing(table, name, ids1, ids2) {
} }
} }
function handleBuffer(obj) { function handleBuffer(obj: { content: Buffer | string }) {
if (obj && Buffer.isBuffer(obj.content)) { if (obj && Buffer.isBuffer(obj.content)) {
obj.content = obj.content.toString(); obj.content = obj.content.toString();
} }
@ -36,7 +37,7 @@ function handleBuffer(obj) {
return obj; return obj;
} }
function compareRows(table, rsLeft, rsRight, column) { function compareRows(table: string, rsLeft: Record<string, any>, rsRight: Record<string, any>, column: string) {
const leftIds = Object.keys(rsLeft); const leftIds = Object.keys(rsLeft);
const rightIds = Object.keys(rsRight); const rightIds = Object.keys(rsRight);
@ -72,7 +73,7 @@ async function main() {
const dbLeft = await sqlite.open({filename: dbLeftPath, driver: sqlite3.Database}); const dbLeft = await sqlite.open({filename: dbLeftPath, driver: sqlite3.Database});
const dbRight = await sqlite.open({filename: dbRightPath, driver: sqlite3.Database}); const dbRight = await sqlite.open({filename: dbRightPath, driver: sqlite3.Database});
async function compare(table, column, query) { async function compare(table: string, column: string, query: string) {
const rsLeft = await sql.getIndexed(dbLeft, column, query); const rsLeft = await sql.getIndexed(dbLeft, column, query);
const rsRight = await sql.getIndexed(dbRight, column, query); const rsRight = await sql.getIndexed(dbRight, column, query);

View File

@ -1,16 +1,18 @@
"use strict"; "use strict";
async function getSingleResult(db, query, params = []) { import type { Database } from "sqlite";
async function getSingleResult(db: Database, query: string, params: any[] = []) {
return await wrap(db, async db => db.get(query, ...params)); return await wrap(db, async db => db.get(query, ...params));
} }
async function getSingleResultOrNull(db, query, params = []) { async function getSingleResultOrNull(db: Database, query: string, params: any[] = []) {
const all = await wrap(db, async db => db.all(query, ...params)); const all = await wrap(db, async db => db.all(query, ...params));
return all.length > 0 ? all[0] : null; return all.length > 0 ? all[0] : null;
} }
async function getSingleValue(db, query, params = []) { async function getSingleValue(db: Database, query: string, params: any[] = []) {
const row = await getSingleResultOrNull(db, query, params); const row = await getSingleResultOrNull(db, query, params);
if (!row) { if (!row) {
@ -20,14 +22,14 @@ async function getSingleValue(db, query, params = []) {
return row[Object.keys(row)[0]]; return row[Object.keys(row)[0]];
} }
async function getResults(db, query, params = []) { async function getResults(db: Database, query: string, params: any[] = []) {
return await wrap(db, async db => db.all(query, ...params)); return await wrap(db, async db => db.all(query, ...params));
} }
async function getIndexed(db, column, query, params = []) { async function getIndexed(db: Database, column: string, query: string, params: any[] = []) {
const results = await getResults(db, query, params); const results = await getResults(db, query, params);
const map = {}; const map: Record<string, any> = {};
for (const row of results) { for (const row of results) {
map[row[column]] = row; map[row[column]] = row;
@ -36,8 +38,8 @@ async function getIndexed(db, column, query, params = []) {
return map; return map;
} }
async function getMap(db, query, params = []) { async function getMap(db: Database, query: string, params: any[] = []) {
const map = {}; const map: Record<string, any> = {};
const results = await getResults(db, query, params); const results = await getResults(db, query, params);
for (const row of results) { for (const row of results) {
@ -49,7 +51,7 @@ async function getMap(db, query, params = []) {
return map; return map;
} }
async function getFlattenedResults(db, key, query, params = []) { async function getFlattenedResults(db: Database, key: string, query: string, params: any[] = []) {
const list = []; const list = [];
const result = await getResults(db, query, params); const result = await getResults(db, query, params);
@ -60,24 +62,23 @@ async function getFlattenedResults(db, key, query, params = []) {
return list; return list;
} }
async function execute(db, query, params = []) { async function execute(db: Database, query: string, params: any[] = []) {
return await wrap(db, async db => db.run(query, ...params)); return await wrap(db, async db => db.run(query, ...params));
} }
async function wrap(db, func) { async function wrap<T>(db: Database, func: (db: Database) => Promise<T>) {
const thisError = new Error(); const thisError = new Error();
try { try {
return await func(db); return await func(db);
} } catch (e: any) {
catch (e) {
console.error("Error executing query. Inner exception: " + e.stack + thisError.stack); console.error("Error executing query. Inner exception: " + e.stack + thisError.stack);
throw thisError; throw thisError;
} }
} }
module.exports = { export default {
getSingleValue, getSingleValue,
getSingleResult, getSingleResult,
getSingleResultOrNull, getSingleResultOrNull,
@ -86,4 +87,4 @@ module.exports = {
getMap, getMap,
getFlattenedResults, getFlattenedResults,
execute execute
}; };

View File

@ -6,7 +6,8 @@
"node" "node"
], ],
"rootDir": "src", "rootDir": "src",
"tsBuildInfoFile": "dist/tsconfig.app.tsbuildinfo" "tsBuildInfoFile": "dist/tsconfig.app.tsbuildinfo",
"verbatimModuleSyntax": false
}, },
"include": [ "include": [
"src/**/*.ts" "src/**/*.ts"

40
pnpm-lock.yaml generated
View File

@ -298,6 +298,13 @@ importers:
sqlite3: sqlite3:
specifier: 5.0.2 specifier: 5.0.2
version: 5.0.2 version: 5.0.2
devDependencies:
'@types/colors':
specifier: 1.2.4
version: 1.2.4
'@types/diff':
specifier: ^7.0.2
version: 7.0.2
apps/desktop: apps/desktop:
dependencies: dependencies:
@ -361,7 +368,7 @@ importers:
version: 1.0.2 version: 1.0.2
copy-webpack-plugin: copy-webpack-plugin:
specifier: 13.0.0 specifier: 13.0.0
version: 13.0.0(webpack@5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4)) version: 13.0.0(webpack@5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4(webpack@5.98.0)))
electron: electron:
specifier: 35.2.2 specifier: 35.2.2
version: 35.2.2 version: 35.2.2
@ -417,7 +424,7 @@ importers:
version: 11.0.4 version: 11.0.4
copy-webpack-plugin: copy-webpack-plugin:
specifier: 13.0.0 specifier: 13.0.0
version: 13.0.0(webpack@5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4)) version: 13.0.0(webpack@5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4(webpack@5.98.0)))
electron: electron:
specifier: 35.2.2 specifier: 35.2.2
version: 35.2.2 version: 35.2.2
@ -595,7 +602,7 @@ importers:
version: 1.4.7 version: 1.4.7
copy-webpack-plugin: copy-webpack-plugin:
specifier: 13.0.0 specifier: 13.0.0
version: 13.0.0(webpack@5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4)) version: 13.0.0(webpack@5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4(webpack@5.98.0)))
csrf-csrf: csrf-csrf:
specifier: 3.2.2 specifier: 3.2.2
version: 3.2.2 version: 3.2.2
@ -766,7 +773,7 @@ importers:
version: 1.0.1 version: 1.0.1
webpack: webpack:
specifier: 5.99.7 specifier: 5.99.7
version: 5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4) version: 5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4(webpack@5.98.0))
ws: ws:
specifier: 8.18.1 specifier: 8.18.1
version: 8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) version: 8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)
@ -3304,6 +3311,10 @@ packages:
'@types/cls-hooked@4.3.9': '@types/cls-hooked@4.3.9':
resolution: {integrity: sha512-CMtHMz6Q/dkfcHarq9nioXH8BDPP+v5xvd+N90lBQ2bdmu06UvnLDqxTKoOJzz4SzIwb/x9i4UXGAAcnUDuIvg==} resolution: {integrity: sha512-CMtHMz6Q/dkfcHarq9nioXH8BDPP+v5xvd+N90lBQ2bdmu06UvnLDqxTKoOJzz4SzIwb/x9i4UXGAAcnUDuIvg==}
'@types/colors@1.2.4':
resolution: {integrity: sha512-oSQxEVIDcYisAzWLa+wr50GSIPu8ml4PsKNJzgrDX3SmEHVBBqbaUurqsUceFauNlCRxNtENKkQm3yOe3m3nfg==}
deprecated: This is a stub types definition. colors provides its own type definitions, so you do not need this installed.
'@types/compression@1.7.5': '@types/compression@1.7.5':
resolution: {integrity: sha512-AAQvK5pxMpaT+nDvhHrsBhLSYG5yQdtkaJE1WYieSNY2mVFKAgmU4ks65rkZD5oqnGCFLyQpUr1CqI4DmUMyDg==} resolution: {integrity: sha512-AAQvK5pxMpaT+nDvhHrsBhLSYG5yQdtkaJE1WYieSNY2mVFKAgmU4ks65rkZD5oqnGCFLyQpUr1CqI4DmUMyDg==}
@ -3420,6 +3431,9 @@ packages:
'@types/debug@4.1.12': '@types/debug@4.1.12':
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
'@types/diff@7.0.2':
resolution: {integrity: sha512-JSWRMozjFKsGlEjiiKajUjIJVKuKdE3oVy2DNtK+fUo8q82nhFZ2CPQwicAIkXrofahDXrWJ7mjelvZphMS98Q==}
'@types/ejs@3.1.5': '@types/ejs@3.1.5':
resolution: {integrity: sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg==} resolution: {integrity: sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg==}
@ -14325,6 +14339,10 @@ snapshots:
dependencies: dependencies:
'@types/node': 18.16.9 '@types/node': 18.16.9
'@types/colors@1.2.4':
dependencies:
colors: 1.4.0
'@types/compression@1.7.5': '@types/compression@1.7.5':
dependencies: dependencies:
'@types/express': 4.17.21 '@types/express': 4.17.21
@ -14467,6 +14485,8 @@ snapshots:
dependencies: dependencies:
'@types/ms': 2.1.0 '@types/ms': 2.1.0
'@types/diff@7.0.2': {}
'@types/ejs@3.1.5': {} '@types/ejs@3.1.5': {}
'@types/electron-squirrel-startup@1.0.2': {} '@types/electron-squirrel-startup@1.0.2': {}
@ -16020,14 +16040,14 @@ snapshots:
serialize-javascript: 6.0.2 serialize-javascript: 6.0.2
webpack: 5.98.0(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4) webpack: 5.98.0(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4)
copy-webpack-plugin@13.0.0(webpack@5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4)): copy-webpack-plugin@13.0.0(webpack@5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4(webpack@5.98.0))):
dependencies: dependencies:
glob-parent: 6.0.2 glob-parent: 6.0.2
normalize-path: 3.0.0 normalize-path: 3.0.0
schema-utils: 4.3.2 schema-utils: 4.3.2
serialize-javascript: 6.0.2 serialize-javascript: 6.0.2
tinyglobby: 0.2.13 tinyglobby: 0.2.13
webpack: 5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4) webpack: 5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4(webpack@5.98.0))
core-js-compat@3.41.0: core-js-compat@3.41.0:
dependencies: dependencies:
@ -22070,14 +22090,14 @@ snapshots:
'@swc/core': 1.5.29(@swc/helpers@0.5.17) '@swc/core': 1.5.29(@swc/helpers@0.5.17)
esbuild: 0.25.3 esbuild: 0.25.3
terser-webpack-plugin@5.3.14(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack@5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4)): terser-webpack-plugin@5.3.14(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack@5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4(webpack@5.98.0))):
dependencies: dependencies:
'@jridgewell/trace-mapping': 0.3.25 '@jridgewell/trace-mapping': 0.3.25
jest-worker: 27.5.1 jest-worker: 27.5.1
schema-utils: 4.3.2 schema-utils: 4.3.2
serialize-javascript: 6.0.2 serialize-javascript: 6.0.2
terser: 5.39.0 terser: 5.39.0
webpack: 5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4) webpack: 5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4(webpack@5.98.0))
optionalDependencies: optionalDependencies:
'@swc/core': 1.5.29(@swc/helpers@0.5.17) '@swc/core': 1.5.29(@swc/helpers@0.5.17)
esbuild: 0.25.3 esbuild: 0.25.3
@ -22843,7 +22863,7 @@ snapshots:
- esbuild - esbuild
- uglify-js - uglify-js
webpack@5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4): webpack@5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4(webpack@5.98.0)):
dependencies: dependencies:
'@types/eslint-scope': 3.7.7 '@types/eslint-scope': 3.7.7
'@types/estree': 1.0.7 '@types/estree': 1.0.7
@ -22866,7 +22886,7 @@ snapshots:
neo-async: 2.6.2 neo-async: 2.6.2
schema-utils: 4.3.2 schema-utils: 4.3.2
tapable: 2.2.1 tapable: 2.2.1
terser-webpack-plugin: 5.3.14(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack@5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4)) terser-webpack-plugin: 5.3.14(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack@5.99.7(@swc/core@1.5.29(@swc/helpers@0.5.17))(esbuild@0.25.3)(webpack-cli@5.1.4(webpack@5.98.0)))
watchpack: 2.4.2 watchpack: 2.4.2
webpack-sources: 3.2.3 webpack-sources: 3.2.3
optionalDependencies: optionalDependencies: