document.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const index_1 = require("./index");
  4. const util_1 = require("./util");
  5. const update_1 = require("./serializer/update");
  6. const datatype_1 = require("./serializer/datatype");
  7. const update_2 = require("./commands/update");
  8. const websocket_client_1 = require("./realtime/websocket-client");
  9. const constant_1 = require("./constant");
  10. const utils_1 = require("./utils/utils");
  11. const code_1 = require("./const/code");
  12. const bson_1 = require("bson");
  13. class DocumentReference {
  14. constructor(db, coll, apiOptions, docID, transactionId) {
  15. this.watch = (options) => {
  16. if (!index_1.Db.ws) {
  17. index_1.Db.ws = new websocket_client_1.RealtimeWebSocketClient({
  18. context: {
  19. appConfig: {
  20. docSizeLimit: 1000,
  21. realtimePingInterval: 10000,
  22. realtimePongWaitTimeout: 5000,
  23. request: this.request
  24. }
  25. }
  26. });
  27. }
  28. return index_1.Db.ws.watch(Object.assign(Object.assign({}, options), { envId: this._db.config.env, collectionName: this._coll, query: JSON.stringify({
  29. _id: this.id
  30. }) }));
  31. };
  32. this._db = db;
  33. this._coll = coll;
  34. this.id = docID;
  35. this._transactionId = transactionId;
  36. this.request = new index_1.Db.reqClass(this._db.config);
  37. this._apiOptions = apiOptions;
  38. }
  39. async create(data) {
  40. if (this.id) {
  41. data['_id'] = this.id;
  42. }
  43. let params = {
  44. collectionName: this._coll,
  45. data: [utils_1.stringifyByEJSON(datatype_1.serialize(data))],
  46. transactionId: this._transactionId
  47. };
  48. const res = await this.request.send('database.insertDocument', params, utils_1.getReqOpts(this._apiOptions));
  49. if (res.code) {
  50. return res;
  51. }
  52. if (this._transactionId) {
  53. return {
  54. inserted: 1,
  55. ok: 1,
  56. id: res.data.insertedIds[0],
  57. requestId: res.requestId
  58. };
  59. }
  60. return {
  61. id: res.data.insertedIds[0],
  62. requestId: res.requestId
  63. };
  64. }
  65. async set(data) {
  66. if (!this.id) {
  67. return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.INVALID_PARAM), { message: 'docId不能为空' }));
  68. }
  69. if (!data || typeof data !== 'object') {
  70. return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.INVALID_PARAM), { message: '参数必需是非空对象' }));
  71. }
  72. if (data.hasOwnProperty('_id')) {
  73. return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.INVALID_PARAM), { message: '不能更新_id的值' }));
  74. }
  75. let hasOperator = false;
  76. const checkMixed = objs => {
  77. if (typeof objs === 'object') {
  78. for (let key in objs) {
  79. if (objs[key] instanceof update_2.UpdateCommand) {
  80. hasOperator = true;
  81. }
  82. else if (typeof objs[key] === 'object') {
  83. checkMixed(objs[key]);
  84. }
  85. }
  86. }
  87. };
  88. checkMixed(data);
  89. if (hasOperator) {
  90. return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.DATABASE_REQUEST_FAILED), { message: 'update operator complicit' }));
  91. }
  92. let param = {
  93. collectionName: this._coll,
  94. queryType: constant_1.QueryType.DOC,
  95. data: utils_1.stringifyByEJSON(datatype_1.serialize(data)),
  96. transactionId: this._transactionId,
  97. multi: false,
  98. merge: false,
  99. upsert: true
  100. };
  101. if (this.id) {
  102. param['query'] = utils_1.stringifyByEJSON({ _id: this.id });
  103. }
  104. const res = await this.request.send('database.modifyDocument', param, utils_1.getReqOpts(this._apiOptions));
  105. if (res.code) {
  106. return res;
  107. }
  108. if (this._transactionId) {
  109. return {
  110. updated: res.data.updated,
  111. upserted: [{ _id: res.data.upsert_id }],
  112. requestId: res.requestId
  113. };
  114. }
  115. return {
  116. updated: res.data.updated,
  117. upsertedId: res.data.upsert_id,
  118. requestId: res.requestId
  119. };
  120. }
  121. async update(data) {
  122. if (!data || typeof data !== 'object') {
  123. return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.INVALID_PARAM), { message: '参数必需是非空对象' }));
  124. }
  125. if (data.hasOwnProperty('_id')) {
  126. return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.INVALID_PARAM), { message: '不能更新_id的值' }));
  127. }
  128. const query = utils_1.stringifyByEJSON({ _id: this.id });
  129. const param = {
  130. collectionName: this._coll,
  131. transactionId: this._transactionId,
  132. data: update_1.UpdateSerializer.encodeEJSON(data),
  133. query,
  134. queryType: constant_1.QueryType.DOC,
  135. multi: false,
  136. merge: true,
  137. upsert: false
  138. };
  139. const res = await this.request.send('database.modifyDocument', param, utils_1.getReqOpts(this._apiOptions));
  140. if (res.code) {
  141. return res;
  142. }
  143. return {
  144. updated: res.data.updated,
  145. requestId: res.requestId
  146. };
  147. }
  148. async delete() {
  149. return this.remove();
  150. }
  151. async remove() {
  152. const query = utils_1.stringifyByEJSON({ _id: this.id });
  153. const param = {
  154. collectionName: this._coll,
  155. transactionId: this._transactionId,
  156. query: query,
  157. queryType: constant_1.QueryType.DOC,
  158. multi: false
  159. };
  160. const res = await this.request.send('database.removeDocument', param, utils_1.getReqOpts(this._apiOptions));
  161. if (res.code) {
  162. return res;
  163. }
  164. return {
  165. deleted: res.data.deleted,
  166. requestId: res.requestId
  167. };
  168. }
  169. async get() {
  170. const query = utils_1.stringifyByEJSON({ _id: this.id });
  171. const { projection } = this._apiOptions;
  172. const param = {
  173. collectionName: this._coll,
  174. query,
  175. transactionId: this._transactionId,
  176. queryType: constant_1.QueryType.DOC,
  177. multi: false
  178. };
  179. if (projection) {
  180. param.projection = utils_1.stringifyByEJSON(projection);
  181. }
  182. const res = await this.request.send('database.getDocument', param, utils_1.getReqOpts(this._apiOptions));
  183. if (res.code) {
  184. return res;
  185. }
  186. const list = res.data.list.map(item => bson_1.EJSON.parse(item));
  187. const documents = util_1.Util.formatResDocumentData(list);
  188. if (this._transactionId) {
  189. return {
  190. data: documents[0] || null,
  191. requestId: res.requestId
  192. };
  193. }
  194. return {
  195. data: documents,
  196. requestId: res.requestId,
  197. offset: res.data.offset,
  198. limit: res.data.limit
  199. };
  200. }
  201. field(projection) {
  202. let transformProjection = {};
  203. for (let k in projection) {
  204. if (typeof projection[k] === 'boolean') {
  205. transformProjection[k] = projection[k] === true ? 1 : 0;
  206. }
  207. if (typeof projection[k] === 'number') {
  208. transformProjection[k] = projection[k] > 0 ? 1 : 0;
  209. }
  210. if (typeof projection[k] === 'object') {
  211. transformProjection[k] = projection[k];
  212. }
  213. }
  214. let newApiOption = Object.assign({}, this._apiOptions);
  215. newApiOption.projection = transformProjection;
  216. return new DocumentReference(this._db, this._coll, newApiOption, this.id, this._transactionId);
  217. }
  218. }
  219. exports.DocumentReference = DocumentReference;