UNPKG

2.96 kBtext/coffeescriptView Raw
1url = require('url')
2anyDB = require('any-db')
3queries = require('./queries')
4dialects = require('./dialects')
5
6module.exports = -> Engine.create.apply Engine, arguments
7
8class Engine
9 ###
10 ``Engine`` is gesundheits interface to an actual database.
11
12 Engines have all of the :ref:`query factory functions <query-factories>`
13 attached to them as instance methods that automatically bind created queries
14 to the engine. They also have these additionaly methods
15 ###
16
17 @create = (dbUrl, poolOptions) ->
18 ###
19 Create an :class:`engine::Engine` instance from an Any-DB_ connect string
20 and extra connection pool options, this is exported by gesundheit as
21 ``gesundheit.engine(...)``.
22
23 :ref:`This example <engine-usage-example>` shows the most common way to set up
24 a single default database engine for an application.
25
26 .. _Any-DB: https://github.com/grncdr/node-any-db
27 .. _Any-DB ConnectionPool: https://github.com/grncdr/node-any-db/blob/master/API.md#connectionpool
28 ###
29 parsed = url.parse(dbUrl)
30 driverName = parsed.protocol.replace(':', '').split('+').shift()
31
32 if driverName is 'fake'
33 pool = fakePool()
34 if parsed.protocol.match('pretty')
35 dialectType = dialects.pretty
36 else
37 dialectType = dialects.base
38 else
39 pool = anyDB.createPool(dbUrl, poolOptions)
40 dialectType = dialects[driverName]
41
42 if not dialectType?
43 throw new Error('no such dialect: ' + driverName)
44 new Engine driverName, dbUrl, pool, new dialectType()
45
46 constructor: (@driver, @url, @pool, @dialect) ->
47 queries.mixinFactoryMethods @
48
49 query: (statement, params, callback) ->
50 ###
51 Passes arguments directly to the query method of the underlying `Any-DB
52 ConnectionPool`_
53 ###
54 @pool.query(arguments...)
55
56 begin: (callback) ->
57 ###
58 Start a new transaction and return it.
59
60 The returned object behaves exactly like a new engine, but has ``commit``
61 and ``rollback`` methods instead of ``close``. (In fact it's an `Any-DB
62 Transaction`_ that has had the query factory functions mixed in to it).
63
64 .. _Any-DB Transaction: https://github.com/grncdr/node-any-db/blob/master/API.md#transaction
65 ###
66 tx = queries.mixinFactoryMethods(@pool.begin(callback))
67 tx.engine = @
68 tx.compile = @dialect.compile.bind(@dialect)
69 tx
70
71 compile: (root) ->
72 ###
73 Render an AST to a SQL string and collect parameters
74 ###
75 @dialect.compile(root)
76
77 close: ->
78 ###
79 Closes the internal connection pool.
80 ###
81 @pool.close()
82
83fakePool = ->
84 ###
85 Create a fake database connection pool that throws errors if you try to
86 execute a query.
87 ###
88 return {
89 begin: (cb) ->
90 if cb then process.nextTick(cb.bind(null, engine))
91 engine
92 query: (sql, params, cb) ->
93 throw new Error("Cannot query with fakeEngine. Do `gesundheit.defaultEngine = gesundheit.engine(url)` before querying")
94 close: ->
95 }