mongodb-adapter.spec.js 90 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391
  1. import {expect} from 'chai';
  2. import {ObjectId} from 'mongodb';
  3. import {MongoClient} from 'mongodb';
  4. import {format} from '@e22m4u/js-format';
  5. import {Service} from '@e22m4u/js-service';
  6. import {Schema} from '@e22m4u/js-repository';
  7. import {DataType} from '@e22m4u/js-repository';
  8. import {createMongodbUrl} from './utils/index.js';
  9. import {MongodbAdapter} from './mongodb-adapter.js';
  10. import {AdapterRegistry} from '@e22m4u/js-repository';
  11. import {DEFAULT_PRIMARY_KEY_PROPERTY_NAME as DEF_PK} from '@e22m4u/js-repository';
  12. const CONFIG = {
  13. host: process.env.MONGODB_HOST || 'localhost',
  14. port: process.env.MONGODB_PORT || 27017,
  15. database: process.env.MONGODB_DATABASE,
  16. };
  17. const MDB_CLIENT = new MongoClient(createMongodbUrl(CONFIG));
  18. const ADAPTERS_STACK = [];
  19. function createSchema() {
  20. const schema = new Schema();
  21. const adapter = new MongodbAdapter(schema.container, CONFIG);
  22. ADAPTERS_STACK.push(adapter);
  23. schema.defineDatasource({name: 'mongodb', adapter: 'mongodb'});
  24. schema.getService(AdapterRegistry)._adapters['mongodb'] = adapter;
  25. return schema;
  26. }
  27. describe('MongodbAdapter', function () {
  28. this.timeout(15000);
  29. afterEach(async function () {
  30. await MDB_CLIENT.db(CONFIG.database).dropDatabase();
  31. });
  32. after(async function () {
  33. for await (const adapter of ADAPTERS_STACK) {
  34. await adapter.disconnect();
  35. }
  36. await MDB_CLIENT.close(true);
  37. });
  38. it('able to connect and disconnect', async function () {
  39. const S = new Service();
  40. const adapter = new MongodbAdapter(S.container, CONFIG);
  41. await adapter.connect();
  42. expect(adapter.connected).to.be.true;
  43. await adapter.disconnect();
  44. });
  45. describe('create', function () {
  46. it('generates a new identifier when a value of a primary key is not provided', async function () {
  47. const schema = createSchema();
  48. schema.defineModel({name: 'model', datasource: 'mongodb'});
  49. const rep = schema.getRepository('model');
  50. const result = await rep.create({foo: 'bar'});
  51. expect(result).to.be.eql({[DEF_PK]: result[DEF_PK], foo: 'bar'});
  52. expect(typeof result[DEF_PK]).to.be.eq('string');
  53. expect(result[DEF_PK]).to.have.lengthOf(24);
  54. });
  55. it('generates a new identifier when a value of a primary key is undefined', async function () {
  56. const schema = createSchema();
  57. schema.defineModel({name: 'model', datasource: 'mongodb'});
  58. const rep = schema.getRepository('model');
  59. const result = await rep.create({[DEF_PK]: undefined, foo: 'bar'});
  60. expect(result).to.be.eql({[DEF_PK]: result[DEF_PK], foo: 'bar'});
  61. expect(typeof result[DEF_PK]).to.be.eq('string');
  62. expect(result[DEF_PK]).to.have.lengthOf(24);
  63. });
  64. it('generates a new identifier when a value of a primary key is null', async function () {
  65. const schema = createSchema();
  66. schema.defineModel({name: 'model', datasource: 'mongodb'});
  67. const rep = schema.getRepository('model');
  68. const result = await rep.create({[DEF_PK]: null, foo: 'bar'});
  69. expect(result).to.be.eql({[DEF_PK]: result[DEF_PK], foo: 'bar'});
  70. expect(typeof result[DEF_PK]).to.be.eq('string');
  71. expect(result[DEF_PK]).to.have.lengthOf(24);
  72. });
  73. it('generates a new identifier for a primary key of a "string" type', async function () {
  74. const schema = createSchema();
  75. schema.defineModel({
  76. name: 'model',
  77. datasource: 'mongodb',
  78. properties: {
  79. id: {
  80. type: DataType.STRING,
  81. primaryKey: true,
  82. },
  83. },
  84. });
  85. const rep = schema.getRepository('model');
  86. const result = await rep.create({[DEF_PK]: null, foo: 'bar'});
  87. expect(result).to.be.eql({[DEF_PK]: result[DEF_PK], foo: 'bar'});
  88. expect(typeof result[DEF_PK]).to.be.eq('string');
  89. expect(result[DEF_PK]).to.have.lengthOf(24);
  90. });
  91. it('generates a new identifier for a primary key of a "any" type', async function () {
  92. const schema = createSchema();
  93. schema.defineModel({
  94. name: 'model',
  95. datasource: 'mongodb',
  96. properties: {
  97. id: {
  98. type: DataType.ANY,
  99. primaryKey: true,
  100. },
  101. },
  102. });
  103. const rep = schema.getRepository('model');
  104. const result = await rep.create({[DEF_PK]: null, foo: 'bar'});
  105. expect(result).to.be.eql({[DEF_PK]: result[DEF_PK], foo: 'bar'});
  106. expect(typeof result[DEF_PK]).to.be.eq('string');
  107. expect(result[DEF_PK]).to.have.lengthOf(24);
  108. });
  109. it('throws an error when generating a new value for a primary key of a "number" type', async function () {
  110. const schema = createSchema();
  111. schema.defineModel({
  112. name: 'model',
  113. datasource: 'mongodb',
  114. properties: {
  115. id: {
  116. type: DataType.NUMBER,
  117. primaryKey: true,
  118. },
  119. },
  120. });
  121. const rep = schema.getRepository('model');
  122. const promise = rep.create({});
  123. expect(promise).to.be.rejectedWith(
  124. 'MongoDB unable to generate primary keys of Number. ' +
  125. 'Do provide your own value for the "id" property ' +
  126. 'or set the property type to String.',
  127. );
  128. });
  129. it('throws an error when generating a new value for a primary key of a "boolean" type', async function () {
  130. const schema = createSchema();
  131. schema.defineModel({
  132. name: 'model',
  133. datasource: 'mongodb',
  134. properties: {
  135. id: {
  136. type: DataType.BOOLEAN,
  137. primaryKey: true,
  138. },
  139. },
  140. });
  141. const rep = schema.getRepository('model');
  142. const promise = rep.create({});
  143. expect(promise).to.be.rejectedWith(
  144. 'MongoDB unable to generate primary keys of Boolean. ' +
  145. 'Do provide your own value for the "id" property ' +
  146. 'or set the property type to String.',
  147. );
  148. });
  149. it('throws an error when generating a new value for a primary key of a "array" type', async function () {
  150. const schema = createSchema();
  151. schema.defineModel({
  152. name: 'model',
  153. datasource: 'mongodb',
  154. properties: {
  155. id: {
  156. type: DataType.ARRAY,
  157. primaryKey: true,
  158. },
  159. },
  160. });
  161. const rep = schema.getRepository('model');
  162. const promise = rep.create({});
  163. expect(promise).to.be.rejectedWith(
  164. 'MongoDB unable to generate primary keys of Array. ' +
  165. 'Do provide your own value for the "id" property ' +
  166. 'or set the property type to String.',
  167. );
  168. });
  169. it('throws an error when generating a new value for a primary key of a "object" type', async function () {
  170. const schema = createSchema();
  171. schema.defineModel({
  172. name: 'model',
  173. datasource: 'mongodb',
  174. properties: {
  175. id: {
  176. type: DataType.OBJECT,
  177. primaryKey: true,
  178. },
  179. },
  180. });
  181. const rep = schema.getRepository('model');
  182. const promise = rep.create({});
  183. expect(promise).to.be.rejectedWith(
  184. 'MongoDB unable to generate primary keys of Object. ' +
  185. 'Do provide your own value for the "id" property ' +
  186. 'or set the property type to String.',
  187. );
  188. });
  189. it('allows to specify an ObjectID instance for a default primary key', async function () {
  190. const schema = createSchema();
  191. schema.defineModel({name: 'model', datasource: 'mongodb'});
  192. const rep = schema.getRepository('model');
  193. const oid = new ObjectId();
  194. const result = await rep.create({[DEF_PK]: oid});
  195. expect(result).to.be.eql({[DEF_PK]: String(oid)});
  196. const rawData = await MDB_CLIENT.db()
  197. .collection('model')
  198. .findOne({_id: oid});
  199. expect(rawData).to.be.not.null;
  200. });
  201. it('allows to specify an ObjectID string for a default primary key', async function () {
  202. const schema = createSchema();
  203. schema.defineModel({name: 'model', datasource: 'mongodb'});
  204. const rep = schema.getRepository('model');
  205. const oid = new ObjectId();
  206. const id = String(oid);
  207. const result = await rep.create({[DEF_PK]: id});
  208. expect(result).to.be.eql({[DEF_PK]: id});
  209. const rawData = await MDB_CLIENT.db()
  210. .collection('model')
  211. .findOne({_id: oid});
  212. expect(rawData).to.be.not.null;
  213. });
  214. it('allows to specify an ObjectID instance for "id" primary key', async function () {
  215. const schema = createSchema();
  216. schema.defineModel({
  217. name: 'model',
  218. datasource: 'mongodb',
  219. properties: {
  220. id: {
  221. type: DataType.ANY,
  222. primaryKey: true,
  223. },
  224. },
  225. });
  226. const rep = schema.getRepository('model');
  227. const oid = new ObjectId();
  228. const result = await rep.create({id: oid});
  229. expect(result).to.be.eql({id: String(oid)});
  230. const rawData = await MDB_CLIENT.db()
  231. .collection('model')
  232. .findOne({_id: oid});
  233. expect(rawData).to.be.not.null;
  234. });
  235. it('allows to specify an ObjectID string for "id" primary key', async function () {
  236. const schema = createSchema();
  237. schema.defineModel({
  238. name: 'model',
  239. datasource: 'mongodb',
  240. properties: {
  241. id: {
  242. type: DataType.STRING,
  243. primaryKey: true,
  244. },
  245. },
  246. });
  247. const rep = schema.getRepository('model');
  248. const oid = new ObjectId();
  249. const id = String(oid);
  250. const result = await rep.create({id});
  251. expect(result).to.be.eql({id});
  252. const rawData = await MDB_CLIENT.db()
  253. .collection('model')
  254. .findOne({_id: oid});
  255. expect(rawData).to.be.not.null;
  256. });
  257. it('allows to specify an ObjectID instance for "_id" primary key', async function () {
  258. const schema = createSchema();
  259. schema.defineModel({
  260. name: 'model',
  261. datasource: 'mongodb',
  262. properties: {
  263. _id: {
  264. type: DataType.ANY,
  265. primaryKey: true,
  266. },
  267. },
  268. });
  269. const rep = schema.getRepository('model');
  270. const oid = new ObjectId();
  271. const result = await rep.create({_id: oid});
  272. expect(result).to.be.eql({_id: String(oid)});
  273. const rawData = await MDB_CLIENT.db()
  274. .collection('model')
  275. .findOne({_id: oid});
  276. expect(rawData).to.be.not.null;
  277. });
  278. it('allows to specify an ObjectID string for "_id" primary key', async function () {
  279. const schema = createSchema();
  280. schema.defineModel({
  281. name: 'model',
  282. datasource: 'mongodb',
  283. properties: {
  284. _id: {
  285. type: DataType.STRING,
  286. primaryKey: true,
  287. },
  288. },
  289. });
  290. const rep = schema.getRepository('model');
  291. const oid = new ObjectId();
  292. const id = String(oid);
  293. const result = await rep.create({_id: id});
  294. expect(result).to.be.eql({_id: id});
  295. const rawData = await MDB_CLIENT.db()
  296. .collection('model')
  297. .findOne({_id: oid});
  298. expect(rawData).to.be.not.null;
  299. });
  300. it('throws an error for a custom primary key', async function () {
  301. const schema = createSchema();
  302. schema.defineModel({
  303. name: 'model',
  304. datasource: 'mongodb',
  305. properties: {
  306. myId: {
  307. type: DataType.ANY,
  308. primaryKey: true,
  309. },
  310. },
  311. });
  312. const rep = schema.getRepository('model');
  313. const oid = new ObjectId();
  314. const promise = rep.create({myId: oid});
  315. await expect(promise).to.be.rejectedWith(
  316. 'MongoDB is not supporting custom names of the primary key. ' +
  317. 'Do use "id" as a primary key instead of "myId".',
  318. );
  319. });
  320. it('throws an error if a given "number" identifier already exists', async function () {
  321. const schema = createSchema();
  322. schema.defineModel({name: 'model', datasource: 'mongodb'});
  323. const rep = schema.getRepository('model');
  324. await rep.create({[DEF_PK]: 10});
  325. const promise = rep.create({[DEF_PK]: 10});
  326. await expect(promise).to.be.rejectedWith(
  327. 'E11000 duplicate key error collection: test.model index: ' +
  328. '_id_ dup key: { _id: 10 }',
  329. );
  330. });
  331. it('throws an error if a given "string" identifier already exists', async function () {
  332. const schema = createSchema();
  333. schema.defineModel({name: 'model', datasource: 'mongodb'});
  334. const rep = schema.getRepository('model');
  335. await rep.create({[DEF_PK]: 'str'});
  336. const promise = rep.create({[DEF_PK]: 'str'});
  337. await expect(promise).to.be.rejectedWith(
  338. 'E11000 duplicate key error collection: test.model index: ' +
  339. '_id_ dup key: { _id: "str" }',
  340. );
  341. });
  342. it('throws an error if a given ObjectId instance identifier already exists', async function () {
  343. const schema = createSchema();
  344. schema.defineModel({name: 'model', datasource: 'mongodb'});
  345. const rep = schema.getRepository('model');
  346. const oid = new ObjectId();
  347. await rep.create({[DEF_PK]: oid});
  348. const promise = rep.create({[DEF_PK]: oid});
  349. await expect(promise).to.be.rejectedWith(
  350. format(
  351. 'E11000 duplicate key error collection: test.model index: ' +
  352. "_id_ dup key: { _id: ObjectId('%s') }",
  353. oid,
  354. ),
  355. );
  356. });
  357. it('throws an error if a given ObjectId string identifier already exists', async function () {
  358. const schema = createSchema();
  359. schema.defineModel({name: 'model', datasource: 'mongodb'});
  360. const rep = schema.getRepository('model');
  361. const oid = new ObjectId();
  362. const id = String(oid);
  363. await rep.create({[DEF_PK]: id});
  364. const promise = rep.create({[DEF_PK]: id});
  365. await expect(promise).to.be.rejectedWith(
  366. format(
  367. 'E11000 duplicate key error collection: test.model index: ' +
  368. "_id_ dup key: { _id: ObjectId('%s') }",
  369. id,
  370. ),
  371. );
  372. });
  373. it('uses a specified column name for a regular property', async function () {
  374. const schema = createSchema();
  375. schema.defineModel({
  376. name: 'model',
  377. datasource: 'mongodb',
  378. properties: {
  379. foo: {
  380. type: DataType.NUMBER,
  381. columnName: 'bar',
  382. },
  383. },
  384. });
  385. const rep = schema.getRepository('model');
  386. const result = await rep.create({foo: 10});
  387. expect(result).to.be.eql({[DEF_PK]: result[DEF_PK], foo: 10});
  388. const oid = new ObjectId(result[DEF_PK]);
  389. const rawData = await MDB_CLIENT.db()
  390. .collection('model')
  391. .findOne({_id: oid});
  392. expect(rawData).to.be.eql({_id: oid, bar: 10});
  393. });
  394. it('uses a specified column name for a regular property with a default value', async function () {
  395. const schema = createSchema();
  396. schema.defineModel({
  397. name: 'model',
  398. datasource: 'mongodb',
  399. properties: {
  400. foo: {
  401. type: DataType.NUMBER,
  402. columnName: 'bar',
  403. default: 10,
  404. },
  405. },
  406. });
  407. const rep = schema.getRepository('model');
  408. const result = await rep.create({});
  409. expect(result).to.be.eql({[DEF_PK]: result[DEF_PK], foo: 10});
  410. const oid = new ObjectId(result[DEF_PK]);
  411. const rawData = await MDB_CLIENT.db()
  412. .collection('model')
  413. .findOne({_id: oid});
  414. expect(rawData).to.be.eql({_id: oid, bar: 10});
  415. });
  416. it('stores a Date instance as date and returns string type', async function () {
  417. const schema = createSchema();
  418. schema.defineModel({name: 'model', datasource: 'mongodb'});
  419. const rep = schema.getRepository('model');
  420. const date = new Date();
  421. const dateString = date.toISOString();
  422. const result = await rep.create({date});
  423. expect(result).to.be.eql({[DEF_PK]: result[DEF_PK], date: dateString});
  424. const oid = new ObjectId(result[DEF_PK]);
  425. const rawData = await MDB_CLIENT.db()
  426. .collection('model')
  427. .findOne({_id: oid});
  428. expect(rawData).to.be.eql({_id: oid, date});
  429. });
  430. it('stores a Date string as date and returns string type', async function () {
  431. const schema = createSchema();
  432. schema.defineModel({name: 'model', datasource: 'mongodb'});
  433. const rep = schema.getRepository('model');
  434. const date = new Date();
  435. const dateString = date.toISOString();
  436. const result = await rep.create({date: dateString});
  437. expect(result).to.be.eql({[DEF_PK]: result[DEF_PK], date: dateString});
  438. const oid = new ObjectId(result[DEF_PK]);
  439. const rawData = await MDB_CLIENT.db()
  440. .collection('model')
  441. .findOne({_id: oid});
  442. expect(rawData).to.be.eql({_id: oid, date});
  443. });
  444. it('stores a string as is', async function () {
  445. const schema = createSchema();
  446. schema.defineModel({name: 'model', datasource: 'mongodb'});
  447. const rep = schema.getRepository('model');
  448. const result = await rep.create({foo: 'str'});
  449. expect(result).to.be.eql({[DEF_PK]: result[DEF_PK], foo: 'str'});
  450. const oid = new ObjectId(result[DEF_PK]);
  451. const rawData = await MDB_CLIENT.db()
  452. .collection('model')
  453. .findOne({_id: oid});
  454. expect(rawData).to.be.eql({_id: oid, foo: 'str'});
  455. });
  456. it('stores a number as is', async function () {
  457. const schema = createSchema();
  458. schema.defineModel({name: 'model', datasource: 'mongodb'});
  459. const rep = schema.getRepository('model');
  460. const result = await rep.create({foo: 10});
  461. expect(result).to.be.eql({[DEF_PK]: result[DEF_PK], foo: 10});
  462. const oid = new ObjectId(result[DEF_PK]);
  463. const rawData = await MDB_CLIENT.db()
  464. .collection('model')
  465. .findOne({_id: oid});
  466. expect(rawData).to.be.eql({_id: oid, foo: 10});
  467. });
  468. it('stores a boolean as is', async function () {
  469. const schema = createSchema();
  470. schema.defineModel({name: 'model', datasource: 'mongodb'});
  471. const rep = schema.getRepository('model');
  472. const result = await rep.create({foo: true, bar: false});
  473. expect(result).to.be.eql({
  474. [DEF_PK]: result[DEF_PK],
  475. foo: true,
  476. bar: false,
  477. });
  478. const oid = new ObjectId(result[DEF_PK]);
  479. const rawData = await MDB_CLIENT.db()
  480. .collection('model')
  481. .findOne({_id: oid});
  482. expect(rawData).to.be.eql({_id: oid, foo: true, bar: false});
  483. });
  484. it('stores an array as is', async function () {
  485. const schema = createSchema();
  486. schema.defineModel({name: 'model', datasource: 'mongodb'});
  487. const rep = schema.getRepository('model');
  488. const result = await rep.create({foo: ['bar']});
  489. expect(result).to.be.eql({
  490. [DEF_PK]: result[DEF_PK],
  491. foo: ['bar'],
  492. });
  493. const oid = new ObjectId(result[DEF_PK]);
  494. const rawData = await MDB_CLIENT.db()
  495. .collection('model')
  496. .findOne({_id: oid});
  497. expect(rawData).to.be.eql({_id: oid, foo: ['bar']});
  498. });
  499. it('stores an object as is', async function () {
  500. const schema = createSchema();
  501. schema.defineModel({name: 'model', datasource: 'mongodb'});
  502. const rep = schema.getRepository('model');
  503. const result = await rep.create({foo: {bar: 10}});
  504. expect(result).to.be.eql({
  505. [DEF_PK]: result[DEF_PK],
  506. foo: {bar: 10},
  507. });
  508. const oid = new ObjectId(result[DEF_PK]);
  509. const rawData = await MDB_CLIENT.db()
  510. .collection('model')
  511. .findOne({_id: oid});
  512. expect(rawData).to.be.eql({_id: oid, foo: {bar: 10}});
  513. });
  514. it('stores an undefined as null', async function () {
  515. const schema = createSchema();
  516. schema.defineModel({name: 'model', datasource: 'mongodb'});
  517. const rep = schema.getRepository('model');
  518. const result = await rep.create({foo: undefined});
  519. expect(result).to.be.eql({
  520. [DEF_PK]: result[DEF_PK],
  521. foo: null,
  522. });
  523. const oid = new ObjectId(result[DEF_PK]);
  524. const rawData = await MDB_CLIENT.db()
  525. .collection('model')
  526. .findOne({_id: oid});
  527. expect(rawData).to.be.eql({_id: oid, foo: null});
  528. });
  529. it('stores an null as is', async function () {
  530. const schema = createSchema();
  531. schema.defineModel({name: 'model', datasource: 'mongodb'});
  532. const rep = schema.getRepository('model');
  533. const result = await rep.create({foo: null});
  534. expect(result).to.be.eql({
  535. [DEF_PK]: result[DEF_PK],
  536. foo: null,
  537. });
  538. const oid = new ObjectId(result[DEF_PK]);
  539. const rawData = await MDB_CLIENT.db()
  540. .collection('model')
  541. .findOne({_id: oid});
  542. expect(rawData).to.be.eql({_id: oid, foo: null});
  543. });
  544. it('uses a short fields clause to filter results', async function () {
  545. const schema = createSchema();
  546. schema.defineModel({name: 'model', datasource: 'mongodb'});
  547. const rep = schema.getRepository('model');
  548. const result = await rep.create({foo: 10, bar: 20}, {fields: 'foo'});
  549. expect(result).to.be.eql({[DEF_PK]: result[DEF_PK], foo: 10});
  550. });
  551. it('uses a full fields clause to filter results', async function () {
  552. const schema = createSchema();
  553. schema.defineModel({name: 'model', datasource: 'mongodb'});
  554. const rep = schema.getRepository('model');
  555. const result = await rep.create(
  556. {foo: 10, bar: 20, baz: 30},
  557. {fields: ['foo', 'bar']},
  558. );
  559. expect(result).to.be.eql({[DEF_PK]: result[DEF_PK], foo: 10, bar: 20});
  560. const oid = new ObjectId(result[DEF_PK]);
  561. const rawData = await MDB_CLIENT.db()
  562. .collection('model')
  563. .findOne({_id: oid});
  564. expect(rawData).to.be.eql({_id: oid, foo: 10, bar: 20, baz: 30});
  565. });
  566. it('a fields clause uses property names instead of column names', async function () {
  567. const schema = createSchema();
  568. schema.defineModel({
  569. name: 'model',
  570. datasource: 'mongodb',
  571. properties: {
  572. foo: {
  573. type: DataType.NUMBER,
  574. columnName: 'fooCol',
  575. },
  576. bar: {
  577. type: DataType.NUMBER,
  578. columnName: 'barCol',
  579. },
  580. baz: {
  581. type: DataType.NUMBER,
  582. columnName: 'bazCol',
  583. },
  584. },
  585. });
  586. const rep = schema.getRepository('model');
  587. const result = await rep.create(
  588. {foo: 10, bar: 20, baz: 30},
  589. {fields: ['fooCol', 'barCol']},
  590. );
  591. expect(result).to.be.eql({[DEF_PK]: result[DEF_PK]});
  592. });
  593. });
  594. describe('replaceById', function () {
  595. it('removes properties when replacing an item by a given identifier', async function () {
  596. const schema = createSchema();
  597. schema.defineModel({name: 'model', datasource: 'mongodb'});
  598. const rep = schema.getRepository('model');
  599. const created = await rep.create({foo: 10});
  600. const id = created[DEF_PK];
  601. const replaced = await rep.replaceById(id, {bar: 20});
  602. expect(replaced).to.be.eql({[DEF_PK]: id, bar: 20});
  603. const oid = new ObjectId(id);
  604. const rawData = await MDB_CLIENT.db()
  605. .collection('model')
  606. .findOne({_id: oid});
  607. expect(rawData).to.be.eql({_id: oid, bar: 20});
  608. });
  609. it('ignores identifier value in a given data in case of a default primary key', async function () {
  610. const schema = createSchema();
  611. schema.defineModel({name: 'model', datasource: 'mongodb'});
  612. const rep = schema.getRepository('model');
  613. await rep.create({[DEF_PK]: 'foo', prop: 10});
  614. const replaced = await rep.replaceById('foo', {
  615. [DEF_PK]: 'bar',
  616. prop: 20,
  617. });
  618. expect(replaced).to.be.eql({[DEF_PK]: 'foo', prop: 20});
  619. const rawData = await MDB_CLIENT.db()
  620. .collection('model')
  621. .findOne({_id: 'foo'});
  622. expect(rawData).to.be.eql({_id: 'foo', prop: 20});
  623. });
  624. it('ignores identifier value in a given data in case of a custom primary key', async function () {
  625. const schema = createSchema();
  626. schema.defineModel({
  627. name: 'model',
  628. datasource: 'mongodb',
  629. properties: {
  630. myId: {
  631. type: DataType.STRING,
  632. primaryKey: true,
  633. columnName: '_id',
  634. },
  635. },
  636. });
  637. const rep = schema.getRepository('model');
  638. await rep.create({myId: 'foo', prop: 10});
  639. const replaced = await rep.replaceById('foo', {myId: 'bar', prop: 20});
  640. expect(replaced).to.be.eql({myId: 'foo', prop: 20});
  641. const rawData = await MDB_CLIENT.db()
  642. .collection('model')
  643. .findOne({_id: 'foo'});
  644. expect(rawData).to.be.eql({_id: 'foo', prop: 20});
  645. });
  646. it('throws an error if a given identifier does not exist', async function () {
  647. const schema = createSchema();
  648. schema.defineModel({name: 'model', datasource: 'mongodb'});
  649. const rep = schema.getRepository('model');
  650. const oid = new ObjectId();
  651. const promise = rep.replaceById(oid, {foo: 10});
  652. await expect(promise).to.be.rejectedWith(
  653. format('Identifier "%s" is not found.', oid),
  654. );
  655. });
  656. it('throws an error for a custom primary key', async function () {
  657. const schema = createSchema();
  658. schema.defineModel({
  659. name: 'model',
  660. datasource: 'mongodb',
  661. properties: {
  662. myId: {
  663. type: DataType.ANY,
  664. primaryKey: true,
  665. },
  666. },
  667. });
  668. const rep = schema.getRepository('model');
  669. const promise = rep.replaceById('id', {foo: 10});
  670. await expect(promise).to.be.rejectedWith(
  671. 'MongoDB is not supporting custom names of the primary key. ' +
  672. 'Do use "id" as a primary key instead of "myId".',
  673. );
  674. });
  675. it('uses a specified column name for a regular property', async function () {
  676. const schema = createSchema();
  677. schema.defineModel({
  678. name: 'model',
  679. datasource: 'mongodb',
  680. properties: {
  681. foo: {
  682. type: DataType.NUMBER,
  683. columnName: 'bar',
  684. },
  685. },
  686. });
  687. const rep = schema.getRepository('model');
  688. const created = await rep.create({foo: 10});
  689. const id = created[DEF_PK];
  690. const replaced = await rep.replaceById(id, {foo: 20});
  691. expect(replaced).to.be.eql({[DEF_PK]: id, foo: 20});
  692. const oid = new ObjectId(id);
  693. const rawData = await MDB_CLIENT.db()
  694. .collection('model')
  695. .findOne({_id: oid});
  696. expect(rawData).to.be.eql({_id: oid, bar: 20});
  697. });
  698. it('stores a Date instance as date and returns string type', async function () {
  699. const schema = createSchema();
  700. schema.defineModel({name: 'model', datasource: 'mongodb'});
  701. const rep = schema.getRepository('model');
  702. const date = new Date();
  703. const dateString = date.toISOString();
  704. const created = await rep.create({date: null});
  705. const id = created[DEF_PK];
  706. const replaced = await rep.replaceById(id, {date});
  707. expect(replaced).to.be.eql({[DEF_PK]: id, date: dateString});
  708. const oid = new ObjectId(id);
  709. const rawData = await MDB_CLIENT.db()
  710. .collection('model')
  711. .findOne({_id: oid});
  712. expect(rawData).to.be.eql({_id: oid, date});
  713. });
  714. it('stores a Date string as date and returns string type', async function () {
  715. const schema = createSchema();
  716. schema.defineModel({name: 'model', datasource: 'mongodb'});
  717. const rep = schema.getRepository('model');
  718. const date = new Date();
  719. const dateString = date.toISOString();
  720. const created = await rep.create({date: null});
  721. const id = created[DEF_PK];
  722. const replaced = await rep.replaceById(id, {date: dateString});
  723. expect(replaced).to.be.eql({[DEF_PK]: id, date: dateString});
  724. const oid = new ObjectId(id);
  725. const rawData = await MDB_CLIENT.db()
  726. .collection('model')
  727. .findOne({_id: oid});
  728. expect(rawData).to.be.eql({_id: oid, date});
  729. });
  730. it('stores a string as is', async function () {
  731. const schema = createSchema();
  732. schema.defineModel({name: 'model', datasource: 'mongodb'});
  733. const rep = schema.getRepository('model');
  734. const created = await rep.create({foo: null});
  735. const id = created[DEF_PK];
  736. const replaced = await rep.replaceById(id, {foo: 'str'});
  737. expect(replaced).to.be.eql({[DEF_PK]: id, foo: 'str'});
  738. const oid = new ObjectId(id);
  739. const rawData = await MDB_CLIENT.db()
  740. .collection('model')
  741. .findOne({_id: oid});
  742. expect(rawData).to.be.eql({_id: oid, foo: 'str'});
  743. });
  744. it('stores a number as is', async function () {
  745. const schema = createSchema();
  746. schema.defineModel({name: 'model', datasource: 'mongodb'});
  747. const rep = schema.getRepository('model');
  748. const created = await rep.create({foo: null});
  749. const id = created[DEF_PK];
  750. const replaced = await rep.replaceById(id, {foo: 10});
  751. expect(replaced).to.be.eql({[DEF_PK]: id, foo: 10});
  752. const oid = new ObjectId(id);
  753. const rawData = await MDB_CLIENT.db()
  754. .collection('model')
  755. .findOne({_id: oid});
  756. expect(rawData).to.be.eql({_id: oid, foo: 10});
  757. });
  758. it('stores a boolean as is', async function () {
  759. const schema = createSchema();
  760. schema.defineModel({name: 'model', datasource: 'mongodb'});
  761. const rep = schema.getRepository('model');
  762. const created = await rep.create({foo: null, bar: null});
  763. const id = created[DEF_PK];
  764. const replaced = await rep.replaceById(id, {foo: true, bar: false});
  765. expect(replaced).to.be.eql({[DEF_PK]: id, foo: true, bar: false});
  766. const oid = new ObjectId(id);
  767. const rawData = await MDB_CLIENT.db()
  768. .collection('model')
  769. .findOne({_id: oid});
  770. expect(rawData).to.be.eql({_id: oid, foo: true, bar: false});
  771. });
  772. it('stores an array as is', async function () {
  773. const schema = createSchema();
  774. schema.defineModel({name: 'model', datasource: 'mongodb'});
  775. const rep = schema.getRepository('model');
  776. const created = await rep.create({foo: null});
  777. const id = created[DEF_PK];
  778. const replaced = await rep.replaceById(id, {foo: ['bar']});
  779. expect(replaced).to.be.eql({[DEF_PK]: id, foo: ['bar']});
  780. const oid = new ObjectId(id);
  781. const rawData = await MDB_CLIENT.db()
  782. .collection('model')
  783. .findOne({_id: oid});
  784. expect(rawData).to.be.eql({_id: oid, foo: ['bar']});
  785. });
  786. it('stores an object as is', async function () {
  787. const schema = createSchema();
  788. schema.defineModel({name: 'model', datasource: 'mongodb'});
  789. const rep = schema.getRepository('model');
  790. const created = await rep.create({foo: null});
  791. const id = created[DEF_PK];
  792. const replaced = await rep.replaceById(id, {foo: {bar: 10}});
  793. expect(replaced).to.be.eql({[DEF_PK]: id, foo: {bar: 10}});
  794. const oid = new ObjectId(id);
  795. const rawData = await MDB_CLIENT.db()
  796. .collection('model')
  797. .findOne({_id: oid});
  798. expect(rawData).to.be.eql({_id: oid, foo: {bar: 10}});
  799. });
  800. it('stores an undefined as null', async function () {
  801. const schema = createSchema();
  802. schema.defineModel({name: 'model', datasource: 'mongodb'});
  803. const rep = schema.getRepository('model');
  804. const created = await rep.create({foo: 10});
  805. const id = created[DEF_PK];
  806. const replaced = await rep.replaceById(id, {foo: undefined});
  807. expect(replaced).to.be.eql({[DEF_PK]: id, foo: null});
  808. const oid = new ObjectId(id);
  809. const rawData = await MDB_CLIENT.db()
  810. .collection('model')
  811. .findOne({_id: oid});
  812. expect(rawData).to.be.eql({_id: oid, foo: null});
  813. });
  814. it('stores an null as is', async function () {
  815. const schema = createSchema();
  816. schema.defineModel({name: 'model', datasource: 'mongodb'});
  817. const rep = schema.getRepository('model');
  818. const created = await rep.create({foo: 10});
  819. const id = created[DEF_PK];
  820. const replaced = await rep.replaceById(id, {foo: null});
  821. expect(replaced).to.be.eql({[DEF_PK]: id, foo: null});
  822. const oid = new ObjectId(id);
  823. const rawData = await MDB_CLIENT.db()
  824. .collection('model')
  825. .findOne({_id: oid});
  826. expect(rawData).to.be.eql({_id: oid, foo: null});
  827. });
  828. it('uses a short fields clause to filter results', async function () {
  829. const schema = createSchema();
  830. schema.defineModel({name: 'model', datasource: 'mongodb'});
  831. const rep = schema.getRepository('model');
  832. const created = await rep.create({foo: 10, bar: 20});
  833. const id = created[DEF_PK];
  834. const replaced = await rep.replaceById(
  835. id,
  836. {foo: 15, bar: 25},
  837. {fields: 'foo'},
  838. );
  839. expect(replaced).to.be.eql({[DEF_PK]: id, foo: 15});
  840. const oid = new ObjectId(id);
  841. const rawData = await MDB_CLIENT.db()
  842. .collection('model')
  843. .findOne({_id: oid});
  844. expect(rawData).to.be.eql({_id: oid, foo: 15, bar: 25});
  845. });
  846. it('uses a full fields clause to filter results', async function () {
  847. const schema = createSchema();
  848. schema.defineModel({name: 'model', datasource: 'mongodb'});
  849. const rep = schema.getRepository('model');
  850. const created = await rep.create({foo: 10, bar: 20, baz: 30});
  851. const id = created[DEF_PK];
  852. const replaced = await rep.replaceById(
  853. id,
  854. {foo: 15, bar: 25, baz: 35},
  855. {fields: ['foo', 'bar']},
  856. );
  857. expect(replaced).to.be.eql({[DEF_PK]: id, foo: 15, bar: 25});
  858. const oid = new ObjectId(id);
  859. const rawData = await MDB_CLIENT.db()
  860. .collection('model')
  861. .findOne({_id: oid});
  862. expect(rawData).to.be.eql({_id: oid, foo: 15, bar: 25, baz: 35});
  863. });
  864. it('a fields clause uses property names instead of column names', async function () {
  865. const schema = createSchema();
  866. schema.defineModel({
  867. name: 'model',
  868. datasource: 'mongodb',
  869. properties: {
  870. foo: {
  871. type: DataType.NUMBER,
  872. columnName: 'fooCol',
  873. },
  874. bar: {
  875. type: DataType.NUMBER,
  876. columnName: 'barCol',
  877. },
  878. baz: {
  879. type: DataType.NUMBER,
  880. columnName: 'bazCol',
  881. },
  882. },
  883. });
  884. const rep = schema.getRepository('model');
  885. const created = await rep.create(
  886. {foo: 10, bar: 20, baz: 30},
  887. {fields: ['fooCol', 'barCol']},
  888. );
  889. const id = created[DEF_PK];
  890. const replaced = await rep.replaceById(
  891. id,
  892. {foo: 15, bar: 25, baz: 35},
  893. {fields: ['fooCol', 'barCol']},
  894. );
  895. expect(replaced).to.be.eql({[DEF_PK]: replaced[DEF_PK]});
  896. const oid = new ObjectId(id);
  897. const rawData = await MDB_CLIENT.db()
  898. .collection('model')
  899. .findOne({_id: oid});
  900. expect(rawData).to.be.eql({_id: oid, fooCol: 15, barCol: 25, bazCol: 35});
  901. });
  902. });
  903. describe('patchById', function () {
  904. it('updates only provided properties by a given identifier', async function () {
  905. const schema = createSchema();
  906. schema.defineModel({name: 'model', datasource: 'mongodb'});
  907. const rep = schema.getRepository('model');
  908. const created = await rep.create({foo: 10});
  909. const id = created[DEF_PK];
  910. const patched = await rep.patchById(id, {bar: 20});
  911. expect(patched).to.be.eql({[DEF_PK]: id, foo: 10, bar: 20});
  912. const oid = new ObjectId(id);
  913. const rawData = await MDB_CLIENT.db()
  914. .collection('model')
  915. .findOne({_id: oid});
  916. expect(rawData).to.be.eql({_id: oid, foo: 10, bar: 20});
  917. });
  918. it('does not throw an error if a partial data does not have required property', async function () {
  919. const schema = createSchema();
  920. schema.defineModel({
  921. name: 'model',
  922. datasource: 'mongodb',
  923. properties: {
  924. foo: {
  925. type: DataType.NUMBER,
  926. required: true,
  927. },
  928. },
  929. });
  930. const rep = schema.getRepository('model');
  931. const {insertedId: oid} = await MDB_CLIENT.db()
  932. .collection('model')
  933. .insertOne({bar: 10});
  934. const patched = await rep.patchById(oid, {baz: 20});
  935. const id = String(oid);
  936. expect(patched).to.be.eql({[DEF_PK]: id, bar: 10, baz: 20});
  937. const rawData = await MDB_CLIENT.db()
  938. .collection('model')
  939. .findOne({_id: oid});
  940. expect(rawData).to.be.eql({_id: oid, bar: 10, baz: 20});
  941. });
  942. it('ignores identifier value in a given data in case of a default primary key', async function () {
  943. const schema = createSchema();
  944. schema.defineModel({name: 'model', datasource: 'mongodb'});
  945. const rep = schema.getRepository('model');
  946. await rep.create({[DEF_PK]: 'foo', prop: 10});
  947. const patched = await rep.patchById('foo', {
  948. [DEF_PK]: 'bar',
  949. prop: 20,
  950. });
  951. expect(patched).to.be.eql({[DEF_PK]: 'foo', prop: 20});
  952. const rawData = await MDB_CLIENT.db()
  953. .collection('model')
  954. .findOne({_id: 'foo'});
  955. expect(rawData).to.be.eql({_id: 'foo', prop: 20});
  956. });
  957. it('ignores identifier value in a given data in case of a custom primary key', async function () {
  958. const schema = createSchema();
  959. schema.defineModel({
  960. name: 'model',
  961. datasource: 'mongodb',
  962. properties: {
  963. myId: {
  964. type: DataType.STRING,
  965. primaryKey: true,
  966. columnName: '_id',
  967. },
  968. },
  969. });
  970. const rep = schema.getRepository('model');
  971. await rep.create({myId: 'foo', prop: 10});
  972. const patched = await rep.patchById('foo', {myId: 'bar', prop: 20});
  973. expect(patched).to.be.eql({myId: 'foo', prop: 20});
  974. const rawData = await MDB_CLIENT.db()
  975. .collection('model')
  976. .findOne({_id: 'foo'});
  977. expect(rawData).to.be.eql({_id: 'foo', prop: 20});
  978. });
  979. it('throws an error if a given identifier does not exist', async function () {
  980. const schema = createSchema();
  981. schema.defineModel({name: 'model', datasource: 'mongodb'});
  982. const rep = schema.getRepository('model');
  983. const oid = new ObjectId();
  984. const promise = rep.patchById(oid, {foo: 10});
  985. await expect(promise).to.be.rejectedWith(
  986. format('Identifier "%s" is not found.', oid),
  987. );
  988. });
  989. it('throws an error for a custom primary key', async function () {
  990. const schema = createSchema();
  991. schema.defineModel({
  992. name: 'model',
  993. datasource: 'mongodb',
  994. properties: {
  995. myId: {
  996. type: DataType.ANY,
  997. primaryKey: true,
  998. },
  999. },
  1000. });
  1001. const rep = schema.getRepository('model');
  1002. const promise = rep.patchById('id', {foo: 10});
  1003. await expect(promise).to.be.rejectedWith(
  1004. 'MongoDB is not supporting custom names of the primary key. ' +
  1005. 'Do use "id" as a primary key instead of "myId".',
  1006. );
  1007. });
  1008. it('uses a specified column name for a regular property', async function () {
  1009. const schema = createSchema();
  1010. schema.defineModel({
  1011. name: 'model',
  1012. datasource: 'mongodb',
  1013. properties: {
  1014. foo: {
  1015. type: DataType.NUMBER,
  1016. columnName: 'bar',
  1017. },
  1018. },
  1019. });
  1020. const rep = schema.getRepository('model');
  1021. const created = await rep.create({foo: 10});
  1022. const id = created[DEF_PK];
  1023. const patched = await rep.replaceById(id, {foo: 20});
  1024. expect(patched).to.be.eql({[DEF_PK]: id, foo: 20});
  1025. const oid = new ObjectId(id);
  1026. const rawData = await MDB_CLIENT.db()
  1027. .collection('model')
  1028. .findOne({_id: oid});
  1029. expect(rawData).to.be.eql({_id: oid, bar: 20});
  1030. });
  1031. it('stores a Date instance as date and returns string type', async function () {
  1032. const schema = createSchema();
  1033. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1034. const rep = schema.getRepository('model');
  1035. const date = new Date();
  1036. const dateString = date.toISOString();
  1037. const created = await rep.create({date: null});
  1038. const id = created[DEF_PK];
  1039. const patched = await rep.patchById(id, {date});
  1040. expect(patched).to.be.eql({[DEF_PK]: id, date: dateString});
  1041. const oid = new ObjectId(id);
  1042. const rawData = await MDB_CLIENT.db()
  1043. .collection('model')
  1044. .findOne({_id: oid});
  1045. expect(rawData).to.be.eql({_id: oid, date});
  1046. });
  1047. it('stores a Date string as date and returns string type', async function () {
  1048. const schema = createSchema();
  1049. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1050. const rep = schema.getRepository('model');
  1051. const date = new Date();
  1052. const dateString = date.toISOString();
  1053. const created = await rep.create({date: null});
  1054. const id = created[DEF_PK];
  1055. const patched = await rep.patchById(id, {date: dateString});
  1056. expect(patched).to.be.eql({[DEF_PK]: id, date: dateString});
  1057. const oid = new ObjectId(id);
  1058. const rawData = await MDB_CLIENT.db()
  1059. .collection('model')
  1060. .findOne({_id: oid});
  1061. expect(rawData).to.be.eql({_id: oid, date});
  1062. });
  1063. it('stores a string as is', async function () {
  1064. const schema = createSchema();
  1065. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1066. const rep = schema.getRepository('model');
  1067. const created = await rep.create({foo: null});
  1068. const id = created[DEF_PK];
  1069. const patched = await rep.patchById(id, {foo: 'str'});
  1070. expect(patched).to.be.eql({[DEF_PK]: id, foo: 'str'});
  1071. const oid = new ObjectId(id);
  1072. const rawData = await MDB_CLIENT.db()
  1073. .collection('model')
  1074. .findOne({_id: oid});
  1075. expect(rawData).to.be.eql({_id: oid, foo: 'str'});
  1076. });
  1077. it('stores a number as is', async function () {
  1078. const schema = createSchema();
  1079. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1080. const rep = schema.getRepository('model');
  1081. const created = await rep.create({foo: null});
  1082. const id = created[DEF_PK];
  1083. const patched = await rep.patchById(id, {foo: 10});
  1084. expect(patched).to.be.eql({[DEF_PK]: id, foo: 10});
  1085. const oid = new ObjectId(id);
  1086. const rawData = await MDB_CLIENT.db()
  1087. .collection('model')
  1088. .findOne({_id: oid});
  1089. expect(rawData).to.be.eql({_id: oid, foo: 10});
  1090. });
  1091. it('stores a boolean as is', async function () {
  1092. const schema = createSchema();
  1093. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1094. const rep = schema.getRepository('model');
  1095. const created = await rep.create({foo: null, bar: null});
  1096. const id = created[DEF_PK];
  1097. const patched = await rep.patchById(id, {foo: true, bar: false});
  1098. expect(patched).to.be.eql({[DEF_PK]: id, foo: true, bar: false});
  1099. const oid = new ObjectId(id);
  1100. const rawData = await MDB_CLIENT.db()
  1101. .collection('model')
  1102. .findOne({_id: oid});
  1103. expect(rawData).to.be.eql({_id: oid, foo: true, bar: false});
  1104. });
  1105. it('stores an array as is', async function () {
  1106. const schema = createSchema();
  1107. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1108. const rep = schema.getRepository('model');
  1109. const created = await rep.create({foo: null});
  1110. const id = created[DEF_PK];
  1111. const patched = await rep.patchById(id, {foo: ['bar']});
  1112. expect(patched).to.be.eql({[DEF_PK]: id, foo: ['bar']});
  1113. const oid = new ObjectId(id);
  1114. const rawData = await MDB_CLIENT.db()
  1115. .collection('model')
  1116. .findOne({_id: oid});
  1117. expect(rawData).to.be.eql({_id: oid, foo: ['bar']});
  1118. });
  1119. it('stores an object as is', async function () {
  1120. const schema = createSchema();
  1121. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1122. const rep = schema.getRepository('model');
  1123. const created = await rep.create({foo: null});
  1124. const id = created[DEF_PK];
  1125. const patched = await rep.patchById(id, {foo: {bar: 10}});
  1126. expect(patched).to.be.eql({[DEF_PK]: id, foo: {bar: 10}});
  1127. const oid = new ObjectId(id);
  1128. const rawData = await MDB_CLIENT.db()
  1129. .collection('model')
  1130. .findOne({_id: oid});
  1131. expect(rawData).to.be.eql({_id: oid, foo: {bar: 10}});
  1132. });
  1133. it('stores an undefined as null', async function () {
  1134. const schema = createSchema();
  1135. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1136. const rep = schema.getRepository('model');
  1137. const created = await rep.create({foo: 10});
  1138. const id = created[DEF_PK];
  1139. const patched = await rep.patchById(id, {foo: undefined});
  1140. expect(patched).to.be.eql({[DEF_PK]: id, foo: null});
  1141. const oid = new ObjectId(id);
  1142. const rawData = await MDB_CLIENT.db()
  1143. .collection('model')
  1144. .findOne({_id: oid});
  1145. expect(rawData).to.be.eql({_id: oid, foo: null});
  1146. });
  1147. it('stores an null as is', async function () {
  1148. const schema = createSchema();
  1149. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1150. const rep = schema.getRepository('model');
  1151. const created = await rep.create({foo: 10});
  1152. const id = created[DEF_PK];
  1153. const patched = await rep.patchById(id, {foo: null});
  1154. expect(patched).to.be.eql({[DEF_PK]: id, foo: null});
  1155. const oid = new ObjectId(id);
  1156. const rawData = await MDB_CLIENT.db()
  1157. .collection('model')
  1158. .findOne({_id: oid});
  1159. expect(rawData).to.be.eql({_id: oid, foo: null});
  1160. });
  1161. it('uses a short fields clause to filter results', async function () {
  1162. const schema = createSchema();
  1163. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1164. const rep = schema.getRepository('model');
  1165. const created = await rep.create({foo: 10, bar: 20});
  1166. const id = created[DEF_PK];
  1167. const patched = await rep.patchById(
  1168. id,
  1169. {foo: 15, bar: 25},
  1170. {fields: 'foo'},
  1171. );
  1172. expect(patched).to.be.eql({[DEF_PK]: id, foo: 15});
  1173. const oid = new ObjectId(id);
  1174. const rawData = await MDB_CLIENT.db()
  1175. .collection('model')
  1176. .findOne({_id: oid});
  1177. expect(rawData).to.be.eql({_id: oid, foo: 15, bar: 25});
  1178. });
  1179. it('uses a full fields clause to filter results', async function () {
  1180. const schema = createSchema();
  1181. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1182. const rep = schema.getRepository('model');
  1183. const created = await rep.create({foo: 10, bar: 20, baz: 30});
  1184. const id = created[DEF_PK];
  1185. const patched = await rep.patchById(
  1186. id,
  1187. {foo: 15, bar: 25, baz: 35},
  1188. {fields: ['foo', 'bar']},
  1189. );
  1190. expect(patched).to.be.eql({[DEF_PK]: id, foo: 15, bar: 25});
  1191. const oid = new ObjectId(id);
  1192. const rawData = await MDB_CLIENT.db()
  1193. .collection('model')
  1194. .findOne({_id: oid});
  1195. expect(rawData).to.be.eql({_id: oid, foo: 15, bar: 25, baz: 35});
  1196. });
  1197. it('a fields clause uses property names instead of column names', async function () {
  1198. const schema = createSchema();
  1199. schema.defineModel({
  1200. name: 'model',
  1201. datasource: 'mongodb',
  1202. properties: {
  1203. foo: {
  1204. type: DataType.NUMBER,
  1205. columnName: 'fooCol',
  1206. },
  1207. bar: {
  1208. type: DataType.NUMBER,
  1209. columnName: 'barCol',
  1210. },
  1211. baz: {
  1212. type: DataType.NUMBER,
  1213. columnName: 'bazCol',
  1214. },
  1215. },
  1216. });
  1217. const rep = schema.getRepository('model');
  1218. const created = await rep.create(
  1219. {foo: 10, bar: 20, baz: 30},
  1220. {fields: ['fooCol', 'barCol']},
  1221. );
  1222. const id = created[DEF_PK];
  1223. const patched = await rep.patchById(
  1224. id,
  1225. {foo: 15, bar: 25, baz: 35},
  1226. {fields: ['fooCol', 'barCol']},
  1227. );
  1228. expect(patched).to.be.eql({[DEF_PK]: patched[DEF_PK]});
  1229. const oid = new ObjectId(id);
  1230. const rawData = await MDB_CLIENT.db()
  1231. .collection('model')
  1232. .findOne({_id: oid});
  1233. expect(rawData).to.be.eql({_id: oid, fooCol: 15, barCol: 25, bazCol: 35});
  1234. });
  1235. });
  1236. describe('find', function () {
  1237. it('returns an empty array', async function () {
  1238. const schema = createSchema();
  1239. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1240. const rep = schema.getRepository('model');
  1241. const result = await rep.find();
  1242. expect(result).to.be.empty;
  1243. expect(result).to.be.instanceOf(Array);
  1244. });
  1245. it('returns all items', async function () {
  1246. const schema = createSchema();
  1247. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1248. const rep = schema.getRepository('model');
  1249. const doc1 = await rep.create({foo: 1});
  1250. const doc2 = await rep.create({bar: 2});
  1251. const doc3 = await rep.create({baz: 3});
  1252. const result = await rep.find();
  1253. expect(result).to.be.eql([doc1, doc2, doc3]);
  1254. });
  1255. it('uses a short fields clause to filter results', async function () {
  1256. const schema = createSchema();
  1257. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1258. const rep = schema.getRepository('model');
  1259. const created1 = await rep.create({foo: 10, bar: 20});
  1260. const created2 = await rep.create({foo: 20, bar: 30});
  1261. const id1 = created1[DEF_PK];
  1262. const id2 = created2[DEF_PK];
  1263. const result = await rep.find({fields: 'foo'});
  1264. expect(result).to.be.eql([
  1265. {[DEF_PK]: id1, foo: 10},
  1266. {[DEF_PK]: id2, foo: 20},
  1267. ]);
  1268. });
  1269. it('uses a full fields clause to filter results', async function () {
  1270. const schema = createSchema();
  1271. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1272. const rep = schema.getRepository('model');
  1273. const created1 = await rep.create({foo: 10, bar: 20, baz: 30});
  1274. const created2 = await rep.create({foo: 20, bar: 30, baz: 40});
  1275. const id1 = created1[DEF_PK];
  1276. const id2 = created2[DEF_PK];
  1277. const result = await rep.find({fields: ['foo', 'bar']});
  1278. expect(result).to.be.eql([
  1279. {[DEF_PK]: id1, foo: 10, bar: 20},
  1280. {[DEF_PK]: id2, foo: 20, bar: 30},
  1281. ]);
  1282. });
  1283. it('a fields clause uses property names instead of column names', async function () {
  1284. const schema = createSchema();
  1285. schema.defineModel({
  1286. name: 'model',
  1287. datasource: 'mongodb',
  1288. properties: {
  1289. foo: {
  1290. type: DataType.NUMBER,
  1291. columnName: 'fooCol',
  1292. },
  1293. bar: {
  1294. type: DataType.NUMBER,
  1295. columnName: 'barCol',
  1296. },
  1297. baz: {
  1298. type: DataType.NUMBER,
  1299. columnName: 'bazCol',
  1300. },
  1301. },
  1302. });
  1303. const rep = schema.getRepository('model');
  1304. const created1 = await rep.create({foo: 10, bar: 20, baz: 30});
  1305. const created2 = await rep.create({foo: 20, bar: 30, baz: 40});
  1306. const id1 = created1[DEF_PK];
  1307. const id2 = created2[DEF_PK];
  1308. const result = await rep.find({fields: ['fooCol', 'barCol']});
  1309. expect(result).to.be.eql([{[DEF_PK]: id1}, {[DEF_PK]: id2}]);
  1310. });
  1311. it('uses a short order clause to sort results', async function () {
  1312. const schema = createSchema();
  1313. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1314. const rep = schema.getRepository('model');
  1315. const created1 = await rep.create({foo: 20});
  1316. const created2 = await rep.create({foo: 5});
  1317. const created3 = await rep.create({foo: 10});
  1318. const result1 = await rep.find({order: 'foo'});
  1319. const result2 = await rep.find({order: 'foo ASC'});
  1320. const result3 = await rep.find({order: 'foo DESC'});
  1321. expect(result1).to.be.eql([
  1322. {[DEF_PK]: created2[DEF_PK], foo: 5},
  1323. {[DEF_PK]: created3[DEF_PK], foo: 10},
  1324. {[DEF_PK]: created1[DEF_PK], foo: 20},
  1325. ]);
  1326. expect(result2).to.be.eql([
  1327. {[DEF_PK]: created2[DEF_PK], foo: 5},
  1328. {[DEF_PK]: created3[DEF_PK], foo: 10},
  1329. {[DEF_PK]: created1[DEF_PK], foo: 20},
  1330. ]);
  1331. expect(result3).to.be.eql([
  1332. {[DEF_PK]: created1[DEF_PK], foo: 20},
  1333. {[DEF_PK]: created3[DEF_PK], foo: 10},
  1334. {[DEF_PK]: created2[DEF_PK], foo: 5},
  1335. ]);
  1336. });
  1337. it('uses a full order clause to sort results', async function () {
  1338. const schema = createSchema();
  1339. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1340. const rep = schema.getRepository('model');
  1341. const created1 = await rep.create({foo: 20, bar: 'b'});
  1342. const created2 = await rep.create({foo: 5, bar: 'b'});
  1343. const created3 = await rep.create({foo: 10, bar: 'a'});
  1344. const result1 = await rep.find({order: ['bar DESC', 'foo']});
  1345. const result2 = await rep.find({order: ['bar', 'foo ASC']});
  1346. expect(result1).to.be.eql([
  1347. {[DEF_PK]: created2[DEF_PK], foo: 5, bar: 'b'},
  1348. {[DEF_PK]: created1[DEF_PK], foo: 20, bar: 'b'},
  1349. {[DEF_PK]: created3[DEF_PK], foo: 10, bar: 'a'},
  1350. ]);
  1351. expect(result2).to.be.eql([
  1352. {[DEF_PK]: created3[DEF_PK], foo: 10, bar: 'a'},
  1353. {[DEF_PK]: created2[DEF_PK], foo: 5, bar: 'b'},
  1354. {[DEF_PK]: created1[DEF_PK], foo: 20, bar: 'b'},
  1355. ]);
  1356. });
  1357. it('an order clause uses property names instead of column names', async function () {
  1358. const schema = createSchema();
  1359. schema.defineModel({
  1360. name: 'model',
  1361. datasource: 'mongodb',
  1362. properties: {
  1363. foo: {
  1364. type: DataType.NUMBER,
  1365. columnName: 'fooCol',
  1366. },
  1367. bar: {
  1368. type: DataType.STRING,
  1369. columnName: 'barCol',
  1370. },
  1371. },
  1372. });
  1373. const rep = schema.getRepository('model');
  1374. const created1 = await rep.create({foo: 20, bar: 'b'});
  1375. const created2 = await rep.create({foo: 5, bar: 'b'});
  1376. const created3 = await rep.create({foo: 10, bar: 'a'});
  1377. const result1 = await rep.find({order: ['bar DESC', 'foo']});
  1378. const result2 = await rep.find({order: ['bar', 'foo ASC']});
  1379. expect(result1).to.be.eql([
  1380. {[DEF_PK]: created2[DEF_PK], foo: 5, bar: 'b'},
  1381. {[DEF_PK]: created1[DEF_PK], foo: 20, bar: 'b'},
  1382. {[DEF_PK]: created3[DEF_PK], foo: 10, bar: 'a'},
  1383. ]);
  1384. expect(result2).to.be.eql([
  1385. {[DEF_PK]: created3[DEF_PK], foo: 10, bar: 'a'},
  1386. {[DEF_PK]: created2[DEF_PK], foo: 5, bar: 'b'},
  1387. {[DEF_PK]: created1[DEF_PK], foo: 20, bar: 'b'},
  1388. ]);
  1389. });
  1390. it('uses a limit clause to filter results', async function () {
  1391. const schema = createSchema();
  1392. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1393. const rep = schema.getRepository('model');
  1394. const created1 = await rep.create({foo: 10});
  1395. const created2 = await rep.create({foo: 20});
  1396. await rep.create({foo: 30});
  1397. const result = await rep.find({limit: 2});
  1398. expect(result).to.be.eql([created1, created2]);
  1399. });
  1400. it('uses a skip clause to filter results', async function () {
  1401. const schema = createSchema();
  1402. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1403. const rep = schema.getRepository('model');
  1404. await rep.create({foo: 10});
  1405. const created2 = await rep.create({foo: 20});
  1406. const created3 = await rep.create({foo: 30});
  1407. const result = await rep.find({skip: 1});
  1408. expect(result).to.be.eql([created2, created3]);
  1409. });
  1410. describe('uses a where clause to filter results', function () {
  1411. it('matches by a document subset', async function () {
  1412. const schema = createSchema();
  1413. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1414. const rep = schema.getRepository('model');
  1415. const created1 = await rep.create({foo: 5, bar: 'b'});
  1416. const created2 = await rep.create({foo: 10, bar: 'a'});
  1417. const result1 = await rep.find({where: {foo: 10}});
  1418. const result2 = await rep.find({where: {foo: 5, bar: 'b'}});
  1419. expect(result1).to.be.eql([
  1420. {
  1421. [DEF_PK]: created2[DEF_PK],
  1422. foo: 10,
  1423. bar: 'a',
  1424. },
  1425. ]);
  1426. expect(result2).to.be.eql([
  1427. {
  1428. [DEF_PK]: created1[DEF_PK],
  1429. foo: 5,
  1430. bar: 'b',
  1431. },
  1432. ]);
  1433. });
  1434. it('matches by the "eq" operator', async function () {
  1435. const schema = createSchema();
  1436. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1437. const rep = schema.getRepository('model');
  1438. await rep.create({foo: 5});
  1439. const created2 = await rep.create({foo: 10});
  1440. const created3 = await rep.create({foo: 10});
  1441. const result = await rep.find({where: {foo: {eq: 10}}});
  1442. expect(result).to.be.eql([
  1443. {[DEF_PK]: created2[DEF_PK], foo: 10},
  1444. {[DEF_PK]: created3[DEF_PK], foo: 10},
  1445. ]);
  1446. });
  1447. it('matches by the "neq" operator', async function () {
  1448. const schema = createSchema();
  1449. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1450. const rep = schema.getRepository('model');
  1451. const created1 = await rep.create({foo: 5});
  1452. await rep.create({foo: 10});
  1453. await rep.create({foo: 10});
  1454. const result = await rep.find({where: {foo: {neq: 10}}});
  1455. expect(result).to.be.eql([{[DEF_PK]: created1[DEF_PK], foo: 5}]);
  1456. });
  1457. it('matches by the "gt" operator', async function () {
  1458. const schema = createSchema();
  1459. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1460. const rep = schema.getRepository('model');
  1461. await rep.create({foo: 5});
  1462. await rep.create({foo: 10});
  1463. const created3 = await rep.create({foo: 15});
  1464. const result = await rep.find({where: {foo: {gt: 10}}});
  1465. expect(result).to.be.eql([{[DEF_PK]: created3[DEF_PK], foo: 15}]);
  1466. });
  1467. it('matches by the "lt" operator', async function () {
  1468. const schema = createSchema();
  1469. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1470. const rep = schema.getRepository('model');
  1471. const created1 = await rep.create({foo: 5});
  1472. await rep.create({foo: 10});
  1473. await rep.create({foo: 15});
  1474. const result = await rep.find({where: {foo: {lt: 10}}});
  1475. expect(result).to.be.eql([{[DEF_PK]: created1[DEF_PK], foo: 5}]);
  1476. });
  1477. it('matches by the "gte" operator', async function () {
  1478. const schema = createSchema();
  1479. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1480. const rep = schema.getRepository('model');
  1481. await rep.create({foo: 5});
  1482. const created2 = await rep.create({foo: 10});
  1483. const created3 = await rep.create({foo: 15});
  1484. const result = await rep.find({where: {foo: {gte: 10}}});
  1485. expect(result).to.be.eql([
  1486. {[DEF_PK]: created2[DEF_PK], foo: 10},
  1487. {[DEF_PK]: created3[DEF_PK], foo: 15},
  1488. ]);
  1489. });
  1490. it('matches by the "lte" operator', async function () {
  1491. const schema = createSchema();
  1492. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1493. const rep = schema.getRepository('model');
  1494. const created1 = await rep.create({foo: 5});
  1495. const created2 = await rep.create({foo: 10});
  1496. await rep.create({foo: 15});
  1497. const result = await rep.find({where: {foo: {lte: 10}}});
  1498. expect(result).to.be.eql([
  1499. {[DEF_PK]: created1[DEF_PK], foo: 5},
  1500. {[DEF_PK]: created2[DEF_PK], foo: 10},
  1501. ]);
  1502. });
  1503. it('matches by the "inq" operator', async function () {
  1504. const schema = createSchema();
  1505. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1506. const rep = schema.getRepository('model');
  1507. const created1 = await rep.create({foo: 5});
  1508. const created2 = await rep.create({foo: 10});
  1509. await rep.create({foo: 15});
  1510. const result = await rep.find({where: {foo: {inq: [5, 10]}}});
  1511. expect(result).to.be.eql([
  1512. {[DEF_PK]: created1[DEF_PK], foo: 5},
  1513. {[DEF_PK]: created2[DEF_PK], foo: 10},
  1514. ]);
  1515. });
  1516. it('matches by the "nin" operator', async function () {
  1517. const schema = createSchema();
  1518. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1519. const rep = schema.getRepository('model');
  1520. await rep.create({foo: 5});
  1521. await rep.create({foo: 10});
  1522. const created3 = await rep.create({foo: 15});
  1523. const result = await rep.find({where: {foo: {nin: [5, 10]}}});
  1524. expect(result).to.be.eql([{[DEF_PK]: created3[DEF_PK], foo: 15}]);
  1525. });
  1526. it('matches by the "between" operator', async function () {
  1527. const schema = createSchema();
  1528. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1529. const rep = schema.getRepository('model');
  1530. await rep.create({foo: 5});
  1531. const created2 = await rep.create({foo: 10});
  1532. const created3 = await rep.create({foo: 15});
  1533. await rep.create({foo: 20});
  1534. const result = await rep.find({where: {foo: {between: [9, 16]}}});
  1535. expect(result).to.be.eql([
  1536. {[DEF_PK]: created2[DEF_PK], foo: 10},
  1537. {[DEF_PK]: created3[DEF_PK], foo: 15},
  1538. ]);
  1539. });
  1540. it('matches by the "exists" operator', async function () {
  1541. const schema = createSchema();
  1542. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1543. const rep = schema.getRepository('model');
  1544. const created1 = await rep.create({});
  1545. const created2 = await rep.create({foo: undefined});
  1546. const created3 = await rep.create({foo: null});
  1547. const created4 = await rep.create({foo: 10});
  1548. const result1 = await rep.find({where: {foo: {exists: true}}});
  1549. const result2 = await rep.find({where: {foo: {exists: false}}});
  1550. expect(result1).to.be.eql([
  1551. {[DEF_PK]: created2[DEF_PK], foo: null},
  1552. {[DEF_PK]: created3[DEF_PK], foo: null},
  1553. {[DEF_PK]: created4[DEF_PK], foo: 10},
  1554. ]);
  1555. expect(result2).to.be.eql([{[DEF_PK]: created1[DEF_PK]}]);
  1556. });
  1557. it('matches by the "like" operator', async function () {
  1558. const schema = createSchema();
  1559. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1560. const rep = schema.getRepository('model');
  1561. await rep.create({foo: 'lorem ipsum'});
  1562. const created2 = await rep.create({foo: 'dolor sit amet'});
  1563. await rep.create({foo: 'DOLOR SIT AMET'});
  1564. const created4 = await rep.create({foo: 'sit amet'});
  1565. const result = await rep.find({where: {foo: {like: 'sit amet'}}});
  1566. expect(result).to.be.eql([
  1567. {[DEF_PK]: created2[DEF_PK], foo: 'dolor sit amet'},
  1568. {[DEF_PK]: created4[DEF_PK], foo: 'sit amet'},
  1569. ]);
  1570. });
  1571. it('matches by the "ilike" operator', async function () {
  1572. const schema = createSchema();
  1573. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1574. const rep = schema.getRepository('model');
  1575. await rep.create({foo: 'lorem ipsum'});
  1576. const created2 = await rep.create({foo: 'dolor sit amet'});
  1577. const created3 = await rep.create({foo: 'DOLOR SIT AMET'});
  1578. const created4 = await rep.create({foo: 'sit amet'});
  1579. const result = await rep.find({where: {foo: {ilike: 'sit amet'}}});
  1580. expect(result).to.be.eql([
  1581. {[DEF_PK]: created2[DEF_PK], foo: 'dolor sit amet'},
  1582. {[DEF_PK]: created3[DEF_PK], foo: 'DOLOR SIT AMET'},
  1583. {[DEF_PK]: created4[DEF_PK], foo: 'sit amet'},
  1584. ]);
  1585. });
  1586. it('matches by the "nlike" operator', async function () {
  1587. const schema = createSchema();
  1588. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1589. const rep = schema.getRepository('model');
  1590. const created1 = await rep.create({foo: 'lorem ipsum'});
  1591. await rep.create({foo: 'dolor sit amet'});
  1592. const created3 = await rep.create({foo: 'DOLOR SIT AMET'});
  1593. await rep.create({foo: 'sit amet'});
  1594. const result = await rep.find({where: {foo: {nlike: 'sit amet'}}});
  1595. expect(result).to.be.eql([
  1596. {[DEF_PK]: created1[DEF_PK], foo: 'lorem ipsum'},
  1597. {[DEF_PK]: created3[DEF_PK], foo: 'DOLOR SIT AMET'},
  1598. ]);
  1599. });
  1600. it('matches by the "nilike" operator', async function () {
  1601. const schema = createSchema();
  1602. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1603. const rep = schema.getRepository('model');
  1604. const created1 = await rep.create({foo: 'lorem ipsum'});
  1605. await rep.create({foo: 'dolor sit amet'});
  1606. await rep.create({foo: 'DOLOR SIT AMET'});
  1607. await rep.create({foo: 'sit amet'});
  1608. const result = await rep.find({where: {foo: {nilike: 'sit amet'}}});
  1609. expect(result).to.be.eql([
  1610. {[DEF_PK]: created1[DEF_PK], foo: 'lorem ipsum'},
  1611. ]);
  1612. });
  1613. it('matches by the "regexp" operator', async function () {
  1614. const schema = createSchema();
  1615. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1616. const rep = schema.getRepository('model');
  1617. await rep.create({foo: 'lorem ipsum'});
  1618. const created2 = await rep.create({foo: 'dolor sit amet'});
  1619. await rep.create({foo: 'DOLOR SIT AMET'});
  1620. const created4 = await rep.create({foo: 'sit amet'});
  1621. const result = await rep.find({where: {foo: {regexp: 'sit am+'}}});
  1622. expect(result).to.be.eql([
  1623. {[DEF_PK]: created2[DEF_PK], foo: 'dolor sit amet'},
  1624. {[DEF_PK]: created4[DEF_PK], foo: 'sit amet'},
  1625. ]);
  1626. });
  1627. it('matches by the "regexp" operator with flags', async function () {
  1628. const schema = createSchema();
  1629. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1630. const rep = schema.getRepository('model');
  1631. await rep.create({foo: 'lorem ipsum'});
  1632. const created2 = await rep.create({foo: 'dolor sit amet'});
  1633. const created3 = await rep.create({foo: 'DOLOR SIT AMET'});
  1634. const created4 = await rep.create({foo: 'sit amet'});
  1635. const result = await rep.find({
  1636. where: {
  1637. foo: {regexp: 'sit am+', flags: 'i'},
  1638. },
  1639. });
  1640. expect(result).to.be.eql([
  1641. {[DEF_PK]: created2[DEF_PK], foo: 'dolor sit amet'},
  1642. {[DEF_PK]: created3[DEF_PK], foo: 'DOLOR SIT AMET'},
  1643. {[DEF_PK]: created4[DEF_PK], foo: 'sit amet'},
  1644. ]);
  1645. });
  1646. });
  1647. });
  1648. describe('findById', function () {
  1649. it('throws an error if a given identifier does not exist', async function () {
  1650. const schema = createSchema();
  1651. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1652. const rep = schema.getRepository('model');
  1653. const oid = new ObjectId();
  1654. const promise = rep.findById(oid);
  1655. await expect(promise).to.be.rejectedWith(
  1656. format('Identifier "%s" is not found.', oid),
  1657. );
  1658. });
  1659. it('uses a short fields clause to filter results', async function () {
  1660. const schema = createSchema();
  1661. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1662. const rep = schema.getRepository('model');
  1663. const created = await rep.create({foo: 10, bar: 20});
  1664. const id = created[DEF_PK];
  1665. const result = await rep.findById(id, {fields: 'foo'});
  1666. expect(result).to.be.eql({[DEF_PK]: id, foo: 10});
  1667. });
  1668. it('uses a full fields clause to filter results', async function () {
  1669. const schema = createSchema();
  1670. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1671. const rep = schema.getRepository('model');
  1672. const created = await rep.create({foo: 10, bar: 20, baz: 30});
  1673. const id = created[DEF_PK];
  1674. const result = await rep.findById(id, {fields: ['foo', 'bar']});
  1675. expect(result).to.be.eql({[DEF_PK]: id, foo: 10, bar: 20});
  1676. });
  1677. });
  1678. describe('delete', function () {
  1679. it('removes all table items and returns their number', async function () {
  1680. const schema = createSchema();
  1681. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1682. const rep = schema.getRepository('model');
  1683. await rep.create({foo: 1});
  1684. await rep.create({foo: 2});
  1685. await rep.create({foo: 3});
  1686. const result = await rep.delete();
  1687. expect(result).to.be.eql(3);
  1688. const rawData = await MDB_CLIENT.db()
  1689. .collection('model')
  1690. .find()
  1691. .toArray();
  1692. expect(rawData).to.be.empty;
  1693. });
  1694. describe('removes by a where clause', function () {
  1695. it('removes by a document subset', async function () {
  1696. const schema = createSchema();
  1697. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1698. const rep = schema.getRepository('model');
  1699. const created1 = await rep.create({foo: 5});
  1700. await rep.create({foo: 10});
  1701. const result = await rep.delete({foo: 10});
  1702. expect(result).to.be.eq(1);
  1703. const rawData = await MDB_CLIENT.db()
  1704. .collection('model')
  1705. .find()
  1706. .toArray();
  1707. expect(rawData).to.be.eql([
  1708. {_id: new ObjectId(created1[DEF_PK]), foo: 5},
  1709. ]);
  1710. });
  1711. it('matches by the "eq" operator', async function () {
  1712. const schema = createSchema();
  1713. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1714. const rep = schema.getRepository('model');
  1715. const created1 = await rep.create({foo: 5});
  1716. await rep.create({foo: 10});
  1717. await rep.create({foo: 10});
  1718. const result = await rep.delete({foo: {eq: 10}});
  1719. expect(result).to.be.eq(2);
  1720. const rawData = await MDB_CLIENT.db()
  1721. .collection('model')
  1722. .find()
  1723. .toArray();
  1724. expect(rawData).to.be.eql([
  1725. {_id: new ObjectId(created1[DEF_PK]), foo: 5},
  1726. ]);
  1727. });
  1728. it('matches by the "neq" operator', async function () {
  1729. const schema = createSchema();
  1730. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1731. const rep = schema.getRepository('model');
  1732. await rep.create({foo: 5});
  1733. await rep.create({foo: 5});
  1734. const created3 = await rep.create({foo: 10});
  1735. const result = await rep.delete({foo: {neq: 10}});
  1736. expect(result).to.be.eq(2);
  1737. const rawData = await MDB_CLIENT.db()
  1738. .collection('model')
  1739. .find()
  1740. .toArray();
  1741. expect(rawData).to.be.eql([
  1742. {_id: new ObjectId(created3[DEF_PK]), foo: 10},
  1743. ]);
  1744. });
  1745. it('matches by the "gt" operator', async function () {
  1746. const schema = createSchema();
  1747. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1748. const rep = schema.getRepository('model');
  1749. const created1 = await rep.create({foo: 5});
  1750. const created2 = await rep.create({foo: 10});
  1751. await rep.create({foo: 15});
  1752. const result = await rep.delete({foo: {gt: 10}});
  1753. expect(result).to.be.eq(1);
  1754. const rawData = await MDB_CLIENT.db()
  1755. .collection('model')
  1756. .find()
  1757. .toArray();
  1758. expect(rawData).to.be.eql([
  1759. {_id: new ObjectId(created1[DEF_PK]), foo: 5},
  1760. {_id: new ObjectId(created2[DEF_PK]), foo: 10},
  1761. ]);
  1762. });
  1763. it('matches by the "lt" operator', async function () {
  1764. const schema = createSchema();
  1765. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1766. const rep = schema.getRepository('model');
  1767. await rep.create({foo: 5});
  1768. const created2 = await rep.create({foo: 10});
  1769. const created3 = await rep.create({foo: 15});
  1770. const result = await rep.delete({foo: {lt: 10}});
  1771. expect(result).to.be.eq(1);
  1772. const rawData = await MDB_CLIENT.db()
  1773. .collection('model')
  1774. .find()
  1775. .toArray();
  1776. expect(rawData).to.be.eql([
  1777. {_id: new ObjectId(created2[DEF_PK]), foo: 10},
  1778. {_id: new ObjectId(created3[DEF_PK]), foo: 15},
  1779. ]);
  1780. });
  1781. it('matches by the "gte" operator', async function () {
  1782. const schema = createSchema();
  1783. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1784. const rep = schema.getRepository('model');
  1785. const created1 = await rep.create({foo: 5});
  1786. await rep.create({foo: 10});
  1787. await rep.create({foo: 15});
  1788. const result = await rep.delete({foo: {gte: 10}});
  1789. expect(result).to.be.eq(2);
  1790. const rawData = await MDB_CLIENT.db()
  1791. .collection('model')
  1792. .find()
  1793. .toArray();
  1794. expect(rawData).to.be.eql([
  1795. {_id: new ObjectId(created1[DEF_PK]), foo: 5},
  1796. ]);
  1797. });
  1798. it('matches by the "lte" operator', async function () {
  1799. const schema = createSchema();
  1800. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1801. const rep = schema.getRepository('model');
  1802. await rep.create({foo: 5});
  1803. await rep.create({foo: 10});
  1804. const created3 = await rep.create({foo: 15});
  1805. const result = await rep.delete({foo: {lte: 10}});
  1806. expect(result).to.be.eq(2);
  1807. const rawData = await MDB_CLIENT.db()
  1808. .collection('model')
  1809. .find()
  1810. .toArray();
  1811. expect(rawData).to.be.eql([
  1812. {_id: new ObjectId(created3[DEF_PK]), foo: 15},
  1813. ]);
  1814. });
  1815. it('matches by the "inq" operator', async function () {
  1816. const schema = createSchema();
  1817. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1818. const rep = schema.getRepository('model');
  1819. await rep.create({foo: 5});
  1820. await rep.create({foo: 10});
  1821. const created3 = await rep.create({foo: 15});
  1822. const result = await rep.delete({foo: {inq: [5, 10]}});
  1823. expect(result).to.be.eq(2);
  1824. const rawData = await MDB_CLIENT.db()
  1825. .collection('model')
  1826. .find()
  1827. .toArray();
  1828. expect(rawData).to.be.eql([
  1829. {_id: new ObjectId(created3[DEF_PK]), foo: 15},
  1830. ]);
  1831. });
  1832. it('matches by the "nin" operator', async function () {
  1833. const schema = createSchema();
  1834. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1835. const rep = schema.getRepository('model');
  1836. const created1 = await rep.create({foo: 5});
  1837. const created2 = await rep.create({foo: 10});
  1838. await rep.create({foo: 15});
  1839. const result = await rep.delete({foo: {nin: [5, 10]}});
  1840. expect(result).to.be.eq(1);
  1841. const rawData = await MDB_CLIENT.db()
  1842. .collection('model')
  1843. .find()
  1844. .toArray();
  1845. expect(rawData).to.be.eql([
  1846. {_id: new ObjectId(created1[DEF_PK]), foo: 5},
  1847. {_id: new ObjectId(created2[DEF_PK]), foo: 10},
  1848. ]);
  1849. });
  1850. it('matches by the "between" operator', async function () {
  1851. const schema = createSchema();
  1852. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1853. const rep = schema.getRepository('model');
  1854. const created1 = await rep.create({foo: 5});
  1855. await rep.create({foo: 10});
  1856. await rep.create({foo: 15});
  1857. const created4 = await rep.create({foo: 20});
  1858. const result = await rep.delete({foo: {between: [9, 16]}});
  1859. expect(result).to.be.eq(2);
  1860. const rawData = await MDB_CLIENT.db()
  1861. .collection('model')
  1862. .find()
  1863. .toArray();
  1864. expect(rawData).to.be.eql([
  1865. {_id: new ObjectId(created1[DEF_PK]), foo: 5},
  1866. {_id: new ObjectId(created4[DEF_PK]), foo: 20},
  1867. ]);
  1868. });
  1869. it('matches by the "exists" operator', async function () {
  1870. const schema = createSchema();
  1871. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1872. const rep = schema.getRepository('model');
  1873. const created1 = await rep.create({});
  1874. await rep.create({foo: undefined});
  1875. await rep.create({foo: null});
  1876. await rep.create({foo: 10});
  1877. const result = await rep.delete({foo: {exists: true}});
  1878. expect(result).to.be.eq(3);
  1879. const rawData = await MDB_CLIENT.db()
  1880. .collection('model')
  1881. .find()
  1882. .toArray();
  1883. expect(rawData).to.be.eql([{_id: new ObjectId(created1[DEF_PK])}]);
  1884. });
  1885. it('matches by the "like" operator', async function () {
  1886. const schema = createSchema();
  1887. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1888. const rep = schema.getRepository('model');
  1889. const created1 = await rep.create({foo: 'lorem ipsum'});
  1890. await rep.create({foo: 'dolor sit amet'});
  1891. const created3 = await rep.create({foo: 'DOLOR SIT AMET'});
  1892. await rep.create({foo: 'sit amet'});
  1893. const result = await rep.delete({foo: {like: 'sit amet'}});
  1894. expect(result).to.be.eq(2);
  1895. const rawData = await MDB_CLIENT.db()
  1896. .collection('model')
  1897. .find()
  1898. .toArray();
  1899. expect(rawData).to.be.eql([
  1900. {_id: new ObjectId(created1[DEF_PK]), foo: 'lorem ipsum'},
  1901. {_id: new ObjectId(created3[DEF_PK]), foo: 'DOLOR SIT AMET'},
  1902. ]);
  1903. });
  1904. it('matches by the "nlike" operator', async function () {
  1905. const schema = createSchema();
  1906. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1907. const rep = schema.getRepository('model');
  1908. await rep.create({foo: 'lorem ipsum'});
  1909. const created2 = await rep.create({foo: 'dolor sit amet'});
  1910. await rep.create({foo: 'DOLOR SIT AMET'});
  1911. const created4 = await rep.create({foo: 'sit amet'});
  1912. const result = await rep.delete({foo: {nlike: 'sit amet'}});
  1913. expect(result).to.be.eq(2);
  1914. const rawData = await MDB_CLIENT.db()
  1915. .collection('model')
  1916. .find()
  1917. .toArray();
  1918. expect(rawData).to.be.eql([
  1919. {_id: new ObjectId(created2[DEF_PK]), foo: 'dolor sit amet'},
  1920. {_id: new ObjectId(created4[DEF_PK]), foo: 'sit amet'},
  1921. ]);
  1922. });
  1923. it('matches by the "ilike" operator', async function () {
  1924. const schema = createSchema();
  1925. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1926. const rep = schema.getRepository('model');
  1927. const created1 = await rep.create({foo: 'lorem ipsum'});
  1928. await rep.create({foo: 'dolor sit amet'});
  1929. await rep.create({foo: 'DOLOR SIT AMET'});
  1930. await rep.create({foo: 'sit amet'});
  1931. const result = await rep.delete({foo: {ilike: 'sit amet'}});
  1932. expect(result).to.be.eq(3);
  1933. const rawData = await MDB_CLIENT.db()
  1934. .collection('model')
  1935. .find()
  1936. .toArray();
  1937. expect(rawData).to.be.eql([
  1938. {_id: new ObjectId(created1[DEF_PK]), foo: 'lorem ipsum'},
  1939. ]);
  1940. });
  1941. it('matches by the "nilike" operator', async function () {
  1942. const schema = createSchema();
  1943. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1944. const rep = schema.getRepository('model');
  1945. await rep.create({foo: 'lorem ipsum'});
  1946. const created2 = await rep.create({foo: 'dolor sit amet'});
  1947. const created3 = await rep.create({foo: 'DOLOR SIT AMET'});
  1948. const created4 = await rep.create({foo: 'sit amet'});
  1949. const result = await rep.delete({foo: {nilike: 'sit amet'}});
  1950. expect(result).to.be.eq(1);
  1951. const rawData = await MDB_CLIENT.db()
  1952. .collection('model')
  1953. .find()
  1954. .toArray();
  1955. expect(rawData).to.be.eql([
  1956. {_id: new ObjectId(created2[DEF_PK]), foo: 'dolor sit amet'},
  1957. {_id: new ObjectId(created3[DEF_PK]), foo: 'DOLOR SIT AMET'},
  1958. {_id: new ObjectId(created4[DEF_PK]), foo: 'sit amet'},
  1959. ]);
  1960. });
  1961. it('matches by the "regexp" operator', async function () {
  1962. const schema = createSchema();
  1963. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1964. const rep = schema.getRepository('model');
  1965. const created1 = await rep.create({foo: 'lorem ipsum'});
  1966. await rep.create({foo: 'dolor sit amet'});
  1967. const created3 = await rep.create({foo: 'DOLOR SIT AMET'});
  1968. await rep.create({foo: 'sit amet'});
  1969. const result = await rep.delete({foo: {regexp: 'sit am+'}});
  1970. expect(result).to.be.eq(2);
  1971. const rawData = await MDB_CLIENT.db()
  1972. .collection('model')
  1973. .find()
  1974. .toArray();
  1975. expect(rawData).to.be.eql([
  1976. {_id: new ObjectId(created1[DEF_PK]), foo: 'lorem ipsum'},
  1977. {_id: new ObjectId(created3[DEF_PK]), foo: 'DOLOR SIT AMET'},
  1978. ]);
  1979. });
  1980. it('matches by the "regexp" operator with flags', async function () {
  1981. const schema = createSchema();
  1982. schema.defineModel({name: 'model', datasource: 'mongodb'});
  1983. const rep = schema.getRepository('model');
  1984. const created1 = await rep.create({foo: 'lorem ipsum'});
  1985. await rep.create({foo: 'dolor sit amet'});
  1986. await rep.create({foo: 'DOLOR SIT AMET'});
  1987. await rep.create({foo: 'sit amet'});
  1988. const result = await rep.delete({foo: {regexp: 'sit am+', flags: 'i'}});
  1989. expect(result).to.be.eq(3);
  1990. const rawData = await MDB_CLIENT.db()
  1991. .collection('model')
  1992. .find()
  1993. .toArray();
  1994. expect(rawData).to.be.eql([
  1995. {_id: new ObjectId(created1[DEF_PK]), foo: 'lorem ipsum'},
  1996. ]);
  1997. });
  1998. });
  1999. });
  2000. describe('deleteById', function () {
  2001. it('returns false if a given identifier is not exist', async function () {
  2002. const schema = createSchema();
  2003. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2004. const rep = schema.getRepository('model');
  2005. const oid = new ObjectId();
  2006. const result = await rep.deleteById(oid);
  2007. expect(result).to.be.false;
  2008. });
  2009. it('returns true if an item has removed by a given identifier', async function () {
  2010. const schema = createSchema();
  2011. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2012. const rep = schema.getRepository('model');
  2013. const oid = new ObjectId();
  2014. await rep.create({[DEF_PK]: oid});
  2015. const result = await rep.deleteById(oid);
  2016. expect(result).to.be.true;
  2017. const rawData = await MDB_CLIENT.db()
  2018. .collection('model')
  2019. .find()
  2020. .toArray();
  2021. expect(rawData).to.be.empty;
  2022. });
  2023. });
  2024. describe('exists', function () {
  2025. it('returns false if a given identifier is not exist', async function () {
  2026. const schema = createSchema();
  2027. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2028. const rep = schema.getRepository('model');
  2029. const oid = new ObjectId();
  2030. const result = await rep.exists(oid);
  2031. expect(result).to.be.false;
  2032. });
  2033. it('returns true if a given identifier is exist', async function () {
  2034. const schema = createSchema();
  2035. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2036. const rep = schema.getRepository('model');
  2037. const oid = new ObjectId();
  2038. await rep.create({[DEF_PK]: oid});
  2039. const result = await rep.exists(oid);
  2040. expect(result).to.be.true;
  2041. });
  2042. });
  2043. describe('count', function () {
  2044. it('returns zero if nothing to count', async function () {
  2045. const schema = createSchema();
  2046. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2047. const rep = schema.getRepository('model');
  2048. const result = await rep.count();
  2049. expect(result).to.be.eq(0);
  2050. });
  2051. it('returns a number of table items', async function () {
  2052. const schema = createSchema();
  2053. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2054. const rep = schema.getRepository('model');
  2055. await rep.create({});
  2056. await rep.create({});
  2057. await rep.create({});
  2058. const result = await rep.count();
  2059. expect(result).to.be.eq(3);
  2060. });
  2061. describe('uses a where clause to count items', function () {
  2062. it('matches by a document subset', async function () {
  2063. const schema = createSchema();
  2064. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2065. const rep = schema.getRepository('model');
  2066. await rep.create({foo: 'a'});
  2067. await rep.create({foo: 'b'});
  2068. await rep.create({foo: 'b'});
  2069. const result = await rep.count({foo: 'b'});
  2070. expect(result).to.be.eql(2);
  2071. });
  2072. it('matches by the "eq" operator', async function () {
  2073. const schema = createSchema();
  2074. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2075. const rep = schema.getRepository('model');
  2076. await rep.create({foo: 5});
  2077. await rep.create({foo: 10});
  2078. await rep.create({foo: 10});
  2079. const result = await rep.count({foo: {eq: 10}});
  2080. expect(result).to.be.eql(2);
  2081. });
  2082. it('matches by the "neq" operator', async function () {
  2083. const schema = createSchema();
  2084. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2085. const rep = schema.getRepository('model');
  2086. await rep.create({foo: 5});
  2087. await rep.create({foo: 10});
  2088. await rep.create({foo: 10});
  2089. const result = await rep.count({foo: {neq: 10}});
  2090. expect(result).to.be.eq(1);
  2091. });
  2092. it('matches by the "gt" operator', async function () {
  2093. const schema = createSchema();
  2094. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2095. const rep = schema.getRepository('model');
  2096. await rep.create({foo: 5});
  2097. await rep.create({foo: 10});
  2098. await rep.create({foo: 15});
  2099. const result = await rep.count({foo: {gt: 10}});
  2100. expect(result).to.be.eq(1);
  2101. });
  2102. it('matches by the "lt" operator', async function () {
  2103. const schema = createSchema();
  2104. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2105. const rep = schema.getRepository('model');
  2106. await rep.create({foo: 5});
  2107. await rep.create({foo: 10});
  2108. await rep.create({foo: 15});
  2109. const result = await rep.count({foo: {lt: 10}});
  2110. expect(result).to.be.eq(1);
  2111. });
  2112. it('matches by the "gte" operator', async function () {
  2113. const schema = createSchema();
  2114. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2115. const rep = schema.getRepository('model');
  2116. await rep.create({foo: 5});
  2117. await rep.create({foo: 10});
  2118. await rep.create({foo: 15});
  2119. const result = await rep.count({foo: {gte: 10}});
  2120. expect(result).to.be.eq(2);
  2121. });
  2122. it('matches by the "lte" operator', async function () {
  2123. const schema = createSchema();
  2124. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2125. const rep = schema.getRepository('model');
  2126. await rep.create({foo: 5});
  2127. await rep.create({foo: 10});
  2128. await rep.create({foo: 15});
  2129. const result = await rep.count({foo: {lte: 10}});
  2130. expect(result).to.be.eq(2);
  2131. });
  2132. it('matches by the "inq" operator', async function () {
  2133. const schema = createSchema();
  2134. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2135. const rep = schema.getRepository('model');
  2136. await rep.create({foo: 5});
  2137. await rep.create({foo: 10});
  2138. await rep.create({foo: 15});
  2139. const result = await rep.count({foo: {inq: [5, 10]}});
  2140. expect(result).to.be.eq(2);
  2141. });
  2142. it('matches by the "nin" operator', async function () {
  2143. const schema = createSchema();
  2144. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2145. const rep = schema.getRepository('model');
  2146. await rep.create({foo: 5});
  2147. await rep.create({foo: 10});
  2148. await rep.create({foo: 15});
  2149. const result = await rep.count({foo: {nin: [5, 10]}});
  2150. expect(result).to.be.eq(1);
  2151. });
  2152. it('matches by the "between" operator', async function () {
  2153. const schema = createSchema();
  2154. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2155. const rep = schema.getRepository('model');
  2156. await rep.create({foo: 5});
  2157. await rep.create({foo: 10});
  2158. await rep.create({foo: 15});
  2159. await rep.create({foo: 20});
  2160. const result = await rep.count({foo: {between: [9, 16]}});
  2161. expect(result).to.be.eq(2);
  2162. });
  2163. it('matches by the "exists" operator', async function () {
  2164. const schema = createSchema();
  2165. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2166. const rep = schema.getRepository('model');
  2167. await rep.create({});
  2168. await rep.create({foo: undefined});
  2169. await rep.create({foo: null});
  2170. await rep.create({foo: 10});
  2171. const result1 = await rep.count({foo: {exists: true}});
  2172. expect(result1).to.be.eq(3);
  2173. });
  2174. it('matches by the "like" operator', async function () {
  2175. const schema = createSchema();
  2176. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2177. const rep = schema.getRepository('model');
  2178. await rep.create({foo: 'lorem ipsum'});
  2179. await rep.create({foo: 'dolor sit amet'});
  2180. await rep.create({foo: 'DOLOR SIT AMET'});
  2181. await rep.create({foo: 'sit amet'});
  2182. const result = await rep.count({foo: {like: 'sit amet'}});
  2183. expect(result).to.be.eql(2);
  2184. });
  2185. it('matches by the "nlike" operator', async function () {
  2186. const schema = createSchema();
  2187. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2188. const rep = schema.getRepository('model');
  2189. await rep.create({foo: 'lorem ipsum'});
  2190. await rep.create({foo: 'dolor sit amet'});
  2191. await rep.create({foo: 'DOLOR SIT AMET'});
  2192. await rep.create({foo: 'sit amet'});
  2193. const result = await rep.count({foo: {nlike: 'sit amet'}});
  2194. expect(result).to.be.eql(2);
  2195. });
  2196. it('matches by the "ilike" operator', async function () {
  2197. const schema = createSchema();
  2198. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2199. const rep = schema.getRepository('model');
  2200. await rep.create({foo: 'lorem ipsum'});
  2201. await rep.create({foo: 'dolor sit amet'});
  2202. await rep.create({foo: 'DOLOR SIT AMET'});
  2203. await rep.create({foo: 'sit amet'});
  2204. const result = await rep.count({foo: {ilike: 'sit amet'}});
  2205. expect(result).to.be.eql(3);
  2206. });
  2207. it('matches by the "nilike" operator', async function () {
  2208. const schema = createSchema();
  2209. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2210. const rep = schema.getRepository('model');
  2211. await rep.create({foo: 'lorem ipsum'});
  2212. await rep.create({foo: 'dolor sit amet'});
  2213. await rep.create({foo: 'DOLOR SIT AMET'});
  2214. await rep.create({foo: 'sit amet'});
  2215. const result = await rep.count({foo: {nilike: 'sit amet'}});
  2216. expect(result).to.be.eql(1);
  2217. });
  2218. it('matches by the "regexp" operator', async function () {
  2219. const schema = createSchema();
  2220. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2221. const rep = schema.getRepository('model');
  2222. await rep.create({foo: 'lorem ipsum'});
  2223. await rep.create({foo: 'dolor sit amet'});
  2224. await rep.create({foo: 'DOLOR SIT AMET'});
  2225. await rep.create({foo: 'sit amet'});
  2226. const result = await rep.count({foo: {regexp: 'sit am+'}});
  2227. expect(result).to.be.eql(2);
  2228. });
  2229. it('matches by the "regexp" operator with flags', async function () {
  2230. const schema = createSchema();
  2231. schema.defineModel({name: 'model', datasource: 'mongodb'});
  2232. const rep = schema.getRepository('model');
  2233. await rep.create({foo: 'lorem ipsum'});
  2234. await rep.create({foo: 'dolor sit amet'});
  2235. await rep.create({foo: 'DOLOR SIT AMET'});
  2236. await rep.create({foo: 'sit amet'});
  2237. const result = await rep.count({foo: {regexp: 'sit am+', flags: 'i'}});
  2238. expect(result).to.be.eql(3);
  2239. });
  2240. });
  2241. });
  2242. });