This repository has been archived by the owner on Aug 25, 2021. It is now read-only.
forked from bookshelf/bookshelf
-
Notifications
You must be signed in to change notification settings - Fork 1
/
bookshelf.js
158 lines (133 loc) · 5.56 KB
/
bookshelf.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Bookshelf.js 0.7.5
// ---------------
// (c) 2013 Tim Griesser
// Bookshelf may be freely distributed under the MIT license.
// For all details and documentation:
// http://bookshelfjs.org
var Bookshelf = function() {
return Bookshelf.initialize.apply(null, arguments);
};
// Constructor for a new `Bookshelf` object, it accepts
// an active `knex` instance and initializes the appropriate
// `Model` and `Collection` constructors for use in the current instance.
Bookshelf.initialize = function(knex) {
var bookshelf = {
VERSION: '0.7.5'
};
var _ = require('lodash');
var inherits = require('inherits');
var semver = require('semver');
// We've supplemented `Events` with a `triggerThen`
// method to allow for asynchronous event handling via promises. We also
// mix this into the prototypes of the main objects in the library.
var Events = require('./lib/base/events');
// All core modules required for the bookshelf instance.
var BookshelfModel = require('./lib/model');
var BookshelfCollection = require('./lib/collection');
var BookshelfRelation = require('./lib/relation');
var Errors = require('./lib/errors');
// If the knex isn't a `Knex` instance, we'll assume it's
// a compatible config object and pass it through to create a new instance.
// This behavior is now deprecated.
if (_.isPlainObject(knex)) {
console.warn('Initializing Bookshelf with a config object is deprecated, please pass an initialized knex.js instance.');
knex = require('knex')(knex);
}
var range = '>=0.6.10';
if (!semver.satisfies(knex.VERSION, range)) {
throw new Error('The knex version is ' + knex.VERSION + ' which does not satisfy the Bookshelf\'s requirement ' + range);
}
var Model = bookshelf.Model = function() {
BookshelfModel.apply(this, arguments);
};
var Collection = bookshelf.Collection = function() {
BookshelfCollection.apply(this, arguments);
};
inherits(Model, BookshelfModel);
inherits(Collection, BookshelfCollection);
_.extend(Model, BookshelfModel);
_.extend(Collection, BookshelfCollection);
Model.prototype._builder =
Collection.prototype._builder = function(tableName) {
var builder = knex(tableName);
var instance = this;
return builder.on('query', function(data) {
instance.trigger('query', data);
});
};
// The collection also references the correct `Model`, specified above, for creating
// new `Model` instances in the collection.
Collection.prototype.model = Model;
Model.prototype.Collection = Collection;
function Relation() {
BookshelfRelation.apply(this, arguments);
}
inherits(Relation, BookshelfRelation);
Relation.prototype.Model = Model;
Relation.prototype.Collection = Collection;
// The `Model` constructor is referenced as a property on the `Bookshelf` instance,
// mixing in the correct `builder` method, as well as the `relation` method,
// passing in the correct `Model` & `Collection` constructors for later reference.
Model.prototype._relation = function(type, Target, options) {
if (type !== 'morphTo' && !_.isFunction(Target)) {
throw new Error('A valid target model must be defined for the ' +
_.result(this, 'tableName') + ' ' + type + ' relation');
}
return new Relation(type, Target, options);
};
// Shortcut for creating a new collection with the current collection.
Model.collection = function(rows, options) {
return new Collection((rows || []), _.extend({}, options, {model: this}));
};
// A `Bookshelf` instance may be used as a top-level pub-sub bus, as it mixes in the
// `Events` object. It also contains the version number, and a `Transaction` method
// referencing the correct version of `knex` passed into the object.
_.extend(bookshelf, Events, Errors, {
// Helper method to wrap a series of Bookshelf actions in a `knex` transaction block;
transaction: function() {
return this.knex.transaction.apply(this, arguments);
},
// Provides a nice, tested, standardized way of adding plugins to a `Bookshelf` instance,
// injecting the current instance into the plugin, which should be a module.exports.
plugin: function(plugin, options) {
if (_.isString(plugin)) {
try {
require('./plugins/' + plugin)(this, options);
} catch (e) {
require(plugin)(this, options);
}
} else if (_.isArray(plugin)) {
_.each(plugin, function (plugin) {
this.plugin(plugin, options);
}, this);
} else {
plugin(this, options);
}
return this;
}
});
// Grab a reference to the `knex` instance passed (or created) in this constructor,
// for convenience.
bookshelf.knex = knex;
// The `forge` function properly instantiates a new Model or Collection
// without needing the `new` operator... to make object creation cleaner
// and more chainable.
Model.forge = Collection.forge = function() {
var inst = Object.create(this.prototype);
var obj = this.apply(inst, arguments);
return (Object(obj) === obj ? obj : inst);
};
// Attach `where`, `query`, and `fetchAll` as static methods.
['where', 'query'].forEach(function(method) {
Model[method] =
Collection[method] = function() {
var model = this.forge();
return model[method].apply(model, arguments);
};
});
Model.fetchAll = function(options) { return this.forge().fetchAll(options); };
Model.extend = Collection.extend = require('simple-extend');
return bookshelf;
};
// Finally, export `Bookshelf` to the world.
module.exports = Bookshelf;