@@ -9,6 +9,7 @@ class BsonDB {
99 this . noBlankData = options [ 'noBlankData' ] ? ( typeof options [ 'noBlankData' ] === 'boolean' ? options [ 'noBlankData' ] : false ) : false ;
1010 this . readable = options [ 'readable' ] ? ( typeof options [ 'readable' ] === 'boolean' ? true : false ) : false ;
1111 this . seperator = options [ 'seperator' ] ;
12+ this . message = options [ 'message' ] ;
1213
1314 try {
1415 bson = require ( 'bson' ) ;
@@ -378,18 +379,155 @@ class BsonDB {
378379
379380 find ( key , query ) {
380381 if ( typeof key !== 'string' || key . trim ( ) === '' ) {
381- throw new TypeError ( 'Key must be a non-empty string.' ) ;
382+ throw new TypeError ( this . message [ 'errors' ] [ 'nonEmptyString' ] ) ;
382383 } ;
383384
384385 if ( typeof query !== 'object' || query === null ) {
385- throw new TypeError ( 'Query must be an object.' ) ;
386+ throw new TypeError ( this . message [ 'errors' ] [ 'queryMustObjects' ] ) ;
386387 } ;
387388
388389 const data = this . get ( key ) || [ ] ;
389- if ( ! Array . isArray ( data ) ) throw new Error ( 'Data must be an array.' ) ;
390+ if ( ! Array . isArray ( data ) ) throw new Error ( this . message [ 'errors' ] [ 'dataMustArray' ] ) ;
390391
391392 return data . filter ( doc => Object . keys ( query ) . every ( queryKey => queryKey in doc && doc [ queryKey ] === query [ queryKey ] ) ) || [ ] ;
392393 }
394+
395+ findAndUpdate ( key , query , update ) {
396+ if ( typeof key !== 'string' || key . trim ( ) === '' ) {
397+ throw new TypeError ( this . message [ 'errors' ] [ 'nonEmptyString' ] ) ;
398+ } ;
399+
400+ if ( typeof query !== 'object' || query === null ) {
401+ throw new TypeError ( this . message [ 'errors' ] [ 'queryMustObjects' ] ) ;
402+ } ;
403+
404+ if ( typeof update !== 'object' || update === null ) {
405+ throw new TypeError ( this . message [ 'errors' ] [ 'updateMustObjects' ] ) ;
406+ } ;
407+
408+ const data = this . get ( key ) || [ ] ;
409+ if ( ! Array . isArray ( data ) ) throw new Error ( this . message [ 'errors' ] [ 'dataMustArray' ] ) ;
410+
411+ const updatedDocs = data . map ( doc => {
412+ const matches = Object . keys ( query ) . every ( queryKey => queryKey in doc && doc [ queryKey ] === query [ queryKey ] ) ;
413+ if ( matches ) {
414+ const oldDoc = { ...doc } ;
415+ const newDoc = { ...oldDoc , ...update } ;
416+
417+ return { old : oldDoc , new : newDoc } ;
418+ } ;
419+
420+ return null ;
421+ } ) . filter ( doc => doc !== null ) ;
422+
423+ if ( updatedDocs . length > 0 ) {
424+ this . set ( key , data . map ( doc => {
425+ const matchingUpdate = updatedDocs . find ( updatedDoc =>
426+ Object . keys ( query ) . every ( queryKey => queryKey in doc && doc [ queryKey ] === query [ queryKey ] )
427+ ) ;
428+
429+ return matchingUpdate ? matchingUpdate . new : doc ;
430+ } ) ) ;
431+ } ;
432+
433+ return updatedDocs ;
434+ }
435+
436+ findAndDelete ( key , query ) {
437+ if ( typeof key !== 'string' || key . trim ( ) === '' ) {
438+ throw new TypeError ( this . message [ 'errors' ] [ 'nonEmptyString' ] ) ;
439+ } ;
440+
441+ if ( typeof query !== 'object' || query === null ) {
442+ throw new TypeError ( this . message [ 'errors' ] [ 'queryMustObjects' ] ) ;
443+ } ;
444+
445+ const data = this . get ( key ) || [ ] ;
446+ if ( ! Array . isArray ( data ) ) throw new Error ( this . message [ 'errors' ] [ 'dataMustArray' ] ) ;
447+
448+ const deletedDocs = data . filter ( doc =>
449+ Object . keys ( query ) . every ( queryKey => queryKey in doc && doc [ queryKey ] === query [ queryKey ] )
450+ ) ;
451+
452+ const updatedData = data . filter ( doc => ! deletedDocs . includes ( doc ) ) ;
453+
454+ this . set ( key , updatedData ) ;
455+
456+ return deletedDocs ;
457+ }
458+
459+ findOneAndUpdate ( key , query , update ) {
460+ if ( typeof key !== 'string' || key . trim ( ) === '' ) {
461+ throw new TypeError ( this . message [ 'errors' ] [ 'nonEmptyString' ] ) ;
462+ } ;
463+
464+ if ( typeof query !== 'object' || query === null ) {
465+ throw new TypeError ( this . message [ 'errors' ] [ 'queryMustObjects' ] ) ;
466+ } ;
467+
468+ if ( typeof update !== 'object' || update === null ) {
469+ throw new TypeError ( this . message [ 'errors' ] [ 'updateMustObjects' ] ) ;
470+ } ;
471+
472+ const data = this . get ( key ) || [ ] ;
473+ if ( ! Array . isArray ( data ) ) throw new Error ( this . message [ 'errors' ] [ 'dataMustArray' ] ) ;
474+
475+ let oldDoc = null ;
476+ let newDoc = null ;
477+
478+ const updatedData = data . map ( doc => {
479+ const matches = Object . keys ( query ) . every ( queryKey => queryKey in doc && doc [ queryKey ] === query [ queryKey ] ) ;
480+
481+ if ( matches ) {
482+ oldDoc = { ...doc } ;
483+ newDoc = { ...doc , ...update } ;
484+
485+ return newDoc ;
486+ } ;
487+
488+ return doc ;
489+ } ) ;
490+
491+ if ( oldDoc && newDoc ) {
492+ this . set ( key , updatedData ) ;
493+ return { old : oldDoc , new : newDoc } ;
494+ } else {
495+ throw new Error ( this . message [ 'errors' ] [ 'noDocMatchedQuery' ] ) ;
496+ } ;
497+ }
498+
499+ findOneAndDelete ( key , query ) {
500+ if ( typeof key !== 'string' || key . trim ( ) === '' ) {
501+ throw new TypeError ( this . message [ 'errors' ] [ 'nonEmptyString' ] ) ;
502+ } ;
503+
504+ if ( typeof query !== 'object' || query === null ) {
505+ throw new TypeError ( this . message [ 'errors' ] [ 'queryMustObjects' ] ) ;
506+ } ;
507+
508+ const data = this . get ( key ) || [ ] ;
509+ if ( ! Array . isArray ( data ) ) throw new Error ( this . message [ 'errors' ] [ 'dataMustArray' ] ) ;
510+
511+ let deletedDoc = null ;
512+
513+ const updatedData = data . filter ( doc => {
514+ const matches = Object . keys ( query ) . every ( queryKey => queryKey in doc && doc [ queryKey ] === query [ queryKey ] ) ;
515+ if ( matches ) {
516+ deletedDoc = { ...doc } ;
517+
518+ return false ;
519+ } ;
520+
521+ return true ;
522+ } ) ;
523+
524+ if ( deletedDoc ) {
525+ this . set ( key , updatedData ) ;
526+ return deletedDoc ;
527+ } else {
528+ throw new Error ( this . message [ 'errors' ] [ 'noDocMatchedQuery' ] ) ;
529+ } ;
530+ }
393531}
394532
395533module . exports = BsonDB ;
0 commit comments