Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

hydrate-mongodb

Package Overview
Dependencies
Maintainers
1
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hydrate-mongodb - npm Package Compare versions

Comparing version 0.11.0 to 0.12.0

2

core/callback.d.ts

@@ -25,3 +25,3 @@ /*!

export interface ResultCallback<T> {
(err: Error, result?: T): void;
(err?: Error, result?: T): void;
}

@@ -28,0 +28,0 @@ export interface IteratorCallback<T> {

export { NamingStrategies, NamingStrategy } from "./config/namingStrategies";
export { PersistenceError } from "./persistenceError";
export { CascadeFlags, ChangeTrackingType, FlushPriority } from "./mapping/mappingModel";
export { CascadeFlags, ChangeTrackingType, FlushPriority, FetchType } from "./mapping/mappingModel";
export { Configuration } from "./config/configuration";

@@ -5,0 +5,0 @@ export { ObjectIdGenerator } from "./config/objectIdGenerator";

@@ -15,2 +15,3 @@ import { IdentityGenerator } from "../config/configuration";

import { WriteContext } from "./writeContext";
import { QueryDocument } from "../query/queryBuilder";
/**

@@ -36,2 +37,3 @@ * @hidden

identityProperty: Property;
private _defaultFields;
constructor(baseClass?: EntityMapping);

@@ -51,3 +53,5 @@ setDocumentVersion(obj: any, version: number): void;

fetchInverse(session: InternalSession, parentEntity: any, propertyName: string, path: string[], depth: number, callback: ResultCallback<any>): void;
protected fetchPropertyValue(session: InternalSession, value: any, property: Property, callback: ResultCallback<any>): void;
getDefaultFields(): QueryDocument;
protected resolveCore(context: ResolveContext): void;
}

@@ -199,2 +199,19 @@ "use strict";

};
EntityMapping.prototype.fetchPropertyValue = function (session, value, property, callback) {
session.getPersister(this).fetchPropertyValue(value, property, callback);
};
EntityMapping.prototype.getDefaultFields = function () {
var fields = {};
if (this._defaultFields === undefined) {
// find any lazy fields and mark them with a 0 so they are not loaded
for (var i = 0; i < this.properties.length; i++) {
var property = this.properties[i];
if ((property.flags & 2048 /* FetchLazy */) != 0) {
property.setFieldValue(fields, 0);
}
}
this._defaultFields = fields;
}
return this._defaultFields;
};
EntityMapping.prototype.resolveCore = function (context) {

@@ -201,0 +218,0 @@ if (!context.isFirst) {

@@ -7,2 +7,5 @@ "use strict";

function createErrorMessage(errors) {
if (!errors) {
return "";
}
var message = [];

@@ -9,0 +12,0 @@ for (var i = 0, l = errors.length; i < l; i++) {

@@ -132,6 +132,14 @@ import { Index } from "./index";

/**
* Indicates the field should be eagerly fetched.
*/
FetchEager = 1024,
/**
* Indicates the field should be lazily fetched.
*/
FetchLazy = 2048,
/**
* All non-walk flags.
* @hidden
*/
All = 1023,
All = 4095,
/**

@@ -384,1 +392,11 @@ * Indicates that refererences to entities should be walked.

}
export declare const enum FetchType {
/**
* Indicates the field should be eagerly fetched.
*/
Eager = 1024,
/**
* Indicates the field should be lazily fetched.
*/
Lazy = 2048,
}

@@ -37,3 +37,4 @@ import { MappingBase } from "./mappingBase";

fetch(session: InternalSession, parentEntity: any, value: any, path: string[], depth: number, callback: ResultCallback<any>): void;
protected fetchPropertyValue(session: InternalSession, value: any, property: Property, callback: ResultCallback<any>): void;
protected resolveCore(context: ResolveContext): void;
}

@@ -109,2 +109,5 @@ "use strict";

context.path = base + property.name;
if ((property.flags & 1024 /* FetchEager */) != 0) {
context.addFetch(context.path);
}
propertyValue = property.mapping.read(context, fieldValue);

@@ -234,3 +237,3 @@ context.path = savedPath;

if ((property.flags & 1 /* Ignored */) == 0
&& ((property.flags & flags) != 0 || ((flags & 1023 /* All */) == 0))) {
&& ((property.flags & flags) != 0 || ((flags & 4095 /* All */) == 0))) {
property.mapping.walk(session, property.getPropertyValue(value), flags, entities, embedded, references);

@@ -253,2 +256,5 @@ }

}
else if ((property.flags & 2048 /* FetchLazy */) != 0 && propertyValue === undefined) {
this.fetchPropertyValue(session, value, property, handleCallback);
}
else {

@@ -266,2 +272,6 @@ property.mapping.fetch(session, parentEntity, propertyValue, path, depth + 1, handleCallback);

};
ObjectMapping.prototype.fetchPropertyValue = function (session, value, property, callback) {
// property values should be fully fetched on all non-entity types.
callback(null, property.getPropertyValue(value));
};
ObjectMapping.prototype.resolveCore = function (context) {

@@ -268,0 +278,0 @@ var property = this.getProperty(context.currentProperty);

@@ -1,2 +0,2 @@

import { PropertyConverter, FlushPriority } from "../mappingModel";
import { PropertyConverter, FlushPriority, FetchType } from "../mappingModel";
import { CollectionOptions } from "../collectionOptions";

@@ -235,2 +235,11 @@ import { IndexOptions } from "../indexOptions";

*/
export declare class FetchAnnotation extends Annotation implements PropertyAnnotation {
type: FetchType;
constructor(type: FetchType);
toString(): string;
processPropertyAnnotation(context: MappingBuilderContext, mapping: MappingModel.ObjectMapping, property: MappingModel.Property, symbol: Property, annotation: FetchAnnotation): void;
}
/**
* @hidden
*/
export declare class TypeAnnotation extends Annotation implements TargetClassAnnotation {

@@ -237,0 +246,0 @@ target: Constructor<any> | string;

@@ -435,2 +435,20 @@ "use strict";

*/
var FetchAnnotation = (function (_super) {
__extends(FetchAnnotation, _super);
function FetchAnnotation(type) {
_super.call(this);
this.type = type;
}
FetchAnnotation.prototype.toString = function () {
return "@Fetch";
};
FetchAnnotation.prototype.processPropertyAnnotation = function (context, mapping, property, symbol, annotation) {
property.setFlags(annotation.type & (1024 /* FetchEager */ | 2048 /* FetchLazy */));
};
return FetchAnnotation;
}(Annotation));
exports.FetchAnnotation = FetchAnnotation;
/**
* @hidden
*/
var TypeAnnotation = (function (_super) {

@@ -437,0 +455,0 @@ __extends(TypeAnnotation, _super);

import { Constructor, ParameterlessConstructor } from "../../index";
import { FieldDescription, CollectionDescription, ClassIndexDescription, PropertyIndexDescription } from "./annotations";
import { PropertyConverter } from "../mappingModel";
import { PropertyConverter, FetchType } from "../mappingModel";
import { ChangeTrackingType } from "../mappingModel";

@@ -426,2 +426,44 @@ import { CascadeFlags } from "../mappingModel";

/**
* ## FetchType.Eager
*
* By default entity references are not loaded and must be fetched using Session#fetch or similar. If a FetchType of Eager is specified on
* an entity reference then that reference is automatically fetched when the entity is loaded.
*
* ### Notes
* * This works on entity reference in Embeddable objects as well.
* * It is generally preferable to fetch references as needed.
* * A FetchType of Eager on a property that is not an entity reference has no effect.
*
* ### Example
* ```typescript
*  @Entity()
* export class Task {
*
*  @Fetch(FetchType.Eager)
* owner: Person;
* }
* ```
*
* ## FetchType.Lazy
*
* When an entity is loaded, all fields for that entity are retrieved from the database. Specifying a FetchType of Lazy for a field causes
* that field to not be retrieved from the database when the entity is loaded. The field is only loaded by calling Session#fetch and
* indicating which field to load.
*
* ### Notes
* * Useful for properties that contain large amounts of data, such as images, that are not always needed.
* * A FetchType of Lazy on a property in an Embeddable objects is ignored. All properties in an embeddable object are always loaded from the database.
* * It is generally not advisable to use a FetchType of Lazy on a property that is an entity reference.
*
* ### Example
* ```typescript
*  @Entity()
* export class Person {
*
*  @Fetch(FetchType.Lazy)
* image: Buffer;
* }
*/
export declare function Fetch(type: FetchType): PropertyDecorator;
/**
* Specifies the type of a property.

@@ -428,0 +470,0 @@ *

@@ -17,2 +17,3 @@ "use strict";

exports.Cascade = reflect_helper_1.makeDecorator(annotations_1.CascadeAnnotation);
exports.Fetch = reflect_helper_1.makeDecorator(annotations_1.FetchAnnotation);
exports.InverseOf = reflect_helper_1.makeDecorator(annotations_1.InverseOfAnnotation);

@@ -19,0 +20,0 @@ exports.Type = reflect_helper_1.makeDecorator(annotations_1.TypeAnnotation);

@@ -25,2 +25,6 @@ import { MappingError } from "./mappingError";

observer: Observer;
/**
* Fetches found while walking the object.
*/
fetches: string[];
constructor(session: InternalSession);

@@ -33,2 +37,3 @@ /**

addError(message: string, path?: string): void;
addFetch(path: string): void;
/**

@@ -35,0 +40,0 @@ * Gets a string summarizing all errors in the context.

@@ -13,6 +13,2 @@ "use strict";

this.path = "";
/**
* A list of errors that occurred during deserialization.
*/
this.errors = [];
}

@@ -25,2 +21,6 @@ /**

ReadContext.prototype.addError = function (message, path) {
if (!this.errors) {
this.errors = [];
this.hasErrors = true;
}
this.errors.push({

@@ -30,4 +30,9 @@ message: message,

});
this.hasErrors = true;
};
ReadContext.prototype.addFetch = function (path) {
if (!this.fetches) {
this.fetches = [];
}
this.fetches.push(path);
};
/**

@@ -34,0 +39,0 @@ * Gets a string summarizing all errors in the context.

{
"name": "hydrate-mongodb",
"description": "An Object Document Mapper (ODM) for MongoDB.",
"version": "0.11.0",
"version": "0.12.0",
"author": {

@@ -6,0 +6,0 @@ "name": "Artifact Health, LLC",

@@ -12,2 +12,3 @@ import * as mongodb from "mongodb";

import { Observer } from "./observer";
import { Property } from "./mapping/property";
/**

@@ -23,2 +24,3 @@ * @hidden

fetch(entity: Object, path: string, callback: Callback): void;
fetchPropertyValue(entity: any, property: Property, callback: ResultCallback<any>): void;
refresh(entity: Object, callback: ResultCallback<Object>): void;

@@ -45,2 +47,3 @@ watch(value: any, observer: Observer): void;

private _traceEnabled;
private _defaultFields;
constructor(session: InternalSession, mapping: EntityMapping, collection: mongodb.Collection);

@@ -62,2 +65,9 @@ dirtyCheck(batch: Batch, entity: Object, originalDocument: Object, callback: ResultCallback<Object>): void;

fetch(entity: any, path: string, callback: Callback): void;
/**
* Fetches a property value from the collection.
* @param entity The entity to load the property on.
* @param property The property to fetch.
* @param callback Called after the property has been loaded.
*/
fetchPropertyValue(entity: any, property: Property, callback: ResultCallback<any>): void;
findInverseOf(entity: Object, path: string, callback: ResultCallback<any[]>): void;

@@ -64,0 +74,0 @@ findOneInverseOf(entity: Object, path: string, callback: ResultCallback<any>): void;

@@ -24,2 +24,3 @@ "use strict";

this._traceEnabled = this._session.factory.logger != null;
this._defaultFields = mapping.getDefaultFields();
}

@@ -98,2 +99,50 @@ PersisterImpl.prototype.dirtyCheck = function (batch, entity, originalDocument, callback) {

};
/**
* Fetches a property value from the collection.
* @param entity The entity to load the property on.
* @param property The property to fetch.
* @param callback Called after the property has been loaded.
*/
PersisterImpl.prototype.fetchPropertyValue = function (entity, property, callback) {
var _this = this;
// indicate the field we want to pull back
var fields = {
_id: 0
};
property.setFieldValue(fields, 1);
// if the entity is versioned then return the version number as well
var version;
if (this._versioned) {
// get the current version
version = this._session.getVersion(entity);
// include the document version in the projection
this._mapping.setDocumentVersion(fields, 1);
}
var criteria = {
_id: entity["_id"]
};
// setup trace logging.
var handleCallback = callback;
if (this._traceEnabled) {
handleCallback = this._createTraceableCallback({ kind: queryKind_1.QueryKind[queryKind_1.QueryKind.FindOne], criteria: criteria, fields: fields }, callback);
}
this._collection.findOne(criteria, fields, function (err, document) {
if (err)
return callback(err);
// check to make sure the version has not changed
if (_this._versioned) {
if (_this._mapping.getDocumentVersion(document) != version) {
return callback(new Error("Cannot fetch property value because document version has changed."));
}
}
// read the property based on the property mapping
var readContext = new readContext_1.ReadContext(_this._session);
readContext.path = property.name;
var propertyValue = property.mapping.read(readContext, property.getFieldValue(document));
if (readContext.hasErrors) {
return callback(new persistenceError_1.PersistenceError("Error deserializing property value: " + readContext.getErrorMessage()));
}
handleCallback(null, propertyValue);
});
};
PersisterImpl.prototype.findInverseOf = function (entity, path, callback) {

@@ -145,12 +194,17 @@ var criteria = this._prepareInverseQuery(entity, path, callback);

PersisterImpl.prototype.findOne = function (criteria, callback) {
var query = {
criteria: criteria,
fields: this._defaultFields
};
// setup trace logging.
var handleCallback = callback;
// setup trace logging.
if (this._traceEnabled) {
handleCallback = this._createTraceableCallback({ kind: queryKind_1.QueryKind[queryKind_1.QueryKind.FindOne], criteria: criteria }, callback);
query.kind = queryKind_1.QueryKind[queryKind_1.QueryKind.FindOne];
handleCallback = this._createTraceableCallback(query, callback);
}
this._findOne({ criteria: criteria }, handleCallback);
this._findOne(query, handleCallback);
};
PersisterImpl.prototype._findOne = function (query, callback) {
var _this = this;
this._collection.findOne(query.criteria, function (err, document) {
this._collection.findOne(query.criteria, query.fields, function (err, document) {
if (err)

@@ -162,8 +216,13 @@ return callback(err);

PersisterImpl.prototype.findAll = function (criteria, callback) {
var query = {
criteria: criteria,
fields: this._defaultFields
};
// setup trace logging.
var handleCallback = callback;
// setup trace logging.
if (this._traceEnabled) {
handleCallback = this._createTraceableCallback({ kind: queryKind_1.QueryKind[queryKind_1.QueryKind.FindAll], criteria: criteria }, callback);
query.kind = queryKind_1.QueryKind[queryKind_1.QueryKind.FindAll];
handleCallback = this._createTraceableCallback(query, callback);
}
this._findAll({ criteria: criteria }, handleCallback);
this._findAll(query, handleCallback);
};

@@ -212,2 +271,4 @@ PersisterImpl.prototype._findAll = function (query, callback) {

}
// todo: handle field projection
query.fields = this._defaultFields;
// map update document if it's defined

@@ -414,3 +475,3 @@ if (query.updateDocument) {

PersisterImpl.prototype._prepareFind = function (query) {
var cursor = this._collection.find(query.criteria);
var cursor = this._collection.find(query.criteria, query.fields);
if (query.orderDocument !== undefined) {

@@ -609,3 +670,9 @@ cursor.sort(query.orderDocument);

this._session.registerManaged(this, entity, document);
callback(null, entity);
if (!context.fetches) {
callback(null, entity);
}
else {
// requested fetches were found when reading the entity
this._session.fetchInternal(entity, context.fetches, callback);
}
return;

@@ -612,0 +679,0 @@ }

@@ -38,2 +38,3 @@ import { Callback } from "../core/callback";

execute(callback: ResultCallback<T>): void;
asPromise(): Promise<T>;
}

@@ -40,0 +41,0 @@ export interface CountQuery extends Query<number> {

@@ -239,2 +239,17 @@ "use strict";

};
QueryObject.prototype.asPromise = function () {
var _this = this;
// create and return the promise.
return new Promise(function (resolve, reject) {
// wrapping of the classic callback handler.
_this.handleCallback(function (err, result) {
if (err) {
reject(err);
}
else {
resolve(result);
}
});
});
};
/**

@@ -247,2 +262,3 @@ * Creates an object for logging purposes.

criteria: this.criteria,
fields: this.fields,
update: this.updateDocument,

@@ -249,0 +265,0 @@ wantsUpdated: this.wantsUpdated,

@@ -18,2 +18,3 @@ import {ResultCallback} from "../core/callback";

criteria: QueryDocument;
fields: QueryDocument;
updateDocument: QueryDocument;

@@ -20,0 +21,0 @@

@@ -255,2 +255,22 @@ [![Build Status](https://travis-ci.org/artifacthealth/hydrate-mongodb.svg?branch=master)](https://travis-ci.org/artifacthealth/hydrate-mongodb)

### Promises
All queries can return a Promise by chaining a call to `asPromise`.
Converting a find-by-id query to a Promise.
```typescript
session.find(Task, id).asPromise().then((task) => {
...
});
```
Converting a find-all query to a promise
```typescript
session.query(Task).findAll({ assigned: person }).asPromise().then((tasks) => {
...
});
```
## Modeling

@@ -624,1 +644,40 @@

### Fetching
#### Eager Fetching of Entity References
By default entity references are not loaded and must be fetched using Session#fetch or similar. If a FetchType of Eager is specified on
an entity reference then that reference is automatically fetched when the entity is loaded.
* This works on entity reference in Embeddable objects as well.
* It is generally preferable to fetch references as needed.
* A FetchType of Eager on a property that is not an entity reference has no effect.
```typescript
 @Entity()
export class Task {
 @Fetch(FetchType.Eager)
owner: Person;
}
```
#### Lazy Fetching of Properties
When an entity is loaded, all fields for that entity are retrieved from the database. Specifying a FetchType of Lazy for a field causes
that field to not be retrieved from the database when the entity is loaded. The field is only loaded by calling Session#fetch and
indicating which field to load.
* Useful for properties that contain large amounts of data, such as images, that are not always needed.
* A FetchType of Lazy on a property in an Embeddable objects is ignored. All properties in an embeddable object are always loaded from the database.
* It is generally not advisable to use a FetchType of Lazy on a property that is an entity reference.
```typescript
 @Entity()
export class Person {
 @Fetch(FetchType.Lazy)
image: Buffer;
}
```

@@ -180,2 +180,6 @@ "use strict";

SessionImpl.prototype.getVersion = function (obj) {
var links = this._getObjectLinks(obj);
if (!links || links.state == 1 /* Detached */) {
return null;
}
var mapping = this.factory.getMappingForObject(obj);

@@ -185,3 +189,3 @@ if (!mapping) {

}
return mapping.getDocumentVersion(obj);
return mapping.getDocumentVersion(links.originalDocument);
};

@@ -188,0 +192,0 @@ SessionImpl.prototype.getReferenceInternal = function (mapping, id) {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc