Ticket #4775: multiple_keywords_ticket_query_redone.diff
| File multiple_keywords_ticket_query_redone.diff, 4.0 kB (added by wijister@…, 20 months ago) |
|---|
-
trac/ticket/tests/query.py
312 312 self.assertEqual([], args) 313 313 tickets = query.execute(Mock(href=self.env.href)) 314 314 315 def test_constrained_allof_keywords(self): 316 query = Query.from_string(self.env, None, 317 'keywords~=foo bar', 318 order='id') 319 sql, args = query.get_sql() 320 self.assertEqual(sql, 321 """SELECT t.id AS id,t.summary AS summary,t.keywords AS keywords,t.owner AS owner,t.type AS type,t.status AS status,t.priority AS priority,t.time AS time,t.changetime AS changetime,priority.value AS priority_value 322 FROM ticket AS t 323 LEFT OUTER JOIN enum AS priority ON (priority.type='priority' AND priority.name=priority) 324 WHERE (COALESCE(t.keywords,'') LIKE %s ESCAPE '/' AND COALESCE(t.keywords,'') LIKE %s ESCAPE '/') 325 ORDER BY COALESCE(t.id,0)=0,t.id""") 326 self.assertEqual(['%foo%', '%bar%'], args) 327 tickets = query.execute(Mock(href=self.env.href)) 328 315 329 def test_csv_escape(self): 316 330 query = Mock(get_columns=lambda: ['col1'], 317 331 execute=lambda r,c: [{'col1': 'value, needs escaped'}]) … … 336 350 '<em class="error">[Error: Query filter requires ' 337 351 'field and constraints separated by a "="]</em>') 338 352 339 340 353 def suite(): 341 354 suite = unittest.TestSuite() 342 355 suite.addTest(unittest.makeSuite(QueryTestCase, 'test')) -
trac/ticket/query.py
301 301 302 302 if mode == '': 303 303 return ("COALESCE(%s,'')%s=%%s" % (name, neg and '!' or ''), 304 value)304 [value]) 305 305 if not value: 306 306 return None 307 307 db = self.env.get_db_cnx() 308 308 value = db.like_escape(value) 309 310 # special case - search for keywords separated by space 311 if mode == '~' and name == 't.keywords': 312 words = value.split(' ') 313 con = '(' 314 count = 0 315 args = [] 316 # iterate the words 317 for w in words: 318 # word is empty, let's skip it 319 if w == '': 320 continue 321 if count > 0: 322 # need to append to the AND sequence 323 con = con + ' AND '; 324 con = con + "COALESCE(%s,'') %s" % (name, db.like()) 325 args.append('%' + w + '%') 326 count = count + 1 327 if (count == 0): 328 # there are no words to filter by 329 return None 330 con = con + ')' 331 return (con, args) 332 309 333 if mode == '~': 310 334 value = '%' + value + '%' 311 335 elif mode == '^': … … 314 338 value = '%' + value 315 339 return ("COALESCE(%s,'') %s%s" % (name, neg and 'NOT ' or '', 316 340 db.like()), 317 value)341 [value]) 318 342 319 343 clauses = [] 320 344 args = [] … … 368 392 else: 369 393 clauses.append("(" + " OR ".join( 370 394 [item[0] for item in constraint_sql]) + ")") 371 args += [item[1] for item in constraint_sql] 395 for item in constraint_sql: 396 args.extend(item[1]) 372 397 elif len(v) == 1: 373 398 constraint_sql = get_constraint_sql(k, v[0], mode, neg) 374 399 if constraint_sql: 375 400 clauses.append(constraint_sql[0]) 376 args. append(constraint_sql[1])401 args.extend(constraint_sql[1]) 377 402 378 403 clauses = filter(None, clauses) 379 404 if clauses:
