-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.coffee
140 lines (115 loc) · 4.71 KB
/
index.coffee
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
# Dependencies
_ = require('lodash')
Waterline = require('waterline')
def = require('def-type')
# Require any waterline compatible adapters here
memoryAdapter = require('sails-memory')
# Instantiate a new instance of the ORM
orm = new Waterline()
loadedModels = null
# Paths
CWD = process.cwd()
waterlineLoader = def.Module ->
#################################
# WATERLINE CONFIG
#################################
# Build A Config Object
config =
# Setup Adapters
# Creates named adapters that have have been required
adapters:
'default': memoryAdapter
'memory': memoryAdapter
# Build Connections Config
# Setup connections using the named adapter configs
connections:
memory:
adapter: 'memory'
defaults:
migrate: 'drop'
lookUpPath: "#{CWD}/api/models"
defaultModelConf:
connection: 'memory'
useLog: true
namesHashMap = {}
defaultModel = null
@init = (options = {}, callback)->
models = options.models or options.collections
delete options.models; delete options.collections
config = _.defaults(options, config)
defaultModel = config.defaultModelConf
attachModelsTo =
if config.attachModelsTo?
if _.isArray(config.attachModelsTo) then config.attachModelsTo else [config.attachModelsTo]
else
[global]
delete config.defaultModelConf
####################################
# START WATERLINE
####################################
_loadModels(models)
# Start Waterline passing adapters in
orm.initialize config, (err, orm)->
console.log 'WaterlineLoader: Initializing ORM' if config.useLog
if(err) then return callback(err)
loadedModels = orm.collections # We want to manually remove all records later in the teardown
for lowerCaseName, model of orm.collections
# Bind context for models
# (this (breaks?)allows usage with tools like `async`)
#_.bindAll(thisModel);
# Derive information about this model's associations from its schema
# and attach/expose the metadata as `SomeModel.associations` (an array)
# This allows us to use methods like .populateAll()
model.associations = _.reduce( model.attributes, (associatedWith, attrDef, attrName)->
if typeof attrDef is 'object' && (attrDef.model or attrDef.collection)
assoc =
alias: attrName,
type: attrDef.model ? 'model' : 'collection'
if (attrDef.model)
assoc.model = attrDef.model
if (attrDef.collection)
assoc.collection = attrDef.collection
if (attrDef.via)
assoc.via = attrDef.via
associatedWith.push(assoc)
return associatedWith
, [])
# We do not want to add association models (junction tables) to the global scope
# so we make a little check, since those model names have a double underscore on them.
if lowerCaseName.indexOf('__') is -1
#console.log "Adding #{lowerCaseName} to the global scope"
for obj in attachModelsTo
obj[_getOriginalName(lowerCaseName)] = model
callback(null, orm.collections)
@teardown = (callback)->
if config.useLog
console.log 'WaterlineLoader: tearing down...'
# This method calls itself until all models are destroyed
_destroyModel(loadedModels, _.keys(loadedModels), callback)
_destroyModel = (models, modelNamesArray, callback)->
models[modelNamesArray.pop()].destroy().then =>
if modelNamesArray.length is 0
orm.teardown(callback)
else
_destroyModel(models, modelNamesArray, callback)
_loadModels = (models)->
for model in models
# Models can be simple strings entries in the array, or objects
modelFileName = if _.isString(model) then model else (model.fileName or model.path)
modelName = model.alias or modelFileName
modelDefinition = require("#{config.lookUpPath}/#{modelFileName}")
# Useful if sails models were define via commonjs-injector
if _.isFunction(modelDefinition)
if model.afterLoadFilter?
modelDefinition = model.afterLoadFilter(modelDefinition)
else
modelDefinition = modelDefinition()
_loadModelIntoCollection(name: modelName, definition: modelDefinition)
return this
_loadModelIntoCollection = (model)->
waterlineModel = _.defaults(model.definition, {identity: model.name, tableName: model.name}, defaultModel)
waterlineCollection = Waterline.Collection.extend(waterlineModel)
orm.loadCollection(waterlineCollection)
namesHashMap[model.name.toLowerCase()] = model.name
_getOriginalName = (lowerCaseName)-> namesHashMap[lowerCaseName]
module.exports = waterlineLoader