1 |
|
2 |
|
3 | var sphinxQLClient = require('mysql'),
|
4 | util = require ('util'),
|
5 | task = require ('./base');
|
6 |
|
7 | var sphinxConfig = project.config.db.sphinx;
|
8 |
|
9 |
|
10 |
|
11 | var sphinx = module.exports = function (config) {
|
12 | this.init (config);
|
13 | };
|
14 |
|
15 | util.inherits(sphinx, task);
|
16 |
|
17 | util.extend(sphinx.prototype, {
|
18 |
|
19 | _getConnection: function () {
|
20 |
|
21 | var self = this;
|
22 |
|
23 | if (this.connection)
|
24 | return this.connection;
|
25 |
|
26 | self.connection = sphinxQLClient.createConnection(sphinxConfig);
|
27 | self.connection.on('error', function (err) {
|
28 | if (!err.fatal) {
|
29 | self.failed('Fatal error while connecting to server');
|
30 | return;
|
31 | }
|
32 | if (err.code !== 'PROTOCOL_CONNECTION_LOST') {
|
33 | throw err;
|
34 | }
|
35 | if (self.verbose) console.log('Re-connecting lost connection');
|
36 | self.connection = sphinxQLClient.createConnection(sphinxConfig);
|
37 | });
|
38 |
|
39 | if (self.verbose) console.log('Sphinx connection created');
|
40 | return self.connection;
|
41 | },
|
42 |
|
43 | _openConnection: function (cb) {
|
44 | var self = this;
|
45 | var sphinxQL = self._getConnection();
|
46 |
|
47 | sphinxQL.connect(function (err) {
|
48 | if (err) {
|
49 | self.failed({
|
50 | 'code' : err.code,
|
51 | 'err' : err.fatal
|
52 | });
|
53 | } else {
|
54 | cb.call(self, sphinxQL);
|
55 | }
|
56 | });
|
57 | },
|
58 |
|
59 | run: function () {
|
60 |
|
61 |
|
62 | var self = this,
|
63 | select_expr = self.select_expr || '*',
|
64 | index = self.index || sphinxConfig.index,
|
65 | pager = self.pager,
|
66 | match_fields = self.match_fields,
|
67 | match = self.match || pager.match,
|
68 | options = self.options || 'ranker=sph04';
|
69 |
|
70 |
|
71 |
|
72 | if (!match) {
|
73 | return self.completed({
|
74 | ids: null
|
75 | });
|
76 | }
|
77 |
|
78 |
|
79 |
|
80 | match = match.split(' ');
|
81 | match = match.map(function (item) {
|
82 | return item + '*';
|
83 | });
|
84 | match = match.join(' ');
|
85 |
|
86 |
|
87 | if (match_fields) {
|
88 | match_fields = "@(" + match_fields.join(',') + ") ";
|
89 | } else {
|
90 | match_fields = "";
|
91 | }
|
92 |
|
93 | if (! pager) {
|
94 | pager = {};
|
95 | pager.start = 0;
|
96 | pager.limit = 10;
|
97 | }
|
98 |
|
99 | var limit = [pager.start, pager.limit].join(',');
|
100 |
|
101 | self._openConnection(function (sphinxQL) {
|
102 | var query = [
|
103 | "SELECT " + select_expr,
|
104 | "FROM " + index,
|
105 | "WHERE MATCH(" + sphinxQL.escape(match_fields + match) + ")",
|
106 | "LIMIT " + limit,
|
107 | "OPTION " + options
|
108 | ].join(' ');
|
109 |
|
110 | var data = [];
|
111 | var res = sphinxQL.query(query);
|
112 |
|
113 | res.on('result', function(row) {
|
114 | if (self.verbose) console.log('row',row);
|
115 | data.push(row._id);
|
116 | })
|
117 | .on('error', function(err) {
|
118 | console.log('Query to execute', query);
|
119 | console.log('Query error', err);
|
120 | self.failed({
|
121 | 'code' : err.code,
|
122 | 'err' : err.fatal
|
123 | });
|
124 | })
|
125 | .on('end', function() {
|
126 | if (self.verbose) console.log('Done with all results');
|
127 | self.completed({
|
128 | ids: data
|
129 | });
|
130 | });
|
131 | });
|
132 | },
|
133 |
|
134 |
|
135 | getObjProp: function (obj, path) {
|
136 | var props = path.split('.');
|
137 | props.forEach(function (prop) {
|
138 | if (obj.hasOwnProperty(prop)) {
|
139 | obj = obj[prop];
|
140 | } else {
|
141 | return;
|
142 | }
|
143 | });
|
144 |
|
145 | return obj;
|
146 | },
|
147 |
|
148 | insert: function () {
|
149 | var self = this,
|
150 | records = self.records,
|
151 | mapping = self.mapping,
|
152 | index = self.index || sphinxConfig.index
|
153 |
|
154 | self._openConnection(function (sphinxQL) {
|
155 |
|
156 | values = [];
|
157 | records.forEach(function (record) {
|
158 | var id = parseInt(record._id.toString().substring(16,24), 16);
|
159 | var tmpValues = [sphinxQL.escape(id)];
|
160 | mapping.forEach(function (prop) {
|
161 | tmpValues.push(
|
162 | sphinxQL.escape(
|
163 | self.getObjProp(record, prop).toString()
|
164 | )
|
165 | );
|
166 | });
|
167 | values.push("(" + tmpValues.join(',') + ")");
|
168 | });
|
169 |
|
170 |
|
171 | var query = [
|
172 | "INSERT INTO " + index,
|
173 | "VALUES ",
|
174 | values.join(',')
|
175 | ].join(' ');
|
176 |
|
177 | if (self.verbose)
|
178 | console.log('Query to execute', query);
|
179 |
|
180 |
|
181 | var res = sphinxQL.query(query);
|
182 |
|
183 | res.on('error', function(err) {
|
184 | console.log('Query to execute', query);
|
185 | console.log('Query error', err);
|
186 | self.failed({
|
187 | 'code' : err.code,
|
188 | 'err' : err.fatal
|
189 | });
|
190 | }).on('end', function() {
|
191 | if (self.verbose) console.log('Done with all results');
|
192 | self.completed({
|
193 | ok: true
|
194 | });
|
195 | });
|
196 |
|
197 | });
|
198 | }
|
199 | });
|