3
3
var EventEmitter = require ( 'events' ) . EventEmitter ;
4
4
var util = require ( 'util' ) ;
5
5
6
- function LiveMysqlSelect ( query , triggers , base ) {
7
- if ( ! query )
8
- throw new Error ( 'query required' ) ;
6
+ function LiveMysqlSelect ( queryCache , triggers , base ) {
7
+ if ( ! queryCache )
8
+ throw new Error ( 'queryCache required' ) ;
9
9
if ( ! ( triggers instanceof Array ) )
10
10
throw new Error ( 'triggers array required' ) ;
11
11
if ( typeof base !== 'object' )
@@ -15,32 +15,44 @@ function LiveMysqlSelect(query, triggers, base){
15
15
EventEmitter . call ( self ) ;
16
16
self . triggers = triggers ;
17
17
self . base = base ;
18
- self . lastUpdate = 0 ;
19
- self . query = self . _escapeQueryFun ( query ) ;
20
18
self . data = [ ] ;
21
- self . initialized = false ;
19
+ self . queryCache = queryCache ;
20
+ queryCache . selects . push ( self ) ;
21
+
22
+ if ( queryCache . initialized ) {
23
+ var refLastUpdate = queryCache . lastUpdate ;
24
+
25
+ // Trigger events for existing data
26
+ setTimeout ( function ( ) {
27
+ if ( queryCache . lastUpdate !== refLastUpdate ) {
28
+ // Query cache has been updated since this select object was created;
29
+ // our data would've been updated already.
30
+ return ;
31
+ }
32
+
33
+ self . emit ( 'update' , queryCache . data ) ;
34
+
35
+ if ( queryCache . data . length !== 0 && ! self . base . settings . skipDiff ) {
36
+ var diff = queryCache . data . map ( function ( row , index ) {
37
+ return [ 'added' , row , index ] ;
38
+ } ) ;
22
39
23
- if ( self . query in base . _resultsBuffer ) {
24
- setTimeout ( function ( ) {
25
- self . _setRows ( base . _resultsBuffer [ self . query ] ) ;
26
- } , 1 ) ;
40
+ diff . forEach ( function ( evt ) {
41
+ self . emit . apply ( self , evt ) ;
42
+ // New row added to end
43
+ self . data [ evt [ 2 ] ] = evt [ 1 ] ;
44
+ } ) ;
45
+ // Output all difference events in a single event
46
+ self . emit ( 'diff' , diff ) ;
47
+ }
48
+ } , 50 ) ;
27
49
} else {
28
- self . update ( ) ;
50
+ queryCache . invalidate ( ) ;
29
51
}
30
52
}
31
53
32
54
util . inherits ( LiveMysqlSelect , EventEmitter ) ;
33
55
34
- LiveMysqlSelect . prototype . _escapeQueryFun = function ( query ) {
35
- var self = this ;
36
- if ( typeof query === 'function' ) {
37
- var escId = self . base . db . escapeId ;
38
- var esc = self . base . db . escape . bind ( self . base . db ) ;
39
- return query ( esc , escId ) ;
40
- }
41
- return query ;
42
- } ;
43
-
44
56
LiveMysqlSelect . prototype . matchRowEvent = function ( event ) {
45
57
var self = this ;
46
58
var tableMap = event . tableMap [ event . tableId ] ;
@@ -72,114 +84,9 @@ LiveMysqlSelect.prototype.matchRowEvent = function(event){
72
84
return false ;
73
85
} ;
74
86
75
- LiveMysqlSelect . prototype . _setRows = function ( rows ) {
76
- var self = this ;
77
- var diff = [ ] ;
78
-
79
- // Determine what changes before updating cache in order to
80
- // be able to skip all event emissions if no change
81
- // TODO update this algorithm to use less data
82
- rows . forEach ( function ( row , index ) {
83
- if ( self . data . length - 1 < index ) {
84
- diff . push ( [ 'added' , row , index ] ) ;
85
- } else if ( JSON . stringify ( self . data [ index ] ) !== JSON . stringify ( row ) ) {
86
- diff . push ( [ 'changed' , self . data [ index ] , row , index ] ) ;
87
- }
88
- } ) ;
89
-
90
- if ( self . data . length > rows . length ) {
91
- for ( var i = self . data . length - 1 ; i >= rows . length ; i -- ) {
92
- diff . push ( [ 'removed' , self . data [ i ] , i ] ) ;
93
- }
94
- }
95
-
96
- if ( diff . length !== 0 ) {
97
- self . emit ( 'update' , rows ) ;
98
-
99
- diff . forEach ( function ( evt ) {
100
- if ( ! self . base . settings . skipDiff ) {
101
- self . emit . apply ( self , evt ) ;
102
- }
103
- switch ( evt [ 0 ] ) {
104
- case 'added' :
105
- // New row added to end
106
- self . data [ evt [ 2 ] ] = evt [ 1 ] ;
107
- break ;
108
- case 'changed' :
109
- // Update row data reference
110
- self . data [ evt [ 3 ] ] = evt [ 2 ] ;
111
- break ;
112
- case 'removed' :
113
- // Remove extra rows off the end
114
- self . data . splice ( evt [ 2 ] , 1 ) ;
115
- break ;
116
- }
117
- } ) ;
118
- if ( ! self . base . settings . skipDiff ) {
119
- // Output all difference events in a single event
120
- self . emit ( 'diff' , diff ) ;
121
- }
122
- } else if ( self . initialized === false ) {
123
- // If the result set initializes to 0 rows, it still needs to output an
124
- // update event.
125
- self . emit ( 'update' , rows ) ;
126
- }
127
-
128
- self . initialized = true ;
129
-
130
- self . lastUpdate = Date . now ( ) ;
131
- } ;
132
-
133
- LiveMysqlSelect . prototype . update = function ( callback ) {
134
- var self = this ;
135
-
136
- function _update ( ) {
137
- self . base . db . query ( self . query , function ( error , rows ) {
138
- if ( error ) {
139
- self . emit ( 'error' , error ) ;
140
- callback && callback . call ( self , error ) ;
141
- } else {
142
- self . base . _resultsBuffer [ self . query ] = rows ;
143
- self . _setRows ( rows ) ;
144
- callback && callback . call ( self , undefined , rows ) ;
145
- }
146
- } ) ;
147
- }
148
-
149
- if ( self . base . settings . minInterval === undefined ) {
150
- _update ( ) ;
151
- } else if ( self . lastUpdate + self . base . settings . minInterval < Date . now ( ) ) {
152
- _update ( ) ;
153
- } else { // Before minInterval
154
- if ( ! self . _updateTimeout ) {
155
- self . _updateTimeout = setTimeout ( function ( ) {
156
- delete self . _updateTimeout ;
157
- _update ( ) ;
158
- } , self . lastUpdate + self . base . settings . minInterval - Date . now ( ) ) ;
159
- }
160
- }
161
- } ;
162
-
163
87
LiveMysqlSelect . prototype . stop = function ( ) {
164
88
var self = this ;
165
-
166
- var index = self . base . _select . indexOf ( self ) ;
167
- if ( index !== - 1 ) {
168
- self . base . _select . splice ( index , 1 ) ;
169
-
170
- // If no other instance of the same query string, remove the resultsBuffer
171
- var sameCount = self . base . _select . filter ( function ( select ) {
172
- return select . query === self . query ;
173
- } ) . length ;
174
-
175
- if ( sameCount === 0 ) {
176
- delete self . base . _resultsBuffer [ self . query ] ;
177
- }
178
-
179
- return true ;
180
- } else {
181
- return false ;
182
- }
89
+ return self . base . _removeSelect ( self ) ;
183
90
} ;
184
91
185
92
LiveMysqlSelect . prototype . active = function ( ) {
0 commit comments