querybuilder 0.5.5 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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