From 3d08496ec4c76d264d0dcc8db2d18f164d484dc4 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Wed, 30 Nov 2011 16:20:56 +0100 Subject: [PATCH 01/14] ( ( ) ( ) ) --- lib/smql_to_ar/query_builder.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/smql_to_ar/query_builder.rb b/lib/smql_to_ar/query_builder.rb index ded1481..7e88255 100644 --- a/lib/smql_to_ar/query_builder.rb +++ b/lib/smql_to_ar/query_builder.rb @@ -244,7 +244,7 @@ class SmqlToAR def default() SmqlToAR::And end def default_new( parent) default.new self, parent, false end def collect_build_where - collect {|x| x.respond_to?( :build_where) ? x.build_where : x.to_s } + collect {|x| "( #{x.respond_to?( :build_where) ? x.build_where : x.to_s } )" } end end From 3ba285548c7627671c2e42744103ad839800f1b8 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Mon, 5 Dec 2011 12:39:41 +0100 Subject: [PATCH 02/14] patch fix --- lib/smql_to_ar/query_builder.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/smql_to_ar/query_builder.rb b/lib/smql_to_ar/query_builder.rb index 7e88255..1299b4d 100644 --- a/lib/smql_to_ar/query_builder.rb +++ b/lib/smql_to_ar/query_builder.rb @@ -124,7 +124,7 @@ class SmqlToAR when :belongs_to @_joins += build_join query, pretable, t, refl.primary_key_name, premodel.primary_key when :has_and_belongs_to_many - jointable = [','] + table + jointable = [Column::Col.new('')] + table @_joins += build_join refl.options[:join_table], pretable, @table_alias[jointable], premodel.primary_key, refl.primary_key_name @_joins += build_join query, jointable, t, refl.association_foreign_key, refl.association_primary_key else raise BuilderError, "Unkown reflection macro: #{refl.macro.inspect}" From f6b957907386d59353a8aaf927bd039d33a55a50 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Thu, 12 Jan 2012 16:54:51 +0100 Subject: [PATCH 03/14] over-datanamelen-bug fixed --- lib/smql_to_ar/query_builder.rb | 50 ++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/lib/smql_to_ar/query_builder.rb b/lib/smql_to_ar/query_builder.rb index 1299b4d..81a3ca9 100644 --- a/lib/smql_to_ar/query_builder.rb +++ b/lib/smql_to_ar/query_builder.rb @@ -32,13 +32,36 @@ class SmqlToAR end class Aliases < Hash - def self.new prefix, *a, &e - e ||= lambda do |h, k| - j = Array.wrap( k).compact - h[k] = h.key?(j) ? h[j] : "#{prefix},#{j.collect( &:to_alias).join( ',')}" - end + attr_accessor :counter, :prefix + + def initialize prefix, *a, &e + @counter, @prefix = 0, prefix || 'smql' super *a, &e end + + def format name + pre, suf = name.split( ',', 2) + return name unless suf + pre += ",#{@counter += 1}," + l = 60-pre.length + n = suf[(suf.length<=l ? 0 : -l)..-1] + n == suf ? pre+n : "#{pre},,,#{n}" + end + + def name n + n.collect( &:to_alias).join ',' + end + + def [] k + n = name k + v = super n + v = self[k] = format( "#{prefix},#{n}") unless v + v + end + + def []= k, v + super name( k), v + end end attr_reader :table_alias, :model, :table_model, :base_table, :_where, :_select, :_wobs, :_joins, :prefix, :_vid @@ -48,7 +71,7 @@ class SmqlToAR @prefix = "smql" @logger = SmqlToAR.logger @table_alias = Aliases.new @prefix - @_vid, @_where, @_wobs, @model, @quoter = 0, SmqlToAR::And[], {}, model, model.connection + @_vid, @_where, @_wobs, @model, @quote = 0, SmqlToAR::And[], {}, model, model.connection @base_table = [Column::Col.new( model.table_name)] @table_alias[ @base_table] = @base_table.first t = quote_table_name @base_table.first.col @@ -77,7 +100,7 @@ class SmqlToAR end def quote_column_name name - @quoter.quote_column_name( name).gsub /"\."/, ',' + @quote.quote_column_name( name).gsub /"\."/, ',' end def quote_table_name name @@ -85,7 +108,7 @@ class SmqlToAR when Array, Column::Col then @table_alias[Array.wrap name] else name.to_s end - @quoter.quote_table_name( name).gsub /"\."/, ',' + @quote.quote_table_name name end def column table, name @@ -93,7 +116,7 @@ class SmqlToAR end def build_join orig, pretable, table, prekey, key - " LEFT JOIN #{orig} AS #{quote_table_name table} ON #{column pretable, prekey} = #{column table, key} " + "\tLEFT JOIN #{orig} AS #{quote_table_name table}\n\tON #{column pretable, prekey} = #{column table, key}\n" end def sub_joins table, col, model, query @@ -104,7 +127,8 @@ class SmqlToAR def join_ table, model, query, pretable = nil pretable ||= table[0...-1] @table_model[ table] = model - premodel = @table_model[ pretable] + @table_model.rehash + premodel = @table_model.find {|k,v| pretable == k }[1] t = @table_alias[ table] pt = quote_table_name table[ 0...-1] refl = premodel.reflections[table.last.to_sym] @@ -124,7 +148,7 @@ class SmqlToAR when :belongs_to @_joins += build_join query, pretable, t, refl.primary_key_name, premodel.primary_key when :has_and_belongs_to_many - jointable = [Column::Col.new('')] + table + jointable = [','] + table @_joins += build_join refl.options[:join_table], pretable, @table_alias[jointable], premodel.primary_key, refl.primary_key_name @_joins += build_join query, jointable, t, refl.association_foreign_key, refl.association_primary_key else raise BuilderError, "Unkown reflection macro: #{refl.macro.inspect}" @@ -195,7 +219,7 @@ class SmqlToAR class SubBuilder < Array attr_reader :parent, :_where - delegate :wobs, :joins, :includes, :sub_joins, :vid, :quote_column_name, :quoter, :quote_table_name, :column, :to => :parent + delegate :wobs, :joins, :includes, :sub_joins, :vid, :quote_column_name, :quote, :quote_table_name, :column, :to => :parent def initialize parent, tmp = false @parent = parent @@ -244,7 +268,7 @@ class SmqlToAR def default() SmqlToAR::And end def default_new( parent) default.new self, parent, false end def collect_build_where - collect {|x| "( #{x.respond_to?( :build_where) ? x.build_where : x.to_s } )" } + collect {|x| x.respond_to?( :build_where) ? x.build_where : x.to_s } end end From a4a1d1b9e9ce22463d3be7cc19347dd288c044d2 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Thu, 12 Jan 2012 16:55:25 +0100 Subject: [PATCH 04/14] v0.0.4.8 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 3e2497e..706161a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.4.7 +0.0.4.8 From 6f8569f80a6c7c15fcbc6141eccebea9685634a6 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Thu, 12 Jan 2012 17:11:55 +0100 Subject: [PATCH 05/14] =?UTF-8?q?OVERLAPS-Operator=20<=3D>=20bzw.=20=20?= =?UTF-8?q?implementiert.=20=20SmqlToAR.reload=5Flibrary=20l=C3=B6scht=20z?= =?UTF-8?q?uerst=20SmqlToAR,=20l=C3=A4d=20dann=20erst=20neu.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/smql_to_ar.rb | 5 +-- lib/smql_to_ar/condition_types.rb | 64 +++++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/lib/smql_to_ar.rb b/lib/smql_to_ar.rb index d9404b2..5071a31 100644 --- a/lib/smql_to_ar.rb +++ b/lib/smql_to_ar.rb @@ -222,10 +222,8 @@ class SmqlToAR SmqlToAR.logger = ::Rails.logger end end - else - require 'logger' - @@logger = Logger.new $stdout end + @@logger = ::Rails.logger || begin require 'logger'; Logger.new( $stdout) end class <. +# TODO: +# * Array als Typ ist zu allgemein. Allgemeine Lösung gesucht, um die Typen im Array angeben zu können. + class SmqlToAR ############################################################################# # Alle Subklassen (qualitativ: ConditionTypes::*), die als Superklasse Condition haben, @@ -104,7 +107,7 @@ class SmqlToAR end def inspect - "#{self.name}(:operator=>#{self::Operator.inspect}, :expected=>#{self::Expected.inspect}, :where=>#{self::Where.inspect})" + "#{self.name}( :operator=>#{self::Operator.inspect}, :expected=>#{self::Expected.inspect}, :where=>#{self::Where.inspect})" end end @@ -175,11 +178,11 @@ class SmqlToAR class NotInRange < Condition Operator = '!..' - Where = "%s NOT BETWEEN %s AND %s" + Where = '%s NOT BETWEEN %s AND %s' Expected = [Range, lambda {|val| Array === val && 2 == val.length } ] def initialize model, cols, val - if Array === val && 2 == val.length + if Array === val f, l = val f, l = Time.parse(f), Time.parse(l) if f.kind_of? String val = f..l @@ -196,7 +199,45 @@ class SmqlToAR self end end - InRange = simple_condition NotInRange, '..', "%s BETWEEN %s AND %s" + InRange = simple_condition NotInRange, '..', '%s BETWEEN %s AND %s' + + class NotOverlaps < Condition + Operator, Where = '', 'NOT (%s, %s) OVERLAPS (%s, %s)' + Expected = [Range, lambda {|val| + Array === val && 2 == val.length && + [Time, Date, String].any? {|v|v===val[0]} && + [Numeric, String].any? {|v|v===val[1]} + }] + + def initialize model, cols, val + if Array === val + f = Time.parse( val[0]).localtime + l = val[1] + l = case l + when String then Time.parse( l).localtime + when Numeric then f+l + else raise ArgumentError, "Unexpected type for end-value #{l.inspect}" + end + f += f.utc_offset + l += l.utc_offset + val = f.utc..l.utc + end + super model, cols, val + end + + def build builder, table + builder.wobs (v1 = builder.vid).to_sym => @value.begin, (v2 = builder.vid).to_sym => @value.end + v1 = "TIMESTAMP #{v1}" + v2 = "TIMESTAMP #{v2}" + @cols.each do |col| + col.joins builder, table + end.each_slice 2 do |f,s| + builder.where self.class::Where % [ + builder.column( table+f.path, f.col), builder.column( table+s.path, s.col), v1, v2] + end + end + end + Overlaps = simple_condition NotOverlaps, '<=>', '(%s, %s) OVERLAPS (%s, %s)' class NotIn < Condition Operator = '!|=' @@ -219,6 +260,13 @@ class SmqlToAR NotEqual2 = simple_condition Condition, '<>', "%s <> %s", [Array, String, Numeric] GreaterThanOrEqual = simple_condition Condition, '>=', "%s >= %s", [Array, Numeric] LesserThanOrEqual = simple_condition Condition, '<=', "%s <= %s", [Array, Numeric] + class StringTimeGreaterThanOrEqual < Condition + Operator, Where, Expected = '>=', '%s >= %s', [Time, Date, String] + def initialize model, cols, val + super model, cols, Time.parse( val.to_s) + end + end + StringTimeLesserThanOrEqual = simple_condition StringTimeGreaterThanOrEqual, '<=', "%s <= %s" # Examples: # { 'articles=>' => { id: 1 } } @@ -303,10 +351,12 @@ class SmqlToAR end =end - Equal = simple_condition Condition, '=', "%s = %s", [Array, String, Numeric] - Equal2 = simple_condition Equal, '', "%s = %s", [String, Numeric] + Equal = simple_condition Condition, '=', "%s = %s", [Array, String, Numeric, Date, Time] + Equal2 = simple_condition Equal, '', "%s = %s", [String, Numeric, Date, Time] GreaterThan = simple_condition Condition, '>', "%s > %s", [Array, Numeric] + StringTimeGreaterThan = simple_condition StringTimeGreaterThanOrEqual, '>', "%s > %s" LesserThan = simple_condition Condition, '<', "%s < %s", [Array, Numeric] + StringTimeLesserThan = simple_condition StringTimeGreaterThanOrEqual, '<', "%s < %s" NotIlike = simple_condition Condition, '!~', "%s NOT ILIKE %s", [Array, String] Ilike = simple_condition Condition, '~', "%s ILIKE %s", [Array, String] Exists = simple_condition Condition, '', '%s IS NOT NULL', [TrueClass] @@ -352,7 +402,7 @@ class SmqlToAR end def inspect - "#{self.name}(:name=>#{self::Name}, :expected=>#{self::Expected})" + "#{self.name}( :name=>#{self::Name}, :expected=>#{self::Expected})" end end From 40deac93bf78fb520ba836bbb075c72e5b1f2d22 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Thu, 12 Jan 2012 17:12:22 +0100 Subject: [PATCH 06/14] v0.0.5 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 706161a..bbdeab6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.4.8 +0.0.5 From 27639e24b72406db31c35ad1e2fdde28e67f0883 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Mon, 16 Jan 2012 12:52:01 +0100 Subject: [PATCH 07/14] #join: ",".to_alias OPS! --- lib/smql_to_ar/query_builder.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/smql_to_ar/query_builder.rb b/lib/smql_to_ar/query_builder.rb index 81a3ca9..af46ee5 100644 --- a/lib/smql_to_ar/query_builder.rb +++ b/lib/smql_to_ar/query_builder.rb @@ -148,7 +148,7 @@ class SmqlToAR when :belongs_to @_joins += build_join query, pretable, t, refl.primary_key_name, premodel.primary_key when :has_and_belongs_to_many - jointable = [','] + table + jointable = [Column::Col.new(',')] + table @_joins += build_join refl.options[:join_table], pretable, @table_alias[jointable], premodel.primary_key, refl.primary_key_name @_joins += build_join query, jointable, t, refl.association_foreign_key, refl.association_primary_key else raise BuilderError, "Unkown reflection macro: #{refl.macro.inspect}" From fbf5a7019c326235feb46bbbec2572bc49458d44 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Mon, 16 Jan 2012 12:52:28 +0100 Subject: [PATCH 08/14] v0.0.5.1 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index bbdeab6..442b113 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.5 +0.0.5.1 From ce81d21bd868b6cc19242cbf350eb0aecae5c17e Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Tue, 17 Jan 2012 10:52:31 +0100 Subject: [PATCH 09/14] v0.0.5.2. build-methods renamed to an underscored class-name with suffix _build and aliases build to these methods created. equal_join_build fixed; it never use col.joins.each. #foreigh_key --- VERSION | 2 +- lib/smql_to_ar/condition_types.rb | 38 +++++++++++++++++++------------ lib/smql_to_ar/query_builder.rb | 16 ++++++------- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/VERSION b/VERSION index 442b113..e338f86 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.5.1 +0.0.5.2 diff --git a/lib/smql_to_ar/condition_types.rb b/lib/smql_to_ar/condition_types.rb index 013ce6b..3691b40 100644 --- a/lib/smql_to_ar/condition_types.rb +++ b/lib/smql_to_ar/condition_types.rb @@ -153,7 +153,7 @@ class SmqlToAR # 2) {"givenname=", ["Peter", "Hans"]} #=> ( givenname = 'Peter' OR givenname = 'Hans' ) # 3) {"givenname|surname=", ["Peter", "Mueller"]} # #=> ( givenname = 'Peter' OR surname = 'Peter' ) AND ( givenname = 'Mueller' OR surname = 'Mueller' ) - def build builder, table + def condition_build builder, table values = Hash[ @value.collect {|value| [ builder.vid, value ] } ] values.each {|k, v| builder.wobs k.to_sym => v } if 1 == @cols.length @@ -174,6 +174,7 @@ class SmqlToAR end self end + alias build condition_build end class NotInRange < Condition @@ -190,7 +191,7 @@ class SmqlToAR super model, cols, val end - def build builder, table + def not_in_range_build builder, table builder.wobs (v1 = builder.vid).to_sym => @value.begin, (v2 = builder.vid).to_sym => @value.end @cols.each do |col| col.joins builder, table @@ -198,11 +199,12 @@ class SmqlToAR end self end + alias build not_in_range_build end InRange = simple_condition NotInRange, '..', '%s BETWEEN %s AND %s' - class NotOverlaps < Condition - Operator, Where = '', 'NOT (%s, %s) OVERLAPS (%s, %s)' + class Overlaps < Condition + Operator, Where = '<=>', '(%s, %s) OVERLAPS (%s, %s)' Expected = [Range, lambda {|val| Array === val && 2 == val.length && [Time, Date, String].any? {|v|v===val[0]} && @@ -225,7 +227,7 @@ class SmqlToAR super model, cols, val end - def build builder, table + def overlaps_build builder, table builder.wobs (v1 = builder.vid).to_sym => @value.begin, (v2 = builder.vid).to_sym => @value.end v1 = "TIMESTAMP #{v1}" v2 = "TIMESTAMP #{v2}" @@ -236,15 +238,16 @@ class SmqlToAR builder.column( table+f.path, f.col), builder.column( table+s.path, s.col), v1, v2] end end + alias build overlaps_build end - Overlaps = simple_condition NotOverlaps, '<=>', '(%s, %s) OVERLAPS (%s, %s)' + NotOverlaps = simple_condition Overlaps, '<=>', 'NOT (%s, %s) OVERLAPS (%s, %s)' class NotIn < Condition Operator = '!|=' Where = "%s NOT IN (%s)" Expected = [Array] - def build builder, table + def not_in_build builder, table builder.wobs (v = builder.vid).to_sym => @value @cols.each do |col| col.joins builder, table @@ -252,6 +255,7 @@ class SmqlToAR end self end + alias build not_in_build end In = simple_condition NotIn, '|=', '%s IN (%s)', [Array] @@ -290,7 +294,7 @@ class SmqlToAR raise_unless col.relation, NonExistingRelationError.new( %w[Relation], col) end - def build builder, table + def equal_join_build builder, table if 2 < @cols.first.second.length b2, b3 = And, Or else @@ -300,7 +304,7 @@ class SmqlToAR @cols.each do |col, sub| model, *sub = sub t = table + col.path + [col.col] - col.joins.each {|j, m| builder.joins table+j, m } + col.joins builder, table builder.joins t, model b4 = b3.new( b2) sub.each do |i| @@ -310,6 +314,7 @@ class SmqlToAR end self end + alias build equal_join_build end # Takes to Queries. @@ -339,7 +344,7 @@ class SmqlToAR raise_unless col.child?, ConColumnError.new( [:Column], col) end - def build builder, table + def sub_equal_join_build builder, table @cols.each do |col, sub| t = table+col.to_a builder.sub_joins t, col, *sub[0..1] @@ -348,6 +353,7 @@ class SmqlToAR end self end + alias build sub_equal_join_build end =end @@ -372,7 +378,7 @@ class SmqlToAR raise_unless col.exist_in? || SmqlToAR.model_of( col.last_model, col.col), NonExistingSelectableError.new( col) end - def build builder, table + def select_build builder, table @cols.each do |col| if col.exist_in? col.joins builder, table @@ -384,6 +390,7 @@ class SmqlToAR end self end + alias build select_build end class Functions < Condition @@ -432,7 +439,7 @@ class SmqlToAR super model, func, args end - def build builder, table + def order_build builder, table return if @args.blank? @args.each do |o| col, o = o @@ -442,26 +449,29 @@ class SmqlToAR builder.order t, col.col, o end end + alias build order_build end class Limit < Function Name = :limit Expected = [Fixnum] - def build builder, table + def limit_build builder, table raise_unless 1 == table.length, RootOnlyFunctionError.new( table) builder.limit = Array.wrap(@args).first.to_i end + alias build limit_build end class Offset < Function Name = :offset Expected = [Fixnum] - def build builder, table + def offset_build builder, table raise_unless 1 == table.length, RootOnlyFunctionError.new( table) builder.offset = Array.wrap(@args).first.to_i end + alias build offset_build end def self.new model, col, val diff --git a/lib/smql_to_ar/query_builder.rb b/lib/smql_to_ar/query_builder.rb index af46ee5..0781dc7 100644 --- a/lib/smql_to_ar/query_builder.rb +++ b/lib/smql_to_ar/query_builder.rb @@ -135,25 +135,25 @@ class SmqlToAR case refl when ActiveRecord::Reflection::ThroughReflection through = refl.through_reflection - throughtable = table[0...-1]+[Column::Col.new( through.name, table.last.as)] - srctable = throughtable+[Column::Col.new( refl.source_reflection.name, table.last.as)] + through_table = table[0...-1]+[Column::Col.new( through.name, table.last.as)] + srctable = through_table+[Column::Col.new( refl.source_reflection.name, table.last.as)] @table_model[ srctable] = model @table_alias[ table] = @table_alias[ srctable] - join_ throughtable, through.klass, quote_table_name( through.table_name) - join_ srctable, refl.klass, query, throughtable + join_ through_table, through.klass, quote_table_name( through.table_name) + join_ srctable, refl.klass, query, through_table when ActiveRecord::Reflection::AssociationReflection case refl.macro when :has_many, :has_one - @_joins += build_join query, pretable, t, premodel.primary_key, refl.primary_key_name + @_joins += build_join query, pretable, t, premodel.primary_key, refl.foreign_key when :belongs_to - @_joins += build_join query, pretable, t, refl.primary_key_name, premodel.primary_key + @_joins += build_join query, pretable, t, refl.foreign_key, premodel.primary_key when :has_and_belongs_to_many jointable = [Column::Col.new(',')] + table - @_joins += build_join refl.options[:join_table], pretable, @table_alias[jointable], premodel.primary_key, refl.primary_key_name + @_joins += build_join refl.options[:join_table], pretable, @table_alias[ jointable], premodel.primary_key, refl.foreign_key @_joins += build_join query, jointable, t, refl.association_foreign_key, refl.association_primary_key else raise BuilderError, "Unkown reflection macro: #{refl.macro.inspect}" end - else raise BuilderError, "Unkown reflection type: #{refl.class.name}" + else raise BuilderError, "Unkown reflection type: #{refl.class.name} #{refl.macro.inspect}" end self end From 08d161098714e15c0fd6715b23ccba6648263d4c Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Wed, 18 Jan 2012 13:34:26 +0100 Subject: [PATCH 10/14] optimizer optimized (AND[Or["abc"]] -> "abc"). ()-bugfix in where-clause. --- VERSION | 2 +- lib/smql_to_ar/query_builder.rb | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/VERSION b/VERSION index e338f86..78a0339 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.5.2 +0.0.5.3 diff --git a/lib/smql_to_ar/query_builder.rb b/lib/smql_to_ar/query_builder.rb index 0781dc7..4e8ad3c 100644 --- a/lib/smql_to_ar/query_builder.rb +++ b/lib/smql_to_ar/query_builder.rb @@ -248,12 +248,14 @@ class SmqlToAR def optimize! ext = [] collect! do |sub| - sub = sub.optimize! if sub.kind_of? Array + sub = sub.optimize! if sub.kind_of? SubBuilder if self.class == sub.class ext.push *sub nil elsif sub.blank? nil + elsif 1 == sub.size + sub.first else sub end @@ -267,21 +269,22 @@ class SmqlToAR end def default() SmqlToAR::And end def default_new( parent) default.new self, parent, false end - def collect_build_where - collect {|x| x.respond_to?( :build_where) ? x.build_where : x.to_s } + def collect_build_where indent = nil + indent = (indent||0) + 1 + collect {|x| "(#{x.respond_to?( :build_where) ? x.build_where( indent) : x.to_s})" } end end class And < SubBuilder def default; SmqlToAR::Or; end - def build_where - collect_build_where.join ' AND ' + def build_where indent = nil + collect_build_where( indent).join " AND\n"+"\t"*(indent||0) end end class Or < SubBuilder - def build_where - collect_build_where.join ' OR ' + def build_where indent = nil + collect_build_where( indent).join " OR\n"+"\t"*(indent||0) end end end From 7229fd185c0651867b38942098c4e73f644bc7bc Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Thu, 9 Feb 2012 13:31:24 +0100 Subject: [PATCH 11/14] overlaps: key-pairs will be ored --- lib/smql_to_ar/condition_types.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/smql_to_ar/condition_types.rb b/lib/smql_to_ar/condition_types.rb index 3691b40..548cd89 100644 --- a/lib/smql_to_ar/condition_types.rb +++ b/lib/smql_to_ar/condition_types.rb @@ -203,6 +203,7 @@ class SmqlToAR end InRange = simple_condition NotInRange, '..', '%s BETWEEN %s AND %s' + # Every key-pair will be ORed. No multiple values possible. class Overlaps < Condition Operator, Where = '<=>', '(%s, %s) OVERLAPS (%s, %s)' Expected = [Range, lambda {|val| @@ -228,6 +229,7 @@ class SmqlToAR end def overlaps_build builder, table + builder = Or.new builder builder.wobs (v1 = builder.vid).to_sym => @value.begin, (v2 = builder.vid).to_sym => @value.end v1 = "TIMESTAMP #{v1}" v2 = "TIMESTAMP #{v2}" From 3d922c5e473333a6a62ae0a5a167ce520de12b67 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Thu, 9 Feb 2012 14:10:58 +0100 Subject: [PATCH 12/14] v0.0.6 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 78a0339..1750564 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.5.3 +0.0.6 From 7f43e9fb86f411f3bdb5d1a57b327675044d080d Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Tue, 3 Jul 2012 16:28:27 +0200 Subject: [PATCH 13/14] not compatible to ruby1.8 now! new: ActiveRecordExtensions --- lib/smql_to_ar.rb | 48 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/lib/smql_to_ar.rb b/lib/smql_to_ar.rb index 5071a31..702c554 100644 --- a/lib/smql_to_ar.rb +++ b/lib/smql_to_ar.rb @@ -43,9 +43,9 @@ class SmqlToAR # Die eigentliche Exception wird in @data[:exception] hinterlegt. class SubSMQLError < SMQLError def initialize query, model, exception - ex = {:class => exception.class, :message => exception.message} + ex = {class: exception.class, message: exception.message} ex[:data] = exception.data if exception.respond_to? :data - super :query => query, :model => model.to_s, :exception => ex + super query: query, model: model.to_s, exception: ex set_backtrace exception.backtrace end end @@ -55,49 +55,49 @@ class SmqlToAR # Malformed ColOp class UnexpectedColOpError < ParseError def initialize model, colop, val - super :got => colop, :val => val, :model => model.to_s + super got: colop, val: val, model: model.to_s end end class UnexpectedError < ParseError def initialize model, colop, val - super :got => {colop => val}, :model => model.to_s + super got: {colop => val}, model: model.to_s end end class NonExistingSelectableError < SMQLError def initialize got - super :got => got + super got: got end end class NonExistingColumnError < SMQLError def initialize expected, got - super :expected => expected, :got => got + super expected: expected, got: got end end class NonExistingRelationError < SMQLError def initialize expected, got - super :expected => expected, :got => got + super expected: expected, got: got end end class ProtectedColumnError < SMQLError def initialize protected_column - super :protected_column => protected_column + super protected_column: protected_column end end class RootOnlyFunctionError < SMQLError def initialize path - super :path => path + super path: path end end class ConColumnError < SMQLError def initialize expected, got - super :expected => expected, :got => got + super expected: expected, got: got end end @@ -243,8 +243,8 @@ class SmqlToAR refls = model.respond_to?( :reflections) && model.reflections refls && refls.each do |name, refl| r[model.name][name] = case refl - when ActiveRecord::Reflection::ThroughReflection then {:macro => refl.macro, :model => refl.klass.name, :through => refl.through_reflection.name} - when ActiveRecord::Reflection::AssociationReflection then {:macro => refl.macro, :model => refl.klass.name} + when ActiveRecord::Reflection::ThroughReflection then {macro: refl.macro, model: refl.klass.name, through: refl.through_reflection.name} + when ActiveRecord::Reflection::AssociationReflection then {macro: refl.macro, model: refl.klass.name} else raise "Ups: #{refl.class}" end models.push refl.klass unless r.keys.include? refl.klass.name @@ -293,8 +293,26 @@ class SmqlToAR lib_dir = File.dirname __FILE__ fj = lambda {|*a| File.join lib_dir, *a } Object.send :remove_const, :SmqlToAR - load fj.call( 'smql_to_ar.rb') - load fj.call( 'smql_to_ar', 'condition_types.rb') - load fj.call( 'smql_to_ar', 'query_builder.rb') + load fj[ 'smql_to_ar.rb'] + load fj[ 'smql_to_ar', 'condition_types.rb'] + load fj[ 'smql_to_ar', 'query_builder.rb'] + end + + module ActiveRecordExtensions + def self.included base + base.extend ClassMethods + end + + module ClassMethods + def smql *params + SmqlToAR.to_ar self, *params + end + + def smql_protected + [] + end + end end end + +ActiveRecord::Base.send :include, SmqlToAR::ActiveRecordExtensions From a4ce8a1e6b9db2438c3f930f3f46b2d9cca40b28 Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Tue, 3 Jul 2012 16:28:46 +0200 Subject: [PATCH 14/14] v0.0.7 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 1750564..5a5831a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.6 +0.0.7