querybuilder 0.5.5 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,7 +1,6 @@
1
- == 0.5.4 2009-06-04
2
-
3
- * 1 minor enhancement:
4
- * Added 'use_name' to 'add_table' so you can add tables under a different name
1
+ == 0.5.6 2009-10-15
2
+ * 1 minor enhancement
3
+ * Fixed library name (was not loaded on case sensitive systems)
5
4
 
6
5
  == 0.5.4 2009-04-09
7
6
 
@@ -18,12 +17,12 @@
18
17
  * 1 minor enhancement:
19
18
  * Added support for main_table option in custom queries
20
19
  * More tests for custom queries
21
-
20
+
22
21
  == 0.5.1 2009-03-03
23
22
 
24
23
  * 1 minor enhancement:
25
24
  * Added support for glob directories in load_custom_queries
26
-
25
+
27
26
  == 0.5.0 2009-01-23
28
27
 
29
28
  * 1 major enhancement:
data/Manifest.txt CHANGED
@@ -2,7 +2,8 @@ History.txt
2
2
  Manifest.txt
3
3
  README.rdoc
4
4
  Rakefile
5
- lib/QueryBuilder.rb
5
+ lib/query_builder.rb
6
+ lib/querybuilder.rb
6
7
  script/console
7
8
  script/destroy
8
9
  script/generate
data/README.rdoc CHANGED
@@ -1,6 +1,6 @@
1
1
  = QueryBuilder
2
2
 
3
- * http://zenadmin.org/524
3
+ * http://github.com/zena/querybuilder/tree/master
4
4
 
5
5
  == DESCRIPTION:
6
6
 
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
- require File.dirname(__FILE__) + '/lib/QueryBuilder'
2
+ require File.dirname(__FILE__) + '/lib/query_builder'
3
3
 
4
4
  # Generate all the Rake tasks
5
5
  # Run 'rake -T' to see list of generated tasks (from gem root directory)
@@ -13,7 +13,7 @@ $hoe = Hoe.new('querybuilder', QueryBuilder::VERSION) do |p|
13
13
  p.extra_dev_deps = [
14
14
  ['newgem', ">= #{::Newgem::VERSION}"]
15
15
  ]
16
-
16
+
17
17
  p.clean_globs |= %w[**/.DS_Store tmp *.log]
18
18
  path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
19
19
  p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
@@ -10,24 +10,24 @@ Syntax of a query is "RELATION [where ...|] [in ...|from SUB_QUERY|]".
10
10
  =end
11
11
  class QueryBuilder
12
12
  attr_reader :tables, :where, :errors, :join_tables, :distinct, :final_parser, :page_size
13
- VERSION = '0.5.5'
14
-
13
+ VERSION = '0.5.6'
14
+
15
15
  @@main_table = {}
16
16
  @@main_class = {}
17
17
  @@custom_queries = {}
18
-
18
+
19
19
  class << self
20
20
  # This is the table name of the main class.
21
21
  def set_main_table(table_name)
22
22
  @@main_table[self] = table_name.to_s
23
23
  end
24
-
24
+
25
25
  # This is the class of the returned elements if there is no class change in the query. This
26
26
  # should correspond to the class used to build call "Foo.find_by_sql(...)" (Foo).
27
27
  def set_main_class(main_class)
28
28
  @@main_class[self] = main_class.to_s
29
29
  end
30
-
30
+
31
31
  # Load prepared SQL definitions from a set of directories. If the file does not contain "host" or "hosts" keys,
32
32
  # the filename is used as host.
33
33
  #
@@ -87,11 +87,11 @@ class QueryBuilder
87
87
  rescue NameError => err
88
88
  raise ArgumentError.new("invalid class for CustomQueries (#{klass})")
89
89
  end
90
-
90
+
91
91
  # Return the parser built from the query. The class of the returned object can be different
92
92
  # from the class used to call "new". For example: NodeQuery.new("comments from nodes in project") would
93
93
  # return a CommentQuery since that is the final fetched objects (final_parser).
94
- #
94
+ #
95
95
  # ==== Parameters
96
96
  # query<String>:: Pseudo sql query string.
