PouchDB init
This commit is contained in:
parent
45ab894622
commit
84e1ece691
|
@ -25,6 +25,9 @@
|
||||||
"ionicons": "^6.0.3",
|
"ionicons": "^6.0.3",
|
||||||
"jotai": "^1.8.6",
|
"jotai": "^1.8.6",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"pouchdb": "^7.3.0",
|
||||||
|
"pouchdb-browser": "^7.3.0",
|
||||||
|
"pouchdb-find": "^7.3.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-cool-dimensions": "^2.0.7",
|
"react-cool-dimensions": "^2.0.7",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
@ -33,6 +36,7 @@
|
||||||
"react-scripts": "^5.0.0",
|
"react-scripts": "^5.0.0",
|
||||||
"typedoc": "^0.23.17",
|
"typedoc": "^0.23.17",
|
||||||
"typescript": "^4.1.3",
|
"typescript": "^4.1.3",
|
||||||
|
"use-pouchdb": "^1.4.0",
|
||||||
"web-vitals": "^0.2.4",
|
"web-vitals": "^0.2.4",
|
||||||
"workbox-background-sync": "^5.1.4",
|
"workbox-background-sync": "^5.1.4",
|
||||||
"workbox-broadcast-update": "^5.1.4",
|
"workbox-broadcast-update": "^5.1.4",
|
||||||
|
@ -74,7 +78,8 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@capacitor/cli": "4.3.0",
|
"@capacitor/cli": "4.3.0",
|
||||||
"@ionic/cli": "6.20.3",
|
"@ionic/cli": "6.20.3",
|
||||||
"@types/lodash": "^4.14.186"
|
"@types/lodash": "^4.14.186",
|
||||||
|
"@types/pouchdb": "^6.4.0"
|
||||||
},
|
},
|
||||||
"description": "An Ionic project"
|
"description": "An Ionic project"
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,10 @@ import { geoPoint } from './components/map/types';
|
||||||
import Back from './components/buttons/Back';
|
import Back from './components/buttons/Back';
|
||||||
import Forward from './components/buttons/Forward';
|
import Forward from './components/buttons/Forward';
|
||||||
import CurrentLocation from './components/map/CurrentLocation';
|
import CurrentLocation from './components/map/CurrentLocation';
|
||||||
|
import { initDb } from './db';
|
||||||
|
import PouchDB from 'pouchdb';
|
||||||
|
import PouchDBFind from 'pouchdb-find';
|
||||||
|
PouchDB.plugin(PouchDBFind);
|
||||||
|
|
||||||
setupIonicReact();
|
setupIonicReact();
|
||||||
|
|
||||||
|
@ -83,6 +87,10 @@ export const setCenterAtom = atom(null, (get, set, center: geoPoint) => {
|
||||||
};
|
};
|
||||||
set(scopeAtom, newScope);
|
set(scopeAtom, newScope);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const db = new PouchDB('dyomedea', { auto_compaction: true, revs_limit: 10 });
|
||||||
|
initDb(db);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @returns The root app component
|
* @returns The root app component
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
import _ from 'lodash';
|
||||||
|
import uri from '../lib/ids';
|
||||||
|
|
||||||
|
const dbDefinitionId = uri('dbdef', {});
|
||||||
|
|
||||||
|
const currentDbDefinition = {
|
||||||
|
_id: dbDefinitionId,
|
||||||
|
type: dbDefinitionId,
|
||||||
|
def: { version: '0.000001' },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const initDb = async (db: any, setDbReady?: any) => {
|
||||||
|
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-subtype',
|
||||||
|
def: {
|
||||||
|
fields: [{ type: 'asc' }, { subtype: 'asc' }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'type-trkpt-gpx-time',
|
||||||
|
def: {
|
||||||
|
fields: [{ type: 'asc' }, { gpx: 'asc' }, { 'trkpt.time': '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 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setDbReady !== undefined) setDbReady(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)}`);
|
||||||
|
*/
|
||||||
|
};
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { route } from 'docuri';
|
||||||
|
|
||||||
|
const routes = {
|
||||||
|
dbdef: route('dbdef'),
|
||||||
|
settings: route('settings'),
|
||||||
|
gpx: route('gpx/:gpx'),
|
||||||
|
trk: route('gpx/:gpx/trk/:trk'),
|
||||||
|
trkseg: route('gpx/:gpx/trk/:trk/:trkseg'),
|
||||||
|
trkpt: route('gpx/:gpx/trk/:trk/:trkseg/:trkpt'),
|
||||||
|
wpt: route('gpx/:gpx/wpt/:wpt'),
|
||||||
|
rte: route('gpx/:gpx/rte/:rte'),
|
||||||
|
rtept: route('gpx/:gpx/rte/:rte/:rtept'),
|
||||||
|
};
|
||||||
|
|
||||||
|
type RouteKey = keyof typeof routes;
|
||||||
|
|
||||||
|
const uri = (type: RouteKey, param: any) => {
|
||||||
|
return routes[type](param);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default uri;
|
Loading…
Reference in New Issue