You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
5.3 KiB
149 lines
5.3 KiB
4 years ago
|
import { getDbQueryWrapper, dbCollection, DBType } from '../data_layer';
|
||
|
import * as config from '../../config';
|
||
6 years ago
|
|
||
|
import * as nedb from 'nedb';
|
||
|
import * as fs from 'fs';
|
||
5 years ago
|
import * as mongodb from 'mongodb';
|
||
|
import * as deasync from 'deasync';
|
||
6 years ago
|
|
||
|
|
||
5 years ago
|
export enum Collection {
|
||
|
ANALYTIC_UNITS,
|
||
|
ANALYTIC_UNIT_CACHES,
|
||
|
SEGMENTS,
|
||
|
THRESHOLD,
|
||
5 years ago
|
DETECTION_SPANS,
|
||
|
DB_META
|
||
5 years ago
|
};
|
||
6 years ago
|
|
||
5 years ago
|
const COLLECTION_TO_NAME_MAPPING = new Map<Collection, string>([
|
||
|
[Collection.ANALYTIC_UNITS, 'analytic_units'],
|
||
|
[Collection.ANALYTIC_UNIT_CACHES, 'analytic_unit_caches'],
|
||
|
[Collection.SEGMENTS, 'segments'],
|
||
|
[Collection.THRESHOLD, 'threshold'],
|
||
|
[Collection.DETECTION_SPANS, 'detection_spans'],
|
||
|
[Collection.DB_META, 'db_meta']
|
||
5 years ago
|
]);
|
||
5 years ago
|
|
||
5 years ago
|
export enum SortingOrder { ASCENDING = 1, DESCENDING = -1 };
|
||
6 years ago
|
|
||
|
/**
|
||
|
* Class which helps to make queries to your collection
|
||
6 years ago
|
*
|
||
6 years ago
|
* @param { string | object } query: a key as a string or mongodb-style query
|
||
|
*/
|
||
|
export type DBQ = {
|
||
6 years ago
|
findOne: (query: string | object) => Promise<any | null>,
|
||
5 years ago
|
findMany: (query: string[] | object, sortQuery?: object) => Promise<any[]>,
|
||
6 years ago
|
insertOne: (document: object) => Promise<string>,
|
||
|
insertMany: (documents: object[]) => Promise<string[]>,
|
||
5 years ago
|
updateOne: (query: string | object, updateQuery: any) => Promise<void>,
|
||
|
updateMany: (query: string[] | object, updateQuery: any) => Promise<void>,
|
||
6 years ago
|
removeOne: (query: string) => Promise<boolean>
|
||
|
removeMany: (query: string[] | object) => Promise<number>
|
||
6 years ago
|
}
|
||
|
|
||
5 years ago
|
const queryWrapper = getDbQueryWrapper();
|
||
|
const db = new Map<Collection, dbCollection>();
|
||
|
let mongoClient: mongodb.MongoClient;
|
||
|
|
||
|
function dbCollectionFromCollection(collection: Collection): dbCollection {
|
||
5 years ago
|
let dbCollection = db.get(collection);
|
||
|
if(dbCollection === undefined) {
|
||
5 years ago
|
throw new Error('Can`t find collection ' + collection);
|
||
|
}
|
||
5 years ago
|
return dbCollection;
|
||
5 years ago
|
}
|
||
|
|
||
6 years ago
|
export function makeDBQ(collection: Collection): DBQ {
|
||
|
return {
|
||
5 years ago
|
findOne: queryWrapper.dbFindOne.bind(null, dbCollectionFromCollection(collection)),
|
||
|
findMany: queryWrapper.dbFindMany.bind(null, dbCollectionFromCollection(collection)),
|
||
|
insertOne: queryWrapper.dbInsertOne.bind(null, dbCollectionFromCollection(collection)),
|
||
|
insertMany: queryWrapper.dbInsertMany.bind(null, dbCollectionFromCollection(collection)),
|
||
|
updateOne: queryWrapper.dbUpdateOne.bind(null, dbCollectionFromCollection(collection)),
|
||
|
updateMany: queryWrapper.dbUpdateMany.bind(null, dbCollectionFromCollection(collection)),
|
||
|
removeOne: queryWrapper.dbRemoveOne.bind(null, dbCollectionFromCollection(collection)),
|
||
|
removeMany: queryWrapper.dbRemoveMany.bind(null, dbCollectionFromCollection(collection))
|
||
6 years ago
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
5 years ago
|
|
||
6 years ago
|
function maybeCreateDir(path: string): void {
|
||
|
if(fs.existsSync(path)) {
|
||
|
return;
|
||
|
}
|
||
6 years ago
|
console.log('data service: mkdir: ' + path);
|
||
6 years ago
|
fs.mkdirSync(path);
|
||
|
}
|
||
|
|
||
|
function checkDataFolders(): void {
|
||
|
[
|
||
|
config.DATA_PATH,
|
||
|
config.ZMQ_IPC_PATH
|
||
|
].forEach(maybeCreateDir);
|
||
|
}
|
||
|
|
||
5 years ago
|
async function connectToDb() {
|
||
5 years ago
|
if(config.HASTIC_DB_CONNECTION_TYPE === DBType.nedb) {
|
||
5 years ago
|
checkDataFolders();
|
||
|
const inMemoryOnly = config.HASTIC_DB_IN_MEMORY;
|
||
5 years ago
|
console.log('NeDB is used as the storage');
|
||
5 years ago
|
// TODO: it's better if models request db which we create if it`s needed
|
||
|
db.set(Collection.ANALYTIC_UNITS, new nedb({ filename: config.ANALYTIC_UNITS_DATABASE_PATH, autoload: true, timestampData: true, inMemoryOnly}));
|
||
|
db.set(Collection.ANALYTIC_UNIT_CACHES, new nedb({ filename: config.ANALYTIC_UNIT_CACHES_DATABASE_PATH, autoload: true, inMemoryOnly}));
|
||
|
db.set(Collection.SEGMENTS, new nedb({ filename: config.SEGMENTS_DATABASE_PATH, autoload: true, inMemoryOnly}));
|
||
|
db.set(Collection.THRESHOLD, new nedb({ filename: config.THRESHOLD_DATABASE_PATH, autoload: true, inMemoryOnly}));
|
||
|
db.set(Collection.DETECTION_SPANS, new nedb({ filename: config.DETECTION_SPANS_DATABASE_PATH, autoload: true, inMemoryOnly}));
|
||
|
db.set(Collection.DB_META, new nedb({ filename: config.DB_META_PATH, autoload: true, inMemoryOnly}));
|
||
5 years ago
|
} else if(config.HASTIC_DB_CONNECTION_TYPE === DBType.mongodb) {
|
||
|
console.log('MongoDB is used as the storage');
|
||
5 years ago
|
const dbConfig = config.HASTIC_DB_CONFIG;
|
||
|
const uri = `mongodb://${dbConfig.user}:${dbConfig.password}@${dbConfig.url}`;
|
||
|
const auth = {
|
||
|
user: dbConfig.user,
|
||
|
password: dbConfig.password
|
||
|
};
|
||
|
mongoClient = new mongodb.MongoClient(uri, {
|
||
|
useNewUrlParser: true,
|
||
|
auth,
|
||
|
autoReconnect: true,
|
||
|
useUnifiedTopology: true,
|
||
|
authMechanism: 'SCRAM-SHA-1',
|
||
5 years ago
|
authSource: dbConfig.dbName
|
||
5 years ago
|
});
|
||
|
try {
|
||
|
const client: mongodb.MongoClient = await mongoClient.connect();
|
||
5 years ago
|
const hasticDb: mongodb.Db = client.db(dbConfig.dbName);
|
||
5 years ago
|
COLLECTION_TO_NAME_MAPPING.forEach((name, collection) => {
|
||
|
db.set(collection, hasticDb.collection(name));
|
||
|
});
|
||
|
} catch(err) {
|
||
|
console.log(`got error while connect to MongoDB ${err}`);
|
||
|
throw err;
|
||
|
}
|
||
5 years ago
|
} else {
|
||
|
throw new Error(
|
||
|
`"${config.HASTIC_DB_CONNECTION_TYPE}" HASTIC_DB_CONNECTION_TYPE is not supported. Possible values: "nedb", "mongodb"`
|
||
|
);
|
||
5 years ago
|
}
|
||
|
}
|
||
|
|
||
|
export async function closeDb() {
|
||
|
if(mongoClient !== undefined && mongoClient.isConnected) {
|
||
|
await mongoClient.close();
|
||
|
}
|
||
|
}
|
||
5 years ago
|
|
||
5 years ago
|
let done = false;
|
||
|
connectToDb().then(() => {
|
||
|
done = true;
|
||
|
}).catch((err) => {
|
||
|
console.log(`data service got error while connect to data base ${err}`);
|
||
|
//TODO: choose best practice for error handling
|
||
|
throw err;
|
||
|
});
|
||
|
deasync.loopWhile(() => !done);
|