118 lines
2.9 KiB
TypeScript
118 lines
2.9 KiB
TypeScript
|
import _ from 'lodash';
|
||
|
import PouchDB from 'pouchdb';
|
||
|
import PouchDBFind from 'pouchdb-find';
|
||
|
import uri from '../lib/ids';
|
||
|
|
||
|
PouchDB.plugin(PouchDBFind);
|
||
|
|
||
|
const dbDefinitionId = uri('dbdef', {});
|
||
|
|
||
|
const currentDbDefinition = {
|
||
|
_id: dbDefinitionId,
|
||
|
type: dbDefinitionId,
|
||
|
def: { version: '0.000001' },
|
||
|
};
|
||
|
|
||
|
declare global {
|
||
|
var db: any;
|
||
|
var dbReady: boolean;
|
||
|
}
|
||
|
|
||
|
export const initDb = async (params: any) => {
|
||
|
if (globalThis.db === undefined) {
|
||
|
globalThis.db = new PouchDB('dyomedea', {
|
||
|
auto_compaction: true,
|
||
|
revs_limit: 10,
|
||
|
});
|
||
|
}
|
||
|
const db = globalThis.db;
|
||
|
var previousDbDefinition = {
|
||
|
_id: dbDefinitionId,
|
||
|
type: dbDefinitionId,
|
||
|
def: { version: '0' },
|
||
|
};
|
||
|
try {
|
||
|
previousDbDefinition = await db.get(dbDefinitionId);
|
||
|
} catch (error: any) {
|
||
|
if (error.status !== 404) {
|
||
|
console.log(
|
||
|
`Unexpected error fetching db definition: ${JSON.stringify(error)}`
|
||
|
);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (previousDbDefinition.def.version < currentDbDefinition.def.version) {
|
||
|
previousDbDefinition.def = currentDbDefinition.def;
|
||
|
db.put(previousDbDefinition);
|
||
|
// TODO: support migrations
|
||
|
}
|
||
|
await await db.compact();
|
||
|
await db.viewCleanup();
|
||
|
|
||
|
// WARNING: defs must use the canonical form and be identical to what will be returned by db.getIndexes
|
||
|
const requiredIndexes: any = [
|
||
|
{
|
||
|
name: 'type',
|
||
|
def: {
|
||
|
fields: [{ type: 'asc' }],
|
||
|
},
|
||
|
},
|
||
|
];
|
||
|
|
||
|
const existingIndexes = (await db.getIndexes()).indexes;
|
||
|
|
||
|
const pruneIndex = ({ name, def }: any) => ({ name, def });
|
||
|
|
||
|
const isSameIndex = (idx1: any, idx2: any) => {
|
||
|
return _.isEqual(pruneIndex(idx1), pruneIndex(idx2));
|
||
|
};
|
||
|
|
||
|
const findIndex = (targetIndexes: any, index: any) =>
|
||
|
targetIndexes.find((targetIndex: any) => {
|
||
|
return isSameIndex(targetIndex, index);
|
||
|
});
|
||
|
|
||
|
for (var index of existingIndexes) {
|
||
|
if (index.type === 'json') {
|
||
|
// Non system indexes
|
||
|
// console.log(`Checking existing index :${JSON.stringify(index)}`);
|
||
|
if (!findIndex(requiredIndexes, index)) {
|
||
|
// console.log(`db.deleteIndex(${JSON.stringify(index)})`);
|
||
|
await db.deleteIndex(index);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (index of requiredIndexes) {
|
||
|
if (!findIndex(existingIndexes, index)) {
|
||
|
// console.log(`db.createIndex(${JSON.stringify(index)})`);
|
||
|
await db.createIndex({ name: index.name, ...index.def });
|
||
|
}
|
||
|
}
|
||
|
|
||
|
globalThis.dbReady = true;
|
||
|
|
||
|
/* const indexes = await db.getIndexes();
|
||
|
console.log(`indexes: ${JSON.stringify(indexes)}`);
|
||
|
|
||
|
const explain1 = await db.explain({
|
||
|
selector: {
|
||
|
type: 'trkpt',
|
||
|
gpx: 'xxxx',
|
||
|
},
|
||
|
// sort: ['trkpt.time'],
|
||
|
// use_index: 'type-trkpt-gpx-time',
|
||
|
});
|
||
|
console.log(`explain1: ${JSON.stringify(explain1)}`);
|
||
|
const explain2 = await db.explain({
|
||
|
selector: {
|
||
|
type: 'gpx',
|
||
|
},
|
||
|
// sort: ['trkpt.time'],
|
||
|
// use_index: 'type-trkpt-gpx-time',
|
||
|
});
|
||
|
console.log(`explain2: ${JSON.stringify(explain2)}`);
|
||
|
*/
|
||
|
};
|