Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 197 lines (138 sloc) 8.569 kB
f3ec110 @straps node-dbmon initial release
authored
1 # Database monitor utilities for nodejs
2 If you are trying to update a GUI when a database table changes (_insert_, _update_, _delete_), this library is for you.
3
4 This is a node.js module supporting a growing number of database drivers and notification transports
5 you can extend and improve.
6
7 It is designed to be easily extended with simple sintax by anyone and, where possibile,
8 to notify of changes without classic polling, but with real-time notification mechanism
9
10 ## Usage sample
11 As of today, there is only one driver developed, the PostgreSQL one because I'm a PostgreSQL fan and heavy user.
12 This is a short example; you can find more on `test/test-postgresql.js`
13
14 Install a local postgresql database server; grant temporary trust access to the postgresql
15 user editing the pg_hba.conf file and create a test table like this `create table testtable(id integer primary key, val varchar(10));`
16 then run the following
17
18 var pg=require('pg'), cli=new pg.Client('tcp://postgres@localhost/template1'), dbmon=require('dbmon');
19
20 cli.connect();
21 //uncomment if you want node to create the temporary table for you
22 //cli.query('drop table if exists testtable; create table testtable(id integer primary key, val varchar(10));');
23
24 var channel=dbmon.channel({
25 driver:'postgresql',
26 driverOpts:{
27 postgresql:{
28 cli:cli
29 }
30 },
31 table:'testtable',
32 monitor:'all',
33 keyfld:{
34 name:'id',type:'integer'
35 }
36 });
37
38 Now monitor the console and execute some insert/update/delete and see what happens...
39
40 You should see come console messages saying you are modifiyng `testtable` like this
41
42 Console Transport Notification: insert, row={"op":"i","k":2,"oldk":2,"id":1}
43
44 In this case I've executed a simple insert like `insert into testtable values(2,'TWO');`.
45 Console says that the type of notification is an insert and the row modified
46 from last notification is `{"op":"i","k":2,"oldk":2,"id":1}` where fields means:
47
48 - *op* is the operation type; can be *i* for insert, *u* for update, *d* for delete and *t* for truncate
49 - *k* is the key inserted/updated/deleted based on what specified in `keyfld.name`
50 - *oldk* is the old key value, see what happens executing `update testtable set id=20, val='twenty' where id=2`
51 - *id* is an internal change sequence id, an ordered number useful to keep track of modifications
52
53 It is very interesting to know that if you update 2 or more rows in the same transaction, there will
54 arrive 2 ore more notifications based on the number or rows being modified
55
56 Another good thing is that for PostgreSQL, *dbmon* is powered by the NOTIFY/LISTEN constructs. It means
57 that, when something changes, the server that contacts node and node notify listeners via the transports specified, making
58 it really real-time, not like other polling-based alternatives.
59
60 To see the complete list of options see [lib/channelDefaults.js](https://github.com/straps/node-dbmon/blob/master/lib/channelDefaults.js)
61
62
63 ## Structure and Naming Conventions
64
65 Dbmon is designed to be dynamic and easily extensible; there are 3 main actors to extend it
66
67 - **transports**, in [lib/providers](https://github.com/straps/node-dbmon/tree/master/lib/transports) are the way dbmon notify events. You can use how many tranports you want separating them by comma. The name specified in the options object have to match the name of the file followed by `-tranport.js` in the `transports` foler, like the `console` transport in the example above.
68 - **providers**, in [lib/providers](https://github.com/straps/node-dbmon/tree/master/lib/providers), have to initialize their method to fetch data and notify transports whene something happen; in most cases (surely for postgresql case) they should only require the `generic-driver` that dynamiccaly instantiate the method and notify transports
69 - **methods**, in [lib/providers](https://github.com/straps/node-dbmon/tree/master/lib/methods), are the core of the system; their implementation depends upon the driver and the method specified in the configuration object and their name should respect `DRIVER-METHOD-method.js` convention (ie: postgresql-trigger-method.js). Methods init function return an `EventEmitter` inherited object that notify listeners where data changes firing the event notification chain
70
71
72 ### How Create a new Transport
73
74 Creating a new transport is very easy; the node module have to export a single function `init` that `dbmon` will call passing the global options object.
75
76 The `init` function have to return an object with a `notify` method, magically called from drivers, when something server side changed.
77
78 Say we want a generic TCP Socket transport to communicate with another application, transmitting db update notification.
79
80 Create the file `lib/transports/tcpsocket.js` and insert the following lines:
81
82 //TCP Socket Tranport
83 var init=function init(opts){
84 console.log('TCP Socket Transport init');
85 var me={
86 notify:function(type, row){
87 opts.transportsOpts.tcpsocket.client.write(JSON.stringify(row));
88 return me;
89 }
90 };
91 return me;
92 };
93 module.exports={init:init};
94
95 Now use it from your node.js server socket app:
96
97 var net = require('net');
98 var server = net.createServer(function (c) {
99 c.on('data', function(data){
100 console.log('DATA FROM SOCKET HURRAAA --> '+data);
101 });
102 });
103 server.listen(8124, 'localhost', function(){
104 var client=new net.Socket();
105 client.connect(8124, 'localhost', function(){
106 console.log('connected');
107
108 var pg=require('pg'), cli=new pg.Client('tcp://postgres@localhost/template1'), dbmon=require('dbmon');
109 cli.connect();
110
111 dbmon.channel({
112 driver:'postgresql',
113 driverOpts:{
114 postgresql:{
115 cli:cli
116 }
117 },
118 table:'testtable',
119 method:'trigger',
120 transports:'tcpsocket',
121 transportsOpts:{
122 tcpsocket:{
123 client:client
124 }
125 },
126 keyfld:{ name:'id', type:'integer'}
127 });
128 });
129 });
130
131 In 10 lines of code you can create and use a new tranport, contribute to the library and make others happy (me too :)
132
133 Creating a new driver and a new driver method, could be some more complicated, but I thing, in next releases will be a generic
134 mixed trigger/polloging based driver I'm thinking on.
135
136
137 ## Testing
138
139 Test cases are home-made and could not be complete or well done, so feel free to fork and improve tests too.
140
141 In any case, you can test the library doing a `node test/test-*` from main directory
142
143
144 ## Installation
145
146 Using npm: `npm install dbmon`
147
148 Or `npm install dbmon -g` and `npm link dbmon` if you prefer linking a global installation
149
150 Or you can download/fork and copy on a local folder inside your project
151
152
153 ### External Dependencies, automatically installed if you use npm
154
155 - [Underscore.js](http://documentcloud.github.com/underscore/) (`npm install underscore`)
156 - [Step](https://github.com/creationix/step) (`npm install step`)
157
158 Database drivers, depends on the driver you use, including
159
160 - [Pg](https://github.com/brianc/node-postgres) (`npm install pg`)
161
162 Only for test purposes
163
164 - [Colors](https://github.com/Marak/colors.js) (`npm install colors`)
165
166
167
168 ## ToDo
169 - Develop other drivers (MySQL, Oracle, MsSQL, etc...)
170 - Develop other transports (Faye, Hook.io, etc..)
171
172
173 ## License
174
175 (The MIT License)
176
177 Copyright (c) 2011 Francesco Strappini <f@strx.it>
178
179 Permission is hereby granted, free of charge, to any person obtaining
180 a copy of this software and associated documentation files (the
181 'Software'), to deal in the Software without restriction, including
182 without limitation the rights to use, copy, modify, merge, publish,
183 distribute, sublicense, and/or sell copies of the Software, and to
184 permit persons to whom the Software is furnished to do so, subject to
185 the following conditions:
186
187 The above copyright notice and this permission notice shall be
188 included in all copies or substantial portions of the Software.
189
190 THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
191 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
192 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
193 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
194 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
195 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
196 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Something went wrong with that request. Please try again.