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.

164 lines
5.0KB

  1. import * as MongoClient from 'mongodb';
  2. import { Client } from './client';
  3. import { UUID } from './global/scalars/UUID';
  4. export class DB {
  5. private readonly DBDATA = {
  6. user: 'root',
  7. pwd: 'TurnenAufZeit',
  8. host: 'localhost',
  9. port: 27017,
  10. source: 'admin',
  11. db: 'TurnenAufZeit',
  12. };
  13. private mongo: MongoClient;
  14. private db: MongoClient.Db;
  15. public getDB(): MongoClient.Db {
  16. return this.db
  17. }
  18. public async connect(): MongoClient.Db {
  19. this.mongo = await new Promise((resolve, reject) => {
  20. MongoClient.connect(`mongodb://${this.DBDATA.user}:${this.DBDATA.pwd}@${this.DBDATA.host}:${this.DBDATA.port}`, {
  21. authSource: this.DBDATA.source,
  22. useNewUrlParser: true,
  23. useUnifiedTopology: true,
  24. poolSize: 20,
  25. }, (err, database) => {
  26. if (err) {
  27. reject(err);
  28. }
  29. resolve(database);
  30. });
  31. });
  32. this.db = this.mongo.db(this.DBDATA.db);
  33. }
  34. public collection(ops): MongoClient.Collection {
  35. return this.db.collection(ops);
  36. }
  37. public async fetch(collection: string, filter: any = {}, limit?: number, offset?: number): Promise<any[]> {
  38. if (!limit || limit > 1000) limit = 1001;
  39. if (limit < 0) limit = -limit;
  40. if (offset) {
  41. return new Promise<any[]>((resolve, reject) => this.db.collection(collection).find(filter).skip(offset).limit(limit).toArray((e, d) => {
  42. if (e) {
  43. return reject(e);
  44. }
  45. resolve(d);
  46. }))
  47. } else {
  48. return new Promise<any[]>((resolve, reject) => this.db.collection(collection).find(filter).limit(limit).toArray((e, d) => {
  49. if (e) {
  50. return reject(e);
  51. }
  52. resolve(d);
  53. }))
  54. }
  55. }
  56. public async fetchAll(collection: string): Promise<any[]> {
  57. return new Promise<any[]>((resolve, reject) => this.db.collection(collection).find(true).toArray((e, d) => {
  58. if (e) {
  59. return reject(e);
  60. }
  61. resolve(d);
  62. }))
  63. }
  64. public async insert(collection: string, doc: any, client?: Client): Promise<any> {
  65. const d = await this.db.collection(collection).insertOne({ ...doc, _v: 1, _m: { ctime: Date.now(), mtime: Date.now() } })
  66. if (d.insertedCount !== 1) { return null; }
  67. const insertOp = {
  68. id: doc._id,
  69. create: { ...doc },
  70. user: client?.getUser()?._id,
  71. ts: Date.now(),
  72. }
  73. delete insertOp.create._id;
  74. delete insertOp.create._v;
  75. await this.db.collection(`o_${collection}`).insertOne(insertOp);
  76. return d?.ops?.[0];
  77. }
  78. public async update(collection: string, doc: any, client?: Client): Promise<any> {
  79. const old = await this.db.collection(collection).findOne({ _id: doc._id });
  80. if (!old) return null;
  81. const neu = { ...old, ...doc, _m: { ...old?._m, mtime: Date.now() } };
  82. const d = await this.db.collection(collection).replaceOne({_id: doc._id}, neu);
  83. if (d.modifiedCount !== 1 || !client) { return null; }
  84. const insertOp = {
  85. id: doc._id,
  86. old: { ...old },
  87. update: { ...doc },
  88. user: client?.getUser()?._id,
  89. ts: Date.now(),
  90. }
  91. delete insertOp.update._id;
  92. delete insertOp.update._v;
  93. await this.db.collection(`o_${collection}`).insertOne(insertOp);
  94. return d?.ops?.[0];
  95. }
  96. public async delete(collection: string, id: UUID, client?: Client): Promise<UUID> {
  97. const old = await this.db.collection(collection).findOne({ _id: id });
  98. if (!old) { return null; }
  99. const del = await this.db.collection(collection).deleteOne({ _id: id });
  100. if (del.deletedCount !== 1) { return null; }
  101. const insertOp = {
  102. id: old._id,
  103. delete: { ...old },
  104. user: client?.getUser()?._id,
  105. ts: Date.now(),
  106. }
  107. delete insertOp.delete._id;
  108. delete insertOp.delete._v;
  109. await this.db.collection(`o_${collection}`).insertOne(insertOp);
  110. return id;
  111. }
  112. public async doOps(collection: string, id: UUID, ops: any, filter: any, client?: Client): Promise<any> {
  113. const doc: any = await this.fetch(collection, { _id: id });
  114. if (!doc) return null;
  115. await db.collection(collection).updateOne({_id: id}, ops, filter);
  116. const neu = await this.fetch(collection, { _id: id });
  117. const insertOp = {
  118. id: doc._id,
  119. old: { ...doc },
  120. ops: JSON.stringify(ops),
  121. filter: JSON.stringify(filter),
  122. user: client?.getUser()?._id,
  123. ts: Date.now(),
  124. }
  125. this.db.collection(`o_${collection}`).insertOne(insertOp);
  126. return neu[0];
  127. }
  128. }
  129. export const db = new DB();