|
1 | 1 | var rethinkdbdash = require('rethinkdbdash');
|
| 2 | +var contains = require('mout/array/contains'); |
| 3 | +var map = require('mout/array/map'); |
2 | 4 | var forOwn = require('mout/object/forOwn');
|
3 | 5 | var keys = require('mout/object/keys');
|
4 | 6 | var deepMixIn = require('mout/object/deepMixIn');
|
5 | 7 | var forEach = require('mout/array/forEach');
|
6 |
| -var contains = require('mout/array/contains'); |
7 | 8 | var isObject = require('mout/lang/isObject');
|
| 9 | +var isArray = require('mout/lang/isArray'); |
8 | 10 | var isEmpty = require('mout/lang/isEmpty');
|
9 | 11 | var isString = require('mout/lang/isString');
|
10 | 12 | var upperCase = require('mout/string/upperCase');
|
11 | 13 | var underscore = require('mout/string/underscore');
|
| 14 | +var JSData = require('js-data'); |
12 | 15 |
|
13 | 16 | function Defaults() {
|
14 | 17 |
|
@@ -144,6 +147,7 @@ function DSRethinkDBAdapter(options) {
|
144 | 147 | this.r = rethinkdbdash(this.defaults);
|
145 | 148 | this.databases = {};
|
146 | 149 | this.tables = {};
|
| 150 | + this.indices = {}; |
147 | 151 | }
|
148 | 152 |
|
149 | 153 | var dsRethinkDBAdapterPrototype = DSRethinkDBAdapter.prototype;
|
@@ -171,15 +175,109 @@ dsRethinkDBAdapterPrototype.waitForTable = function waitForTable(table, options)
|
171 | 175 | });
|
172 | 176 | };
|
173 | 177 |
|
| 178 | +dsRethinkDBAdapterPrototype.waitForIndex = function waitForIndex(table, index, options) { |
| 179 | + var _this = this; |
| 180 | + options = options || {}; |
| 181 | + var db = options.db || _this.defaults.db; |
| 182 | + return _this.waitForDb(options).then(function () { |
| 183 | + return _this.waitForTable(table, options); |
| 184 | + }).then(function () { |
| 185 | + _this.indices[db] = _this.indices[db] || {}; |
| 186 | + _this.indices[db][table] = _this.indices[db][table] || {}; |
| 187 | + if (!_this.tables[db][table][index]) { |
| 188 | + _this.tables[db][table][index] = _this.r.branch(_this.r.db(db).table(table).indexList().contains(index), true, _this.r.db(db).table(table).indexCreate(index)).run().then(function () { |
| 189 | + return _this.r.db(db).table(table).indexWait(index).run(); |
| 190 | + }); |
| 191 | + } |
| 192 | + return _this.tables[db][table][index]; |
| 193 | + }); |
| 194 | +}; |
| 195 | + |
174 | 196 | dsRethinkDBAdapterPrototype.find = function find(resourceConfig, id, options) {
|
175 | 197 | var _this = this;
|
| 198 | + var newModels = {}; |
| 199 | + var models = {}; |
| 200 | + var merge = {}; |
176 | 201 | options = options || {};
|
177 |
| - return _this.waitForTable(resourceConfig.table || underscore(resourceConfig.name), options).then(function () { |
178 |
| - return _this.r.db(options.db || _this.defaults.db).table(resourceConfig.table || underscore(resourceConfig.name)).get(id).run(); |
| 202 | + var table = resourceConfig.table || underscore(resourceConfig.name); |
| 203 | + var tasks = [_this.waitForTable(table, options)]; |
| 204 | + forEach(resourceConfig.relationList, function (def) { |
| 205 | + var relationName = def.relation; |
| 206 | + var relationDef = resourceConfig.getResource(relationName); |
| 207 | + if (!relationDef) { |
| 208 | + throw new JSData.DSErrors.NER(relationName); |
| 209 | + } |
| 210 | + if (def.foreignKey) { |
| 211 | + tasks.push(_this.waitForIndex(relationDef.table || underscore(relationDef.name), def.foreignKey, options)); |
| 212 | + } else if (def.localKey) { |
| 213 | + tasks.push(_this.waitForIndex(resourceConfig.table || underscore(resourceConfig.name), def.localKey, options)); |
| 214 | + } |
| 215 | + }); |
| 216 | + return JSData.DSUtils.Promise.all(tasks).then(function () { |
| 217 | + return _this.r.do(_this.r.table(table).get(id), function (doc) { |
| 218 | + forEach(resourceConfig.relationList, function (def) { |
| 219 | + var relationName = def.relation; |
| 220 | + models[relationName] = resourceConfig.getResource(relationName); |
| 221 | + if (!options.with || !options.with.length || !contains(options.with, relationName)) { |
| 222 | + return; |
| 223 | + } |
| 224 | + if (!models[relationName]) { |
| 225 | + throw new JSData.DSErrors.NER(relationName); |
| 226 | + } |
| 227 | + var localKey = def.localKey; |
| 228 | + var localField = def.localField; |
| 229 | + var foreignKey = def.foreignKey; |
| 230 | + if (def.type === 'belongsTo') { |
| 231 | + merge[localField] = _this.r.table(models[relationName].table || underscore(models[relationName].name)).get(doc(localKey).default('')); |
| 232 | + newModels[localField] = { |
| 233 | + modelName: relationName, |
| 234 | + relation: 'belongsTo' |
| 235 | + }; |
| 236 | + } else if (def.type === 'hasMany') { |
| 237 | + merge[localField] = _this.r.table(models[relationName].table || underscore(models[relationName].name)).getAll(id, { index: foreignKey }).coerceTo('ARRAY'); |
| 238 | + |
| 239 | + newModels[localField] = { |
| 240 | + modelName: relationName, |
| 241 | + relation: 'hasMany' |
| 242 | + }; |
| 243 | + } else if (def.type === 'hasOne') { |
| 244 | + merge[localField] = _this.r.table(models[relationName].table || underscore(models[relationName].name)); |
| 245 | + |
| 246 | + if (localKey) { |
| 247 | + merge[localField] = merge[localField].get(localKey); |
| 248 | + } else { |
| 249 | + merge[localField] = merge[localField].getAll(id, { index: foreignKey }).coerceTo('ARRAY'); |
| 250 | + } |
| 251 | + |
| 252 | + newModels[localField] = { |
| 253 | + modelName: relationName, |
| 254 | + relation: 'hasOne' |
| 255 | + }; |
| 256 | + } |
| 257 | + }); |
| 258 | + |
| 259 | + if (!isEmpty(merge)) { |
| 260 | + return doc.merge(merge); |
| 261 | + } |
| 262 | + return doc; |
| 263 | + }).run(); |
179 | 264 | }).then(function (item) {
|
180 | 265 | if (!item) {
|
181 | 266 | throw new Error('Not Found!');
|
182 | 267 | } else {
|
| 268 | + forOwn(item, function (localValue, localKey) { |
| 269 | + if (localKey in newModels) { |
| 270 | + if (isObject(localValue)) { |
| 271 | + item[localKey] = item[localKey]; |
| 272 | + } else if (isArray(localValue)) { |
| 273 | + if (newModels[localKey].relation === 'hasOne' && localValue.length) { |
| 274 | + item[localKey] = localValue[0]; |
| 275 | + } else { |
| 276 | + item[localKey] = localValue; |
| 277 | + } |
| 278 | + } |
| 279 | + } |
| 280 | + }); |
183 | 281 | return item;
|
184 | 282 | }
|
185 | 283 | });
|
|
0 commit comments