Module | Sequel::SQL::DateAdd::DatasetMethods |
In: |
lib/sequel/extensions/date_arithmetic.rb
|
These methods are added to datasets using the date_arithmetic extension, for the purposes of correctly literalizing DateAdd expressions for the appropriate database type.
DURATION_UNITS | = | [:years, :months, :days, :hours, :minutes, :seconds].freeze |
DEF_DURATION_UNITS | = | DURATION_UNITS.zip(DURATION_UNITS.map{|s| s.to_s.freeze}).freeze |
MYSQL_DURATION_UNITS | = | DURATION_UNITS.zip(DURATION_UNITS.map{|s| Sequel.lit(s.to_s.upcase[0...-1]).freeze}).freeze |
MSSQL_DURATION_UNITS | = | DURATION_UNITS.zip(DURATION_UNITS.map{|s| Sequel.lit(s.to_s[0...-1]).freeze}).freeze |
H2_DURATION_UNITS | = | DURATION_UNITS.zip(DURATION_UNITS.map{|s| s.to_s[0...-1].freeze}).freeze |
DERBY_DURATION_UNITS | = | DURATION_UNITS.zip(DURATION_UNITS.map{|s| Sequel.lit("SQL_TSI_#{s.to_s.upcase[0...-1]}").freeze}).freeze |
ACCESS_DURATION_UNITS | = | DURATION_UNITS.zip(%w'yyyy m d h n s'.map{|s| s.freeze}).freeze |
DB2_DURATION_UNITS | = | DURATION_UNITS.zip(DURATION_UNITS.map{|s| Sequel.lit(s.to_s).freeze}).freeze |
FDBSQL_DURATION_UNITS | = | DURATION_UNITS.zip(DURATION_UNITS.map{|s| Sequel.lit(s.to_s.chop).freeze}).freeze |
Append the SQL fragment for the DateAdd expression to the SQL query.
# File lib/sequel/extensions/date_arithmetic.rb, line 68 68: def date_add_sql_append(sql, da) 69: h = da.interval 70: expr = da.expr 71: cast = case db_type = db.database_type 72: when :postgres 73: interval = "" 74: each_valid_interval_unit(h, DEF_DURATION_UNITS) do |value, sql_unit| 75: interval << "#{value} #{sql_unit} " 76: end 77: if interval.empty? 78: return literal_append(sql, Sequel.cast(expr, Time)) 79: else 80: return complex_expression_sql_append(sql, :+, [Sequel.cast(expr, Time), Sequel.cast(interval, :interval)]) 81: end 82: when :sqlite 83: args = [expr] 84: each_valid_interval_unit(h, DEF_DURATION_UNITS) do |value, sql_unit| 85: args << "#{value} #{sql_unit}" 86: end 87: return function_sql_append(sql, Sequel.function(:datetime, *args)) 88: when :mysql, :hsqldb, :cubrid 89: if db_type == :hsqldb 90: # HSQLDB requires 2.2.9+ for the DATE_ADD function 91: expr = Sequel.cast(expr, Time) 92: end 93: each_valid_interval_unit(h, MYSQL_DURATION_UNITS) do |value, sql_unit| 94: expr = Sequel.function(:DATE_ADD, expr, Sequel.lit(["INTERVAL ", " "], value, sql_unit)) 95: end 96: when :mssql, :h2, :access, :sqlanywhere 97: units = case db_type 98: when :mssql, :sqlanywhere 99: MSSQL_DURATION_UNITS 100: when :h2 101: H2_DURATION_UNITS 102: when :access 103: ACCESS_DURATION_UNITS 104: end 105: each_valid_interval_unit(h, units) do |value, sql_unit| 106: expr = Sequel.function(:DATEADD, sql_unit, value, expr) 107: end 108: when :derby 109: if expr.is_a?(Date) && !expr.is_a?(DateTime) 110: # Work around for https://issues.apache.org/jira/browse/DERBY-896 111: expr = Sequel.cast_string(expr) + ' 00:00:00' 112: end 113: each_valid_interval_unit(h, DERBY_DURATION_UNITS) do |value, sql_unit| 114: expr = Sequel.lit(["{fn timestampadd(#{sql_unit}, ", ", timestamp(", "))}"], value, expr) 115: end 116: when :oracle 117: each_valid_interval_unit(h, MYSQL_DURATION_UNITS) do |value, sql_unit| 118: expr = Sequel.+(expr, Sequel.lit(["INTERVAL ", " "], value.to_s, sql_unit)) 119: end 120: when :db2 121: expr = Sequel.cast(expr, Time) 122: each_valid_interval_unit(h, DB2_DURATION_UNITS) do |value, sql_unit| 123: expr = Sequel.+(expr, Sequel.lit(["", " "], value, sql_unit)) 124: end 125: false 126: when :fdbsql 127: each_valid_interval_unit(h, FDBSQL_DURATION_UNITS) do |value, sql_unit| 128: expr = Sequel.+(expr, Sequel.lit(["INTERVAL ", " "], value, sql_unit)) 129: end 130: else 131: raise Error, "date arithmetic is not implemented on #{db.database_type}" 132: end 133: 134: if cast 135: expr = Sequel.cast(expr, Time) 136: end 137: 138: literal_append(sql, expr) 139: end