/
dbref.js
129 lines (112 loc) · 3.41 KB
/
dbref.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
* lib/types/dbref.js - the DBRef type
*
* Copyright 2011, Stuart Hudson <goulash1971@yahoo.com>
* Released under the terms of the MIT License.
*
* Version 0.0.2
*/
var mongoose = require("mongoose");
/**
* Utility function that will cast a single object for a condition
*
* @param {Object} the single object to be handled
* @api private
*/
function handleSingle (value) {
return this.cast(value);
}
/**
* Utility function that will cast an array for a condition
*
* @param {Array} the array of objects to be handled
* @api private
*/
function handleArray (value) {
var self = this;
return value.map (function(m) {return self.cast(m);});
}
/**
* Utility function for typeof array testing
* @param {Object} the object to be tested as an array
* @api private
*/
var isArray = Array.isArray || function(obj) {
return toString.call(obj) === '[object Array]';
}
/**
* Loader that loads the type into the mongoose infrastructure
*
* @param {Mongoose} the active Mongoose instance for installation
* @result {Object} the type that is loaded
* @api public
*/
exports.loadType = function (mongoose) {
// The types that are used for schema and models
var SchemaType = mongoose.SchemaType;
var SchemaTypes = mongoose.SchemaTypes;
var CastError = SchemaType.CastError;
// The native type used for storage
var dbref = mongoose.mongo.BSONPure.DBRef;
// Constructor for schema type
function DBRef (value, options) {
SchemaType.call(this, value, options);
};
// Direct inheritence from schema type
DBRef.prototype.__proto__ = SchemaType.prototype;
// Testing method to evaluate whether check needed
DBRef.prototype.checkRequired = function (value) {
return !!value && value instanceof dbref;
};
// Allows a namespace filter to be installed
DBRef.prototype.ns = function (spec) {
if (this.nsValidator) {
this.nsValidator = false;
this.validators = this.validators.filter(function(v) { return v[1] !== 'ns'; });
}
delete this.namespaces;
switch (typeof spec) {
case 'function':
this.validators.push ([this.nsValidator = spec, 'ns']);
break;
case 'string' :
spec = [spec];
default:
this.namespaces = spec;
this.nsValidator = function (v) { return ~spec.indexOf(v.namespace); };
this.validators.push ([this.nsValidator, 'ns']);
}
};
// Casting function using raw or processed refs
DBRef.prototype.cast = function (value) {
var oid = SchemaTypes.ObjectId;
if (value === null) return value;
if (value instanceof dbref) return value;
if (typeof value !== 'object') throw new CastError('db reference', value);
return new dbref(value["$ref"], oid.prototype.cast(value["$id"]), value["$db"]);
};
// Condition handlers - glues condition to casting
DBRef.prototype.$conditionalHandlers = {
'$ne': handleSingle,
'$in': handleArray,
'$nin': handleArray
};
// Casting function used in queries & conditions
DBRef.prototype.castForQuery = function ($conditional, value) {
var handler;
if (arguments.length === 2) {
handler = this.$conditionalHandlers[$conditional];
if (!handler)
throw new Error("Can't use " + $conditional + " with DBRef.");
return handler.call(this, value);
} else {
value = $conditional;
return this.cast(value);
}
};
// Perform the installation
mongoose.SchemaTypes.DBRef = DBRef;
mongoose.Types.DBRef = dbref;
// Return the type
return DBRef;
}