Skip to content
This repository was archived by the owner on Jun 24, 2025. It is now read-only.

Commit 1031906

Browse files
committed
Add '_regroup/trilium-db-compare/' from commit '22d59127f91a588dc5ce9555b7551e428df6a97a'
git-subtree-dir: _regroup/trilium-db-compare git-subtree-mainline: 3e99273 git-subtree-split: 22d5912
2 parents 3e99273 + 22d5912 commit 1031906

5 files changed

Lines changed: 2383 additions & 0 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
8+
# Runtime data
9+
pids
10+
*.pid
11+
*.seed
12+
*.pid.lock
13+
14+
# Directory for instrumented libs generated by jscoverage/JSCover
15+
lib-cov
16+
17+
# Coverage directory used by tools like istanbul
18+
coverage
19+
20+
# nyc test coverage
21+
.nyc_output
22+
23+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24+
.grunt
25+
26+
# Bower dependency directory (https://bower.io/)
27+
bower_components
28+
29+
# node-waf configuration
30+
.lock-wscript
31+
32+
# Compiled binary addons (http://nodejs.org/api/addons.html)
33+
build/Release
34+
35+
# Dependency directories
36+
node_modules/
37+
jspm_packages/
38+
39+
# Typescript v1 declaration files
40+
typings/
41+
42+
# Optional npm cache directory
43+
.npm
44+
45+
# Optional eslint cache
46+
.eslintcache
47+
48+
# Optional REPL history
49+
.node_repl_history
50+
51+
# Output of 'npm pack'
52+
*.tgz
53+
54+
# Yarn Integrity file
55+
.yarn-integrity
56+
57+
# dotenv environment variables file
58+
.env
59+
60+
.idea
61+
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
"use strict";
2+
3+
require('colors');
4+
const jsDiff = require('diff');
5+
const sqlite = require('sqlite');
6+
const sqlite3 = require('sqlite3');
7+
const sql = require('./sql');
8+
9+
function printDiff(one, two) {
10+
const diff = jsDiff.diffChars(one, two);
11+
12+
diff.forEach(function(part){
13+
// green for additions, red for deletions
14+
// grey for common parts
15+
const color = part.added ? 'green' :
16+
part.removed ? 'red' : 'grey';
17+
process.stderr.write(part.value[color]);
18+
});
19+
20+
console.log("");
21+
}
22+
23+
function checkMissing(table, name, ids1, ids2) {
24+
const missing = ids1.filter(item => ids2.indexOf(item) < 0);
25+
26+
if (missing.length > 0) {
27+
console.log("Missing IDs from " + name + " table " + table + ": ", missing);
28+
}
29+
}
30+
31+
function handleBuffer(obj) {
32+
if (obj && Buffer.isBuffer(obj.content)) {
33+
obj.content = obj.content.toString();
34+
}
35+
36+
return obj;
37+
}
38+
39+
function compareRows(table, rsLeft, rsRight, column) {
40+
const leftIds = Object.keys(rsLeft);
41+
const rightIds = Object.keys(rsRight);
42+
43+
console.log("");
44+
console.log("--------------------------------------------------------");
45+
console.log(`${table} - ${leftIds.length}/${rightIds.length}`);
46+
47+
checkMissing(table, "right", leftIds, rightIds);
48+
checkMissing(table, "left", rightIds, leftIds);
49+
50+
const commonIds = leftIds.filter(item => rightIds.includes(item));
51+
52+
for (const id of commonIds) {
53+
const valueLeft = handleBuffer(rsLeft[id]);
54+
const valueRight = handleBuffer(rsRight[id]);
55+
56+
const left = JSON.stringify(valueLeft, null, 2);
57+
const right = JSON.stringify(valueRight, null, 2);
58+
59+
if (left !== right) {
60+
console.log("Table " + table + " row with " + column + "=" + id + " differs:");
61+
console.log("Left: ", left);
62+
console.log("Right: ", right);
63+
printDiff(left, right);
64+
}
65+
}
66+
}
67+
68+
async function main() {
69+
const dbLeftPath = process.argv[2];
70+
const dbRightPath = process.argv[3];
71+
72+
const dbLeft = await sqlite.open({filename: dbLeftPath, driver: sqlite3.Database});
73+
const dbRight = await sqlite.open({filename: dbRightPath, driver: sqlite3.Database});
74+
75+
async function compare(table, column, query) {
76+
const rsLeft = await sql.getIndexed(dbLeft, column, query);
77+
const rsRight = await sql.getIndexed(dbRight, column, query);
78+
79+
compareRows(table, rsLeft, rsRight, column);
80+
}
81+
82+
await compare("branches", "branchId",
83+
"SELECT branchId, noteId, parentNoteId, notePosition, utcDateCreated, isDeleted, prefix FROM branches");
84+
85+
await compare("notes", "noteId",
86+
"SELECT noteId, title, dateCreated, utcDateCreated, isProtected, isDeleted FROM notes WHERE isDeleted = 0");
87+
88+
await compare("note_contents", "noteId",
89+
"SELECT note_contents.noteId, note_contents.content FROM note_contents JOIN notes USING(noteId) WHERE isDeleted = 0");
90+
91+
await compare("note_revisions", "noteRevisionId",
92+
"SELECT noteRevisionId, noteId, title, dateCreated, dateLastEdited, utcDateCreated, utcDateLastEdited, isProtected FROM note_revisions");
93+
94+
await compare("note_revision_contents", "noteRevisionId",
95+
"SELECT noteRevisionId, content FROM note_revision_contents");
96+
97+
await compare("options", "name",
98+
`SELECT name, value, utcDateCreated FROM options WHERE isSynced = 1`);
99+
100+
await compare("attributes", "attributeId",
101+
"SELECT attributeId, noteId, type, name, value FROM attributes");
102+
103+
await compare("api_tokens", "apiTokenId",
104+
"SELECT apiTokenId, token, utcDateCreated, isDeleted FROM api_tokens");
105+
106+
await compare("entity_changes", "uniqueId",
107+
"SELECT entityName || '-' || entityId AS uniqueId, hash, isErased, utcDateChanged FROM entity_changes WHERE isSynced = 1");
108+
}
109+
110+
(async () => {
111+
try {
112+
await main();
113+
} catch (e) {
114+
console.error(e);
115+
}
116+
})();

0 commit comments

Comments
 (0)