97
97
  # opts<Hash>:: List of options.
@@ -111,7 +111,7 @@ class QueryBuilder
111
111
  obj.final_parser
112
112
  end
113
113
  end
114
-
114
+
115
115
  # Build a new query from a pseudo sql string. See QueryBuilder::new for details.
116
116
  def initialize(query, opts = {})
117
117
  if opts[:pre_query]
@@ -119,10 +119,10 @@ class QueryBuilder
119
119
  else
120
120
  init_with_query(query, opts)
121
121
  end
122
-
122
+
123
123
  parse_elements(@elements)
124
124
  end
125
-
125
+
126
126
  # Convert query object to a string. This string should then be evaluated.
127
127
  #
128
128
  # ==== Parameters
@@ -147,7 +147,7 @@ class QueryBuilder
147
147
  statement, bind_values = build_statement(type)
148
148
  bind_values.empty? ? "\"#{statement}\"" : "[#{[["\"#{statement}\""] + bind_values].join(', ')}]"
149
149
  end
150
-
150
+
151
151
  # Convert the query object into an SQL query.
152
152
  #
153
153
  # ==== Parameters
@@ -171,8 +171,8 @@ class QueryBuilder
171
171
  connection = get_connection(bindings)
172
172
  statement.gsub('?') { eval_bound_value(bind_values.shift, connection, bindings) }
173
173
  end
174
-
175
-
174
+
175
+
176
176
  # Test query validity
177
177
  #
178
178
  # ==== Returns
@@ -180,7 +180,7 @@ class QueryBuilder
180
180
  def valid?
181
181
  @errors == []
182
182
  end
183
-
183
+
184
184
  # Name of the pagination key when 'paginate' is used.
185
185
  #
186
186
  # ==== Parameters
@@ -195,7 +195,7 @@ class QueryBuilder
195
195
  def pagination_key
196
196
  @offset_limit_order_group[:paginate]
197
197
  end
198
-
198
+
199
199
  # Main class for the query (useful when queries move from class to class)
200
200
  #
201
201
  # ==== Returns
@@ -207,22 +207,22 @@ class QueryBuilder
207
207
  def main_class
208
208
  Module.const_get(@@main_class[self.class])
209
209
  end
210
-
210
+
211
211
  protected
212
-
212
+
213
213
  def current_table
214
214
  @current_table || main_table
215
215
  end
216
-
216
+
217
217
  def main_table
218
218
  @main_table || @@main_table[self.class]
219
219
  end
220
-
220
+
221
221
  def parse_part(part, is_last)
222
-
222
+
223
223
  rest, context = part.split(' in ')
224
224
  clause, filters = rest.split(/\s+where\s+/)
225
-
225
+
226
226
  if @just_changed_class
227
227
  # just changed class: parse filters && context
228
228
  parse_filters(filters) if filters
@@ -243,7 +243,7 @@ class QueryBuilder
243
243
  return nil
244
244
  end
245
245
  end
246
-
246
+
247
247
  def parse_filters(clause)
248
248
  # TODO: add 'match' parameter (#105)
249
249
  rest = clause.strip
@@ -261,15 +261,15 @@ class QueryBuilder
261
261
  res << " "
262
262
  elsif rest[0..0] == '('
263
263
  unless allowed.include?(:par_open)
264
- @errors << clause_error(clause, rest, res)
264
+ @errors << clause_error(clause, rest, res)
265
265
  return
266
266
  end
267
267
  res << '('
268
268
  rest = rest[1..-1]
269
269
  par_count += 1
270
- elsif rest[0..0] == ')'
270
+ elsif rest[0..0] == ')'
271
271
  unless allowed.include?(:par_close)
272
- @errors << clause_error(clause, rest, res)
272
+ @errors << clause_error(clause, rest, res)
273
273
  return
274
274
  end
275
275
  res << ')'
@@ -282,7 +282,7 @@ class QueryBuilder
282
282
  allowed = [:op, :bool_op]
283
283
  elsif rest =~ /\A((>=|<=|<>|\!=|<|=|>)|((not\s+like|like|lt|le|eq|ne|ge|gt)\s+))/
284
284
  unless allowed.include?(:op)
