diff options
author | bobzel <zzzman@gmail.com> | 2023-12-21 14:55:48 -0500 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2023-12-21 14:55:48 -0500 |
commit | 1caba64ee0f32ee8af79263cd4ef2a8bc5d5146e (patch) | |
tree | 0fa0e957d1f342fdc6ed4a4b43f5dddfddb1298a /src/server/database.ts | |
parent | 02eb7da95df283606d4275a22d9451cef371c3b5 (diff) | |
parent | 2691b951d96f2ce7652acbea9e340b61737b3b57 (diff) |
Merge branch 'moreUpgrading' into dataViz-annotations
Diffstat (limited to 'src/server/database.ts')
-rw-r--r-- | src/server/database.ts | 175 |
1 files changed, 101 insertions, 74 deletions
diff --git a/src/server/database.ts b/src/server/database.ts index 725b66836..3a087ce38 100644 --- a/src/server/database.ts +++ b/src/server/database.ts @@ -9,8 +9,12 @@ import { Transferable } from './Message'; import { Upload } from './SharedMediaTypes'; export namespace Database { - export let disconnect: Function; + + class DocSchema implements mongodb.BSON.Document { + _id!: string; + id!: string; + } const schema = 'Dash'; const port = 27017; export const url = `mongodb://localhost:${port}/${schema}`; @@ -26,7 +30,7 @@ export namespace Database { export async function tryInitializeConnection() { try { const { connection } = mongoose; - disconnect = async () => new Promise<any>(resolve => connection.close(resolve)); + disconnect = async () => new Promise<any>(resolve => connection.close().then(resolve)); if (connection.readyState === ConnectionStates.disconnected) { await new Promise<void>((resolve, reject) => { connection.on('error', reject); @@ -35,12 +39,11 @@ export namespace Database { resolve(); }); mongoose.connect(url, { - useNewUrlParser: true, - useUnifiedTopology: true, + //useNewUrlParser: true, dbName: schema, // reconnectTries: Number.MAX_VALUE, // reconnectInterval: 1000, - }); + }); }); } } catch (e) { @@ -60,11 +63,10 @@ export namespace Database { async doConnect() { console.error(`\nConnecting to Mongo with URL : ${url}\n`); return new Promise<void>(resolve => { - this.MongoClient.connect(url, { connectTimeoutMS: 30000, socketTimeoutMS: 30000, useUnifiedTopology: true }, (_err, client) => { - console.error("mongo connect response\n"); + this.MongoClient.connect(url, { connectTimeoutMS: 30000, socketTimeoutMS: 30000 }).then(client => { + console.error('mongo connect response\n'); if (!client) { - console.error("\nMongo connect failed with the error:\n"); - console.log(_err); + console.error('\nMongo connect failed with the error:\n'); process.exit(0); } this.db = client.db(); @@ -74,20 +76,24 @@ export namespace Database { }); } - public async update(id: string, value: any, callback: (err: mongodb.MongoError, res: mongodb.UpdateWriteOpResult) => void, upsert = true, collectionName = DocumentsCollection) { + public async update(id: string, value: any, callback: (err: mongodb.MongoError, res: mongodb.UpdateResult) => void, upsert = true, collectionName = DocumentsCollection) { if (this.db) { - const collection = this.db.collection(collectionName); + const collection = this.db.collection<DocSchema>(collectionName); const prom = this.currentWrites[id]; let newProm: Promise<void>; const run = (): Promise<void> => { return new Promise<void>(resolve => { - collection.updateOne({ _id: id }, value, { upsert } - , (err, res) => { + collection + .updateOne({ _id: id }, value, { upsert }) + .then(res => { if (this.currentWrites[id] === newProm) { delete this.currentWrites[id]; } resolve(); - callback(err, res); + callback(undefined as any, res); + }) + .catch(error => { + console.log('MOngo UPDATE ONE ERROR:', error); }); }); }; @@ -99,21 +105,20 @@ export namespace Database { } } - public replace(id: string, value: any, callback: (err: mongodb.MongoError, res: mongodb.UpdateWriteOpResult) => void, upsert = true, collectionName = DocumentsCollection) { + public replace(id: string, value: any, callback: (err: mongodb.MongoError, res: mongodb.UpdateResult<mongodb.Document>) => void, upsert = true, collectionName = DocumentsCollection) { if (this.db) { - const collection = this.db.collection(collectionName); + const collection = this.db.collection<DocSchema>(collectionName); const prom = this.currentWrites[id]; let newProm: Promise<void>; const run = (): Promise<void> => { return new Promise<void>(resolve => { - collection.replaceOne({ _id: id }, value, { upsert } - , (err, res) => { - if (this.currentWrites[id] === newProm) { - delete this.currentWrites[id]; - } - resolve(); - callback(err, res); - }); + collection.replaceOne({ _id: id }, value, { upsert }).then(res => { + if (this.currentWrites[id] === newProm) { + delete this.currentWrites[id]; + } + resolve(); + callback(undefined as any, res as any); + }); }); }; newProm = prom ? prom.then(run) : run(); @@ -135,15 +140,20 @@ export namespace Database { return collectionNames; } - public delete(query: any, collectionName?: string): Promise<mongodb.DeleteWriteOpResultObject>; - public delete(id: string, collectionName?: string): Promise<mongodb.DeleteWriteOpResultObject>; + public delete(query: any, collectionName?: string): Promise<mongodb.DeleteResult>; + public delete(id: string, collectionName?: string): Promise<mongodb.DeleteResult>; public delete(id: any, collectionName = DocumentsCollection) { - if (typeof id === "string") { + if (typeof id === 'string') { id = { _id: id }; } if (this.db) { const db = this.db; - return new Promise(res => db.collection(collectionName).deleteMany(id, (err, result) => res(result))); + return new Promise(res => + db + .collection(collectionName) + .deleteMany(id) + .then(result => res(result)) + ); } else { return new Promise(res => this.onConnect.push(() => res(this.delete(id, collectionName)))); } @@ -170,22 +180,27 @@ export namespace Database { public async insert(value: any, collectionName = DocumentsCollection) { if (this.db && value !== null) { - if ("id" in value) { + if ('id' in value) { value._id = value.id; delete value.id; } const id = value._id; - const collection = this.db.collection(collectionName); + const collection = this.db.collection<DocSchema>(collectionName); const prom = this.currentWrites[id]; let newProm: Promise<void>; const run = (): Promise<void> => { return new Promise<void>(resolve => { - collection.insertOne(value, (err, res) => { - if (this.currentWrites[id] === newProm) { - delete this.currentWrites[id]; - } - resolve(); - }); + collection + .insertOne(value) + .then(res => { + if (this.currentWrites[id] === newProm) { + delete this.currentWrites[id]; + } + resolve(); + }) + .catch(err => { + console.log('Mongo INSERT ERROR: ', err); + }); }); }; newProm = prom ? prom.then(run) : run(); @@ -198,11 +213,12 @@ export namespace Database { public getDocument(id: string, fn: (result?: Transferable) => void, collectionName = DocumentsCollection) { if (this.db) { - this.db.collection(collectionName).findOne({ _id: id }, (err, result) => { + const collection = this.db.collection<DocSchema>(collectionName); + collection.findOne({ _id: id }).then(result => { if (result) { result.id = result._id; - delete result._id; - fn(result); + //delete result._id; + fn(result as any); } else { fn(undefined); } @@ -212,19 +228,19 @@ export namespace Database { } } - public getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName = DocumentsCollection) { + public async getDocuments(ids: string[], fn: (result: Transferable[]) => void, collectionName = DocumentsCollection) { if (this.db) { - this.db.collection(collectionName).find({ _id: { "$in": ids } }).toArray((err, docs) => { - if (err) { - console.log(err.message); - console.log(err.errmsg); - } - fn(docs.map(doc => { + const found = await this.db + .collection<DocSchema>(collectionName) + .find({ _id: { $in: ids } }) + .toArray(); + fn( + found.map((doc: any) => { doc.id = doc._id; delete doc._id; return doc; - })); - }); + }) + ); } else { this.onConnect.push(() => this.getDocuments(ids, fn, collectionName)); } @@ -257,15 +273,15 @@ export namespace Database { } } - public query(query: { [key: string]: any }, projection?: { [key: string]: 0 | 1 }, collectionName = DocumentsCollection): Promise<mongodb.Cursor> { + public query(query: { [key: string]: any }, projection?: { [key: string]: 0 | 1 }, collectionName = DocumentsCollection): Promise<mongodb.FindCursor> { if (this.db) { - let cursor = this.db.collection(collectionName).find(query); + let cursor = this.db.collection<DocSchema>(collectionName).find(query); if (projection) { cursor = cursor.project(projection); } - return Promise.resolve<mongodb.Cursor>(cursor); + return Promise.resolve<mongodb.FindCursor>(cursor); } else { - return new Promise<mongodb.Cursor>(res => { + return new Promise<mongodb.FindCursor>(res => { this.onConnect.push(() => res(this.query(query, projection, collectionName))); }); } @@ -274,22 +290,36 @@ export namespace Database { public updateMany(query: any, update: any, collectionName = DocumentsCollection) { if (this.db) { const db = this.db; - return new Promise<mongodb.WriteOpResult>(res => db.collection(collectionName).update(query, update, (_, result) => res(result))); + return new Promise<mongodb.UpdateResult>(res => + db + .collection(collectionName) + .updateMany(query, update) + .then(result => res(result)) + .catch(error => { + console.log('Mongo INSERT MANY ERROR:', error); + }) + ); } else { - return new Promise<mongodb.WriteOpResult>(res => { - this.onConnect.push(() => this.updateMany(query, update, collectionName).then(res)); + return new Promise<mongodb.UpdateResult>(res => { + this.onConnect.push(() => + this.updateMany(query, update, collectionName) + .then(res) + .catch(error => { + console.log('Mongo UPDATAE MANY ERROR: ', error); + }) + ); }); } } public print() { - console.log("db says hi!"); + console.log('db says hi!'); } } function getDatabase() { switch (process.env.DB) { - case "MEM": + case 'MEM': return new MemoryDatabase(); default: return new Database(); @@ -304,13 +334,12 @@ export namespace Database { * or Dash-internal user data. */ export namespace Auxiliary { - /** * All the auxiliary MongoDB collections (schemas) */ export enum AuxiliaryCollections { - GooglePhotosUploadHistory = "uploadedFromGooglePhotos", - GoogleAccess = "googleAuthentication", + GooglePhotosUploadHistory = 'uploadedFromGooglePhotos', + GoogleAccess = 'googleAuthentication', } /** @@ -322,16 +351,18 @@ export namespace Database { const cursor = await Instance.query(query, undefined, collection); const results = await cursor.toArray(); const slice = results.slice(0, Math.min(cap, results.length)); - return removeId ? slice.map(result => { - delete result._id; - return result; - }) : slice; + return removeId + ? slice.map((result: any) => { + delete result._id; + return result; + }) + : slice; }; /** * Searches for the @param query in the specified @param collection, * and returns at most the first result. If @param removeId is true, - * as it is by default, each object will be stripped of its database id. + * as it is by default, each object will be stripped of its database id. * Worth the special case since it converts the Array return type to a single * object of the specified type. */ @@ -341,7 +372,7 @@ export namespace Database { }; /** - * Checks to see if an image with the given @param contentSize + * Checks to see if an image with the given @param contentSize * already exists in the aux database, i.e. has already been downloaded from Google Photos. */ export const QueryUploadHistory = async (contentSize: number) => { @@ -355,7 +386,7 @@ export namespace Database { export const LogUpload = async (information: Upload.ImageInformation) => { const bundle = { _id: Utils.GenerateDeterministicGuid(String(information.contentSize)), - ...information + ...information, }; return Instance.insert(bundle, AuxiliaryCollections.GooglePhotosUploadHistory); }; @@ -365,7 +396,6 @@ export namespace Database { * facilitates interactions with all their APIs for a given account. */ export namespace GoogleAccessToken { - /** * Format stored in database. */ @@ -373,7 +403,7 @@ export namespace Database { /** * Retrieves the credentials associaed with @param userId - * and optionally removes their database id according to @param removeId. + * and optionally removes their database id according to @param removeId. */ export const Fetch = async (userId: string, removeId = true): Promise<Opt<StoredCredentials>> => { return SanitizedSingletonQuery<StoredCredentials>({ userId }, AuxiliaryCollections.GoogleAccess, removeId); @@ -381,7 +411,7 @@ export namespace Database { /** * Writes the @param enrichedCredentials to the database, associated - * with @param userId for later retrieval and updating. + * with @param userId for later retrieval and updating. */ export const Write = async (userId: string, enrichedCredentials: GoogleApiServerUtils.EnrichedCredentials) => { return Instance.insert({ userId, canAccess: [], ...enrichedCredentials }, AuxiliaryCollections.GoogleAccess); @@ -400,7 +430,7 @@ export namespace Database { }; /** - * Revokes the credentials associated with @param userId. + * Revokes the credentials associated with @param userId. */ export const Revoke = async (userId: string) => { const entry = await Fetch(userId, false); @@ -408,9 +438,6 @@ export namespace Database { Instance.delete({ _id: entry._id }, AuxiliaryCollections.GoogleAccess); } }; - } - } - } |