285
- @errors << clause_error(clause, rest, res)
285
+ @errors << clause_error(clause, rest, res)
286
286
  return
287
287
  end
288
288
  op = $1.strip
@@ -290,9 +290,9 @@ class QueryBuilder
290
290
  op = {'lt' => '<', 'le' => '<=', 'eq' => '=', 'ne' => '<>', '!=' => '<>', 'ge' => '>=', 'gt' => '>', 'like' => 'LIKE', 'not like' => 'NOT LIKE'}[op] || $1
291
291
  res << op
292
292
  allowed = [:value, :par_open]
293
- elsif rest =~ /\A("|')([^\1]*?)\1/
293
+ elsif rest =~ /\A("|')([^\1]*?)\1/
294
294
  unless allowed.include?(:value)
295
- @errors << clause_error(clause, rest, res)
295
+ @errors << clause_error(clause, rest, res)
296
296
  return
297
297
  end
298
298
  rest = rest[$&.size..-1]
@@ -300,7 +300,7 @@ class QueryBuilder
300
300
  allowed = after_value
301
301
  elsif rest =~ /\A(\d+|[\w:]+)\s+(second|minute|hour|day|week|month|year)s?/
302
302
  unless allowed.include?(:value)
303
- @errors << clause_error(clause, rest, res)
303
+ @errors << clause_error(clause, rest, res)
304
304
  return
305
305
  end
306
306
  rest = rest[$&.size..-1]
@@ -311,9 +311,9 @@ class QueryBuilder
311
311
  end
312
312
  res << "INTERVAL #{field} #{type.upcase}"
313
313
  allowed = after_value
314
- elsif rest =~ /\A(-?\d+)/
314
+ elsif rest =~ /\A(-?\d+)/
315
315
  unless allowed.include?(:value)
316
- @errors << clause_error(clause, rest, res)
316
+ @errors << clause_error(clause, rest, res)
317
317
  return
318
318
  end
319
319
  rest = rest[$&.size..-1]
@@ -321,23 +321,23 @@ class QueryBuilder
321
321
  allowed = after_value
322
322
  elsif rest =~ /\A(is\s+not\s+null|is\s+null)/
323
323
  unless allowed.include?(:bool_op)
324
- @errors << clause_error(clause, rest, res)
324
+ @errors << clause_error(clause, rest, res)
325
325
  return
326
326
  end
327
327
  rest = rest[$&.size..-1]
328
328
  res << $1.upcase
329
329
  allowed = [:par_close, :bool_op]
330
- elsif rest[0..7] == 'REF_DATE'
330
+ elsif rest[0..7] == 'REF_DATE'
331
331
  unless allowed.include?(:value)
332
- @errors << clause_error(clause, rest, res)
332
+ @errors << clause_error(clause, rest, res)
333
333
  return
334
334
  end
335
335
  rest = rest[8..-1]
336
336
  res << @ref_date
337
337
  allowed = after_value
338
- elsif rest =~ /\A(\+|\-)/
338
+ elsif rest =~ /\A(\+|\-)/
339
339
  unless allowed.include?(:op)
340
- @errors << clause_error(clause, rest, res)
340
+ @errors << clause_error(clause, rest, res)
341
341
  return
342
342
  end
343
343
  rest = rest[$&.size..-1]
@@ -345,7 +345,7 @@ class QueryBuilder
345
345
  allowed = [:value, :par_open]
346
346
  elsif rest =~ /\A(and|or)/
347
347
  unless allowed.include?(:bool_op)
348
- @errors << clause_error(clause, rest, res)
348
+ @errors << clause_error(clause, rest, res)
349
349
  return
350
350
  end
351
351
  rest = rest[$&.size..-1]
@@ -354,7 +354,7 @@ class QueryBuilder
354
354
  allowed = [:par_open, :value]
355
355
  elsif rest =~ /\A[\w:]+/
356
356
  unless allowed.include?(:value)
357
- @errors << clause_error(clause, rest, res)
357
+ @errors << clause_error(clause, rest, res)
358
358
  return
359
359
  end
360
360
  rest = rest[$&.size..-1]
@@ -365,12 +365,12 @@ class QueryBuilder
365
365
  end
366
366
  res << field
367
367
  allowed = after_value
368
- else
368
+ else
369
369
  @errors << clause_error(clause, rest, res)
370
370
  return
371
371
  end
372
372
  end
373
-
373
+
374
374
  if par_count > 0
375
375
  @errors << "invalid clause #{clause.inspect}: missing closing ')'"
376
376
  elsif allowed.include?(:value)
@@ -379,11 +379,11 @@ class QueryBuilder
379
379
  @where << (has_or ? "(#{res})" : res)
380
380
  end
381
381
  end
382
-
382
+
383
383
  def parse_order_clause(order)
384
384
  return @order unless order
385
385
  res = []
386
-
386
+
387
387
  order.split(',').each do |clause|
388
388
  if clause == 'random'
389
389
  res << "RAND()"
@@ -403,11 +403,11 @@ class QueryBuilder
403
403
  end
404
404
  res == [] ? nil : " ORDER BY #{res.join(', ')}"
405
405
  end
406
-
406
+
407
407
  def parse_group_clause(group)
408
408
  return @group unless group
409
409
  res = []
410
-
410
+
411
411
  group.split(',').each do |field|
412
412
  if fld = map_field(field, table, :group)
413
413
  res << fld
@@ -417,7 +417,7 @@ class QueryBuilder
417
417
  end
418
418
  res == [] ? nil : " GROUP BY #{res.join(', ')}"
419
419
  end
420
-
420
+
421
421
  def parse_limit_clause(limit)
422
422
  return @limit unless limit
423
423
  if limit.kind_of?(Fixnum)
@@ -432,7 +432,7 @@ class QueryBuilder
432
432
  nil
433
433
  end
434
434
  end
435
-
435
+
436
436
  def parse_paginate_clause(paginate)
437
437
  return @offset unless paginate
438
438
  if !@limit
@@ -447,7 +447,7 @@ class QueryBuilder
447
447
  nil
448
448
  end
449
449
  end
450
-
450
+
451
451
  def parse_offset_clause(offset)
452
452
  return @offset unless offset
453
453
  if !@limit
@@ -461,7 +461,7 @@ class QueryBuilder
461
461
  nil
462
462
  end
463
463
  end
464
-
464
+
465
465
  def add_table(use_name, table_name = nil)
466
466
  table_name ||= use_name
467
467
  if !@table_counter[use_name]
@@ -471,12 +471,12 @@ class QueryBuilder
471
471
  else
472
472
  @tables << table_name
473
473
  end
474
- else
474
+ else
475
475
  @table_counter[use_name] += 1
476
476
  @tables << "#{table_name} AS #{table(use_name)}"
477
477
  end
478
478
  end
479
-
479
+
480
480
  # return a unique table name for the current sub-query context, adding the table when necessary
481
481
  def needs_table(table1, table2, filter)
482
482
  @needed_tables[table2] ||= {}
@@ -486,16 +486,16 @@ class QueryBuilder
486
486
  table(table2)
487
487
  end
488
488
  end
489
-
489
+
490
490
  # versions LEFT JOIN dyn_attributes ON ...
491
491
  def needs_join_table(table1, type, table2, clause, join_name = nil)
492
492
  join_name ||= "#{table1}=#{type}=#{table2}"
493
493
  @needed_join_tables[join_name] ||= {}
494
494
  @needed_join_tables[join_name][table] ||= begin
495
495
  # define join for this part ('table' = unique for each part)
496
-
496
+
497
497
  first_table = table(table1)
498
-
498
+
499
499
  if !@table_counter[table2]
500
500
  @table_counter[table2] = 0
501
501
  second_table = table2
@@ -508,22 +508,22 @@ class QueryBuilder
508
508
  table(table2)
509
509
  end
510
510
  end
511
-
511
+
512
512
  def table_counter(table_name)
513
513
  @table_counter[table_name] || 0
514
514
  end
515
-
515
+
516
516
  def table_at(table_name, index)
517
517
  if index < 0
518
518
  return nil # no table at this address
519
519
  end
520
520
  index == 0 ? table_name : "#{table_name[0..1]}#{index}"
521
521
  end
522
-
522
+
523
523
  def table(table_name=main_table, index=0)
524
524
  table_at(table_name, table_counter(table_name) + index)
525
525
  end
526
-
526
+
527
527
  def merge_alternate_queries(alt_queries)
528
528
  counter = 1
529
529
  if valid?
@@ -539,13 +539,13 @@ class QueryBuilder
539
539
  end
540
540
  counter = 0
541
541
  end
542
-
542
+
543
543
  if @where.compact == []
544
544
  where_list = []
545
545
  else
546
546
  where_list = [@where.compact.reverse.join(' AND ')]
547
547
  end
548
-
548
+
549
549
  alt_queries.each do |query|
550
550
  next unless query.main_class == self.main_class # no mixed class target !
551
551
  @errors += query.errors unless @ignore_warnings
@@ -557,13 +557,13 @@ class QueryBuilder
557
557
  @distinct ||= query.distinct
558
558
  where_list << query.where.reverse.join(' AND ')
559
559
  end
560
-
560
+
561
561
  @where_list = where_list
562
-
562
+
563
563
  @tables.uniq!
564
-
564
+
565
565
  fix_where_list(where_list)
566
-
566
+
567
567
  if counter > 1
568
568
  @distinct = @tables.size > 1
569
569
  @where = ["((#{where_list.join(') OR (')}))"]
@@ -571,7 +571,7 @@ class QueryBuilder
571
571
  @where = where_list
572
572
  end
573
573
  end
574
-
574
+
575
575
  def merge_tables(sub_query)
576
576
  @tables += sub_query.tables
577
577
  sub_query.join_tables.each do |k,v|
@@ -579,7 +579,7 @@ class QueryBuilder
579
579
  @join_tables[k] << v
580
580
  end
581
581
  end
582
-
582
+
583
583
  def prepare_custom_query_arguments(key, value)
584
584
  if value.kind_of?(Array)
585
585
  value.map {|e| parse_custom_query_argument(key, e)}
@@ -595,7 +595,7 @@ class QueryBuilder
595
595
  parse_custom_query_argument(key, value)
596
596
  end
597
597
  end
598
-
598
+
599
599
  # Map a field to be used inside a query. An attr is a field from table at index 0 = @node attribute.
600
600
  def field_or_attr(fld, table_name = table, context = nil)
601
601
  if fld =~ /^\d+$/
@@ -612,7 +612,7 @@ class QueryBuilder
612
612
  map_attr(fld)
613
613
  end
614
614
  end
615
-
615
+
616
616
  def build_statement(type = :find)
617
617
  statement = type == :find ? find_statement : count_statement
618
618
 
@@ -624,7 +624,7 @@ class QueryBuilder
624
624
  end
625
625
  [statement, bind_values]
626
626
  end
627
-
627
+
628
628
  def find_statement
629
629
  table_list = []
630
630
  @tables.each do |t|
@@ -644,7 +644,7 @@ class QueryBuilder
644
644
 
645
645
  "SELECT #{@select.join(',')} FROM #{table_list.flatten.join(',')}" + (@where == [] ? '' : " WHERE #{@where.reverse.join(' AND ')}") + group.to_s + @order.to_s + @limit.to_s + @offset.to_s
646
646
  end
647
-
647
+
648
648
  def count_statement
649
649
  table_list = []
650
650
  @tables.each do |t|
@@ -668,7 +668,7 @@ class QueryBuilder
668
668
 
669
669
  "SELECT #{count_on} FROM #{table_list.flatten.join(',')}" + (@where == [] ? '' : " WHERE #{@where.reverse.join(' AND ')}")
670
670
  end
671
-
671
+
672
672
  # Adapted from Rail's ActiveRecord code. We need "eval" because
673
673
  # QueryBuilder is a compiler and it has absolutely no knowledge
674
674
  # of the running context.
@@ -693,47 +693,47 @@ class QueryBuilder
693
693
  def class_from_table(table_name)
694
694
  Object
695
695
  end
696
-
696
+
697
697
  def default_context_filter
698
698
  raise NameError.new("default_context_filter not defined for class #{self.class}")
699
699
  end
700
-
700
+
701
701
  # Default sort order
702
702
  def default_order_clause
703
703
  nil
704
704
  end
705
-
705
+
706
706
  def after_parse
707
707
  # do nothing
708
708
  end
709
-
709
+
710
710
  def parse_change_class(rel, is_last)
711
711
  nil
712
712
  end
713
-
713
+
714
714
  def parse_relation(clause, context)
715
715
  return nil
716
716
  end
717
-
717
+
718
718
  def context_filter_fields(clause, is_last = false)
719
719
  nil
720
720
  end
721
-
721
+
722
722
  def parse_context(clause, is_last = false)
723
-
723
+
724
724
  if fields = context_filter_fields(clause, is_last)
725
725
  @where << "#{field_or_attr(fields[0])} = #{field_or_attr(fields[1], table(main_table,-1))}" if fields != :void
726
726
  else
727
727
  @errors << "invalid context '#{clause}'"
728
728
  end
729
729
  end
730
-
730
+
731
731
  # Map a litteral value to be used inside a query
732
732
  def map_literal(value, env = :sql)
733
733
  env == :sql ? insert_bind(value.inspect) : value
734
734
  end
735
-
736
-
735
+
736
+
737
737
  # Overwrite this and take car to check for valid fields.
738
738
  def map_field(fld, table_name, context = nil)
739
739
  if fld == 'id'
@@ -742,11 +742,11 @@ class QueryBuilder
742
742
  # TODO: error, raise / ignore ?
743
743
  end
744
744
  end
745
-
745
+
746
746
  def map_attr(fld)
747
747
  insert_bind(fld.to_s)
748
748
  end
749
-
749
+
750
750
  # ******** And maybe overwrite these **********
751
751
  def parse_custom_query_argument(key, value)
752
752
  return nil unless value
@@ -760,19 +760,19 @@ class QueryBuilder
760
760
  value
761
761
  end
762
762
  end
763
-
763
+
764
764
  def extract_custom_query(list)
765
765
  list[-1].split(' ').first
766
766
  end
767
-
767
+
768
768
  private
769
-
769
+
770
770
  def parse_elements(elements)
771
771
  # "final_parser" is the parser who will respond to 'to_sql'. It might be a sub-parser for another class.
772
772
  @final_parser = self
773
-
774
- if @@custom_queries[self.class] &&
775
- @@custom_queries[self.class][@opts[:custom_query_group]] &&
773
+
774
+ if @@custom_queries[self.class] &&
775
+ @@custom_queries[self.class][@opts[:custom_query_group]] &&
776
776
  custom_query = @@custom_queries[self.class][@opts[:custom_query_group]][extract_custom_query(elements)]
777
777
  custom_query.each do |k,v|
778
778
  instance_variable_set("@#{k}", prepare_custom_query_arguments(k.to_sym, v))
@@ -787,21 +787,21 @@ class QueryBuilder
787
787
  clause, filters = elements[-1].split(/\s+where\s+/)
788
788
 
789
789
  parse_filters(filters) if filters
790
-
790
+
791
791
  @limit = parse_limit_clause(@offset_limit_order_group[:limit])
792
792
  if @offset_limit_order_group[:paginate]
793
793
  @offset = parse_paginate_clause(@offset_limit_order_group[:paginate])
794
794
  else
795
795
  @offset = parse_offset_clause(@offset_limit_order_group[:offset])
796
796
  end
797
-
797
+
798
798
  @order = parse_order_clause(@offset_limit_order_group[:order])
799
799
  else
800
800
  i, new_class = 0, nil
801
801
  elements.each_index do |i|
802
802
  break if new_class = parse_part(elements[i], i == 0) # yes, is_last is first (parsing reverse)
803
803
  end
804
-
804
+
805
805
  if new_class
806
806
  # move to another parser class
807
807
  @final_parser = new_class.new(nil, :pre_query => self, :elements => elements[i..-1])
@@ -829,10 +829,10 @@ class QueryBuilder
829
829
  @where.compact!
830
830
  end
831
831
  end
832
-
832
+
833
833
  def init_with_query(query, opts)
834
834
  @opts = opts
835
-
835
+
836
836
  if query.kind_of?(Array)
837
837
  @query = query[0]
838
838
  if query.size > 1
@@ -841,8 +841,8 @@ class QueryBuilder
841
841
  else
842
842
  @query = query
843
843
  end
844
-
845
-
844
+
845
+
846
846
  @offset_limit_order_group = {}
847
847
  if @query == nil || @query == ''
848
848
  elements = [main_table]
@@ -855,11 +855,11 @@ class QueryBuilder
855
855
  last_element, @offset_limit_order_group[:order] = last_element.split(' order by ')
856
856
  elements[-1], @offset_limit_order_group[:group] = last_element.split(' group by ')
857
857
  end
858
-
858
+
859
859
  @offset_limit_order_group[:limit] = opts[:limit] || @offset_limit_order_group[:limit]
860
860
  # In order to know the table names of the dependencies, we need to parse it backwards.
861
861
  # We first find the closest elements, then the final ones. For example, "pages from project" we need
862
- # project information before getting 'pages'.
862
+ # project information before getting 'pages'.
863
863
  @elements = elements.reverse
864
864
 
865
865
  @tables = []
@@ -888,15 +888,15 @@ class QueryBuilder
888
888
  @just_changed_class = true
889
889
  @elements = elements
890
890
  end
891
-
891
+
892
892
  def clause_error(clause, rest, res)
893
893
  "invalid clause #{clause.inspect} near \"#{res[-2..-1]}#{rest[0..1]}\""
894
894
  end
895
-
895
+
896
896
  def insert_bind(str)
897
897
  "[[#{str}]]"
898
898
  end
899
-
899
+
900
900
  # Make sure all clauses are compatible (where_list is a list of strings, not arrays)
901
901
  def fix_where_list(where_list)
902
902
  # do nothing
@@ -0,0 +1 @@
1
+ require 'query_builder'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: querybuilder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gaspard Bucher
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-04 00:00:00 +02:00
12
+ date: 2009-10-15 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -42,7 +42,12 @@ dependencies:
42
42
  - !ruby/object:Gem::Version
43
43
  version: 1.8.0
44
44
  version:
45
- description: "QueryBuilder is an interpreter for the \"pseudo sql\" language. This language can be used for two purposes: 1. protect your database from illegal SQL by securing queries 2. ease writing complex relational queries by abstracting table internals"
45
+ description: |-
46
+ QueryBuilder is an interpreter for the "pseudo sql" language. This language
47
+ can be used for two purposes:
48
+
49
+ 1. protect your database from illegal SQL by securing queries
50
+ 2. ease writing complex relational queries by abstracting table internals
46
51
  email:
47
52
  - gaspard@teti.ch
48
53
  executables: []
@@ -58,11 +63,11 @@ files:
58
63
  - Manifest.txt
59
64
  - README.rdoc
60
65
  - Rakefile
61
- - lib/QueryBuilder.rb
66
+ - lib/query_builder.rb
67
+ - lib/querybuilder.rb
62
68
  - script/console
63
69
  - script/destroy
64
70
  - script/generate
65
- - test/mock/custom_queries
66
71
  - test/mock/custom_queries/test.yml
67
72
  - test/mock/dummy_query.rb
68
73
  - test/mock/user_query.rb
@@ -74,7 +79,9 @@ files:
74
79
  - test/test_helper.rb
75
80
  - test/test_QueryBuilder.rb
76
81
  has_rdoc: true
77
- homepage: http://zenadmin.org/524
82
+ homepage: http://github.com/zena/querybuilder/tree/master
83
+ licenses: []
84
+
78
85
  post_install_message:
79
86
  rdoc_options:
80
87
  - --main
@@ -96,9 +103,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
103
  requirements: []
97
104
 
98
105
  rubyforge_project: querybuilder
99
- rubygems_version: 1.3.1
106
+ rubygems_version: 1.3.5
100
107
  signing_key:
101
- specification_version: 2
108
+ specification_version: 3
102
109
  summary: QueryBuilder is an interpreter for the "pseudo sql" language
103
110
  test_files:
104
111
  - test/test_helper.rb