sequel 4.45.0 → 4.46.0

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.
Files changed (173) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +108 -0
  3. data/doc/release_notes/4.46.0.txt +404 -0
  4. data/doc/security.rdoc +9 -0
  5. data/doc/sql.rdoc +2 -2
  6. data/doc/testing.rdoc +1 -1
  7. data/doc/validations.rdoc +1 -2
  8. data/lib/sequel/adapters/ado.rb +8 -3
  9. data/lib/sequel/adapters/ado/access.rb +8 -4
  10. data/lib/sequel/adapters/ado/mssql.rb +3 -1
  11. data/lib/sequel/adapters/amalgalite.rb +5 -0
  12. data/lib/sequel/adapters/cubrid.rb +16 -7
  13. data/lib/sequel/adapters/do.rb +7 -1
  14. data/lib/sequel/adapters/do/mysql.rb +8 -4
  15. data/lib/sequel/adapters/ibmdb.rb +10 -5
  16. data/lib/sequel/adapters/jdbc.rb +8 -2
  17. data/lib/sequel/adapters/jdbc/as400.rb +10 -3
  18. data/lib/sequel/adapters/jdbc/db2.rb +27 -16
  19. data/lib/sequel/adapters/jdbc/derby.rb +47 -20
  20. data/lib/sequel/adapters/jdbc/h2.rb +13 -7
  21. data/lib/sequel/adapters/jdbc/hsqldb.rb +18 -9
  22. data/lib/sequel/adapters/jdbc/mssql.rb +5 -2
  23. data/lib/sequel/adapters/jdbc/mysql.rb +3 -2
  24. data/lib/sequel/adapters/jdbc/oracle.rb +3 -2
  25. data/lib/sequel/adapters/jdbc/postgresql.rb +4 -3
  26. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +2 -1
  27. data/lib/sequel/adapters/jdbc/sqlite.rb +10 -3
  28. data/lib/sequel/adapters/jdbc/sqlserver.rb +23 -0
  29. data/lib/sequel/adapters/jdbc/transactions.rb +16 -10
  30. data/lib/sequel/adapters/mock.rb +5 -0
  31. data/lib/sequel/adapters/mysql.rb +8 -1
  32. data/lib/sequel/adapters/mysql2.rb +6 -1
  33. data/lib/sequel/adapters/odbc.rb +20 -8
  34. data/lib/sequel/adapters/odbc/mssql.rb +6 -3
  35. data/lib/sequel/adapters/oracle.rb +12 -6
  36. data/lib/sequel/adapters/postgres.rb +20 -8
  37. data/lib/sequel/adapters/shared/access.rb +76 -47
  38. data/lib/sequel/adapters/shared/cubrid.rb +16 -11
  39. data/lib/sequel/adapters/shared/db2.rb +46 -19
  40. data/lib/sequel/adapters/shared/firebird.rb +20 -8
  41. data/lib/sequel/adapters/shared/informix.rb +6 -3
  42. data/lib/sequel/adapters/shared/mssql.rb +132 -72
  43. data/lib/sequel/adapters/shared/mysql.rb +112 -65
  44. data/lib/sequel/adapters/shared/oracle.rb +36 -21
  45. data/lib/sequel/adapters/shared/postgres.rb +91 -56
  46. data/lib/sequel/adapters/shared/sqlanywhere.rb +65 -37
  47. data/lib/sequel/adapters/shared/sqlite.rb +67 -32
  48. data/lib/sequel/adapters/sqlanywhere.rb +9 -1
  49. data/lib/sequel/adapters/sqlite.rb +8 -1
  50. data/lib/sequel/adapters/swift.rb +5 -0
  51. data/lib/sequel/adapters/swift/mysql.rb +4 -2
  52. data/lib/sequel/adapters/swift/sqlite.rb +1 -1
  53. data/lib/sequel/adapters/tinytds.rb +10 -3
  54. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
  55. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
  56. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -0
  57. data/lib/sequel/adapters/utils/pg_types.rb +14 -6
  58. data/lib/sequel/adapters/utils/replace.rb +4 -2
  59. data/lib/sequel/connection_pool/single.rb +2 -2
  60. data/lib/sequel/core.rb +24 -11
  61. data/lib/sequel/database/connecting.rb +9 -3
  62. data/lib/sequel/database/dataset_defaults.rb +7 -1
  63. data/lib/sequel/database/logging.rb +1 -0
  64. data/lib/sequel/database/misc.rb +5 -2
  65. data/lib/sequel/database/query.rb +7 -5
  66. data/lib/sequel/database/schema_generator.rb +1 -0
  67. data/lib/sequel/database/schema_methods.rb +50 -27
  68. data/lib/sequel/database/transactions.rb +19 -9
  69. data/lib/sequel/dataset/actions.rb +15 -6
  70. data/lib/sequel/dataset/graph.rb +15 -5
  71. data/lib/sequel/dataset/misc.rb +12 -4
  72. data/lib/sequel/dataset/mutation.rb +17 -8
  73. data/lib/sequel/dataset/prepared_statements.rb +3 -2
  74. data/lib/sequel/dataset/query.rb +84 -38
  75. data/lib/sequel/dataset/sql.rb +302 -191
  76. data/lib/sequel/deprecated.rb +26 -17
  77. data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +2 -2
  78. data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
  79. data/lib/sequel/extensions/from_block.rb +1 -0
  80. data/lib/sequel/extensions/graph_each.rb +1 -1
  81. data/lib/sequel/extensions/identifier_mangling.rb +2 -2
  82. data/lib/sequel/extensions/migration.rb +28 -4
  83. data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -0
  84. data/lib/sequel/extensions/schema_dumper.rb +4 -4
  85. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +5 -3
  86. data/lib/sequel/extensions/set_overrides.rb +2 -0
  87. data/lib/sequel/extensions/split_array_nil.rb +2 -2
  88. data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
  89. data/lib/sequel/model.rb +11 -7
  90. data/lib/sequel/model/associations.rb +5 -7
  91. data/lib/sequel/model/base.rb +47 -45
  92. data/lib/sequel/model/dataset_module.rb +9 -14
  93. data/lib/sequel/model/plugins.rb +3 -0
  94. data/lib/sequel/no_core_ext.rb +1 -0
  95. data/lib/sequel/plugins/blacklist_security.rb +1 -1
  96. data/lib/sequel/plugins/boolean_subsets.rb +7 -5
  97. data/lib/sequel/plugins/class_table_inheritance.rb +47 -10
  98. data/lib/sequel/plugins/dataset_associations.rb +1 -1
  99. data/lib/sequel/plugins/def_dataset_method.rb +90 -0
  100. data/lib/sequel/plugins/finder.rb +240 -0
  101. data/lib/sequel/plugins/inverted_subsets.rb +19 -12
  102. data/lib/sequel/plugins/many_through_many.rb +1 -1
  103. data/lib/sequel/plugins/nested_attributes.rb +1 -1
  104. data/lib/sequel/plugins/schema.rb +1 -1
  105. data/lib/sequel/plugins/single_table_inheritance.rb +7 -1
  106. data/lib/sequel/plugins/subset_conditions.rb +11 -3
  107. data/lib/sequel/plugins/whitelist_security.rb +118 -0
  108. data/lib/sequel/sql.rb +80 -36
  109. data/lib/sequel/timezones.rb +2 -0
  110. data/lib/sequel/version.rb +1 -1
  111. data/spec/adapters/mssql_spec.rb +20 -0
  112. data/spec/adapters/mysql_spec.rb +1 -1
  113. data/spec/adapters/oracle_spec.rb +12 -8
  114. data/spec/adapters/postgres_spec.rb +1 -1
  115. data/spec/adapters/spec_helper.rb +1 -1
  116. data/spec/adapters/sqlite_spec.rb +36 -34
  117. data/spec/core/connection_pool_spec.rb +2 -1
  118. data/spec/core/database_spec.rb +87 -9
  119. data/spec/core/dataset_spec.rb +501 -129
  120. data/spec/core/deprecated_spec.rb +1 -1
  121. data/spec/core/expression_filters_spec.rb +146 -60
  122. data/spec/core/mock_adapter_spec.rb +1 -1
  123. data/spec/core/object_graph_spec.rb +61 -9
  124. data/spec/core/placeholder_literalizer_spec.rb +20 -2
  125. data/spec/core/schema_generator_spec.rb +6 -6
  126. data/spec/core/schema_spec.rb +54 -5
  127. data/spec/core_extensions_spec.rb +122 -18
  128. data/spec/deprecation_helper.rb +27 -2
  129. data/spec/extensions/_deprecated_identifier_mangling_spec.rb +6 -6
  130. data/spec/extensions/association_proxies_spec.rb +2 -2
  131. data/spec/extensions/auto_literal_strings_spec.rb +212 -0
  132. data/spec/extensions/blacklist_security_spec.rb +1 -0
  133. data/spec/extensions/class_table_inheritance_spec.rb +1037 -39
  134. data/spec/extensions/column_select_spec.rb +20 -8
  135. data/spec/extensions/columns_introspection_spec.rb +3 -3
  136. data/spec/extensions/core_refinements_spec.rb +29 -12
  137. data/spec/extensions/dataset_associations_spec.rb +12 -12
  138. data/spec/extensions/def_dataset_method_spec.rb +100 -0
  139. data/spec/extensions/error_sql_spec.rb +1 -1
  140. data/spec/extensions/finder_spec.rb +260 -0
  141. data/spec/extensions/graph_each_spec.rb +2 -2
  142. data/spec/extensions/identifier_mangling_spec.rb +14 -8
  143. data/spec/extensions/inverted_subsets_spec.rb +4 -4
  144. data/spec/extensions/lazy_attributes_spec.rb +7 -0
  145. data/spec/extensions/many_through_many_spec.rb +38 -14
  146. data/spec/extensions/nested_attributes_spec.rb +18 -6
  147. data/spec/extensions/no_auto_literal_strings_spec.rb +1 -1
  148. data/spec/extensions/pg_enum_spec.rb +16 -1
  149. data/spec/extensions/pg_interval_spec.rb +11 -2
  150. data/spec/extensions/pg_loose_count_spec.rb +5 -0
  151. data/spec/extensions/pg_row_spec.rb +25 -0
  152. data/spec/extensions/prepared_statements_spec.rb +10 -1
  153. data/spec/extensions/query_spec.rb +2 -2
  154. data/spec/extensions/schema_dumper_spec.rb +2 -2
  155. data/spec/extensions/schema_spec.rb +2 -2
  156. data/spec/extensions/set_overrides_spec.rb +7 -3
  157. data/spec/extensions/sql_expr_spec.rb +0 -1
  158. data/spec/extensions/subset_conditions_spec.rb +6 -6
  159. data/spec/extensions/table_select_spec.rb +24 -12
  160. data/spec/extensions/to_dot_spec.rb +4 -4
  161. data/spec/extensions/whitelist_security_spec.rb +131 -0
  162. data/spec/integration/dataset_test.rb +9 -5
  163. data/spec/integration/model_test.rb +2 -0
  164. data/spec/integration/plugin_test.rb +2 -2
  165. data/spec/integration/spec_helper.rb +1 -1
  166. data/spec/model/associations_spec.rb +39 -11
  167. data/spec/model/base_spec.rb +44 -24
  168. data/spec/model/class_dataset_methods_spec.rb +18 -16
  169. data/spec/model/dataset_methods_spec.rb +4 -4
  170. data/spec/model/eager_loading_spec.rb +84 -24
  171. data/spec/model/model_spec.rb +97 -63
  172. data/spec/model/record_spec.rb +21 -13
  173. metadata +13 -2
@@ -18,8 +18,10 @@ module Sequel
18
18
  module DatabaseMethods
19
19
  include UnmodifiedIdentifiers::DatabaseMethods
20
20
 
21
- AUTO_VACUUM = [:none, :full, :incremental].freeze
22
21
  PRIMARY_KEY_INDEX_RE = /\Asqlite_autoindex_/.freeze
22
+ Sequel::Deprecation.deprecate_constant(self, :PRIMARY_KEY_INDEX_RE)
23
+
24
+ AUTO_VACUUM = [:none, :full, :incremental].freeze
23
25
  SYNCHRONOUS = [:off, :normal, :full].freeze
24
26
  TABLES_FILTER = Sequel.~(:name=>'sqlite_sequence'.freeze) & {:type => 'table'.freeze}
25
27
  TEMP_STORE = [:default, :file, :memory].freeze
@@ -28,7 +30,7 @@ module Sequel
28
30
  :deferred => "BEGIN DEFERRED TRANSACTION".freeze,
29
31
  :immediate => "BEGIN IMMEDIATE TRANSACTION".freeze,
30
32
  :exclusive => "BEGIN EXCLUSIVE TRANSACTION".freeze,
31
- nil => Sequel::Database::SQL_BEGIN,
33
+ nil => "BEGIN".freeze
32
34
  }.freeze
33
35
 
34
36
  # Whether to use integers for booleans in the database. SQLite recommends
@@ -114,7 +116,7 @@ module Sequel
114
116
  indexes = {}
115
117
  metadata_dataset.with_sql("PRAGMA index_list(?)", im.call(table)).each do |r|
116
118
  # :only_autocreated internal option can be used to get only autocreated indexes
117
- next if (!!(r[:name] =~ PRIMARY_KEY_INDEX_RE) ^ !!opts[:only_autocreated])
119
+ next if (!!(r[:name] =~ /\Asqlite_autoindex_/) ^ !!opts[:only_autocreated])
118
120
  indexes[m.call(r[:name])] = {:unique=>r[:unique].to_i==1}
119
121
  end
120
122
  indexes.each do |k, v|
@@ -125,6 +127,7 @@ module Sequel
125
127
 
126
128
  # Get the value of the given PRAGMA.
127
129
  def pragma_get(name)
130
+ Sequel::Deprecation.deprecate('Database#{pragma_get,auto_vacuum,case_sensitive_like,foreign_keys,synchronous,temp_store} on SQLite', "These methods may not be safe when using multiple connections, call fetch(#{"PRAGMA #{name}".inspect}).single_value if you really want to get the pragma value")
128
131
  self["PRAGMA #{name}"].single_value
129
132
  end
130
133
 
@@ -135,6 +138,7 @@ module Sequel
135
138
  # modifications should be done when the connection is created, using
136
139
  # an option provided when creating the Database object.
137
140
  def pragma_set(name, value)
141
+ Sequel::Deprecation.deprecate('Database#{pragma_set,auto_vacuum=,case_sensitive_like=,foreign_keys=,synchronous=,temp_store=} on SQLite', "These methods are not thread safe or safe when using multiple connections, pass the appropriate option when connecting to set the pragma correctly for all connections")
138
142
  execute_ddl("PRAGMA #{name} = #{value}")
139
143
  end
140
144
 
@@ -239,8 +243,8 @@ module Sequel
239
243
  # Run all alter_table commands in a transaction. This is technically only
240
244
  # needed for drop column.
241
245
  def apply_alter_table(table, ops)
242
- fks = foreign_keys
243
- self.foreign_keys = false if fks
246
+ fks = fetch("PRAGMA foreign_keys")
247
+ run "PRAGMA foreign_keys = 0" if fks
244
248
  transaction do
245
249
  if ops.length > 1 && ops.all?{|op| op[:op] == :add_constraint}
246
250
  # If you are just doing constraints, apply all of them at the same time,
@@ -253,7 +257,7 @@ module Sequel
253
257
  end
254
258
  end
255
259
  ensure
256
- self.foreign_keys = true if fks
260
+ run "PRAGMA foreign_keys = 1" if fks
257
261
  end
258
262
 
259
263
  # SQLite supports limited table modification. You can add a column
@@ -545,28 +549,50 @@ module Sequel
545
549
  include Dataset::Replace
546
550
  include UnmodifiedIdentifiers::DatasetMethods
547
551
 
548
- CONSTANT_MAP = {:CURRENT_DATE=>"date(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIMESTAMP=>"datetime(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIME=>"time(CURRENT_TIMESTAMP, 'localtime')".freeze}
549
- EMULATED_FUNCTION_MAP = {:char_length=>'length'.freeze}
550
- EXTRACT_MAP = {:year=>"'%Y'", :month=>"'%m'", :day=>"'%d'", :hour=>"'%H'", :minute=>"'%M'", :second=>"'%f'"}
551
- NOT_SPACE = Dataset::NOT_SPACE
552
- COMMA = Dataset::COMMA
553
- PAREN_CLOSE = Dataset::PAREN_CLOSE
554
- AS = Dataset::AS
555
- APOS = Dataset::APOS
552
+ CONSTANT_MAP = {:CURRENT_DATE=>"date(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIMESTAMP=>"datetime(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIME=>"time(CURRENT_TIMESTAMP, 'localtime')".freeze}#.freeze # SEQUEL5
553
+ EXTRACT_MAP = {:year=>"'%Y'", :month=>"'%m'", :day=>"'%d'", :hour=>"'%H'", :minute=>"'%M'", :second=>"'%f'"}#.freeze # SEQUEL5
554
+ #EXTRACT_MAP.each_value(&:freeze) # SEQUEL5
555
+
556
+ NOT_SPACE = 'NOT '.freeze
557
+ Sequel::Deprecation.deprecate_constant(self, :NOT_SPACE)
558
+ COMMA = ', '.freeze
559
+ Sequel::Deprecation.deprecate_constant(self, :COMMA)
560
+ PAREN_CLOSE = ')'.freeze
561
+ Sequel::Deprecation.deprecate_constant(self, :PAREN_CLOSE)
562
+ AS = ' AS '.freeze
563
+ Sequel::Deprecation.deprecate_constant(self, :AS)
564
+ APOS = "'".freeze
565
+ Sequel::Deprecation.deprecate_constant(self, :APOS)
556
566
  EXTRACT_OPEN = "CAST(strftime(".freeze
567
+ Sequel::Deprecation.deprecate_constant(self, :EXTRACT_OPEN)
557
568
  EXTRACT_CLOSE = ') AS '.freeze
569
+ Sequel::Deprecation.deprecate_constant(self, :EXTRACT_CLOSE)
558
570
  NUMERIC = 'NUMERIC'.freeze
571
+ Sequel::Deprecation.deprecate_constant(self, :NUMERIC)
559
572
  INTEGER = 'INTEGER'.freeze
573
+ Sequel::Deprecation.deprecate_constant(self, :INTEGER)
560
574
  BACKTICK = '`'.freeze
575
+ Sequel::Deprecation.deprecate_constant(self, :BACKTICK)
561
576
  BACKTICK_RE = /`/.freeze
577
+ Sequel::Deprecation.deprecate_constant(self, :BACKTICK_RE)
562
578
  DOUBLE_BACKTICK = '``'.freeze
579
+ Sequel::Deprecation.deprecate_constant(self, :DOUBLE_BACKTICK)
563
580
  BLOB_START = "X'".freeze
581
+ Sequel::Deprecation.deprecate_constant(self, :BLOB_START)
564
582
  HSTAR = "H*".freeze
583
+ Sequel::Deprecation.deprecate_constant(self, :HSTAR)
565
584
  DATE_OPEN = "date(".freeze
585
+ Sequel::Deprecation.deprecate_constant(self, :DATE_OPEN)
566
586
  DATETIME_OPEN = "datetime(".freeze
587
+ Sequel::Deprecation.deprecate_constant(self, :DATETIME_OPEN)
567
588
  ONLY_OFFSET = " LIMIT -1 OFFSET ".freeze
589
+ Sequel::Deprecation.deprecate_constant(self, :ONLY_OFFSET)
568
590
  OR = " OR ".freeze
591
+ Sequel::Deprecation.deprecate_constant(self, :OR)
569
592
  SELECT_VALUES = "VALUES ".freeze
593
+ Sequel::Deprecation.deprecate_constant(self, :SELECT_VALUES)
594
+ EMULATED_FUNCTION_MAP = {:char_length=>'length'.freeze}
595
+ Sequel::Deprecation.deprecate_constant(self, :EMULATED_FUNCTION_MAP)
570
596
 
571
597
  Dataset.def_sql_method(self, :delete, [['if db.sqlite_version >= 30803', %w'with delete from where'], ["else", %w'delete from where']])
572
598
  Dataset.def_sql_method(self, :insert, [['if db.sqlite_version >= 30803', %w'with insert conflict into columns values'], ["else", %w'insert conflict into columns values']])
@@ -575,13 +601,13 @@ module Sequel
575
601
 
576
602
  def cast_sql_append(sql, expr, type)
577
603
  if type == Time or type == DateTime
578
- sql << DATETIME_OPEN
604
+ sql << "datetime("
579
605
  literal_append(sql, expr)
580
- sql << PAREN_CLOSE
606
+ sql << ')'
581
607
  elsif type == Date
582
- sql << DATE_OPEN
608
+ sql << "date("
583
609
  literal_append(sql, expr)
584
- sql << PAREN_CLOSE
610
+ sql << ')'
585
611
  else
586
612
  super
587
613
  end
@@ -592,7 +618,7 @@ module Sequel
592
618
  def complex_expression_sql_append(sql, op, args)
593
619
  case op
594
620
  when :"NOT LIKE", :"NOT ILIKE"
595
- sql << NOT_SPACE
621
+ sql << 'NOT '
596
622
  complex_expression_sql_append(sql, (op == :"NOT ILIKE" ? :ILIKE : :LIKE), args)
597
623
  when :^
598
624
  complex_expression_arg_pairs_append(sql, args){|a, b| Sequel.lit(["((~(", " & ", ")) & (", " | ", "))"], a, b, a, b)}
@@ -605,7 +631,7 @@ module Sequel
605
631
  sql << '1'
606
632
  else
607
633
  sql << '('
608
- arg = args.at(0)
634
+ arg = args[0]
609
635
  if exp < 0
610
636
  invert = true
611
637
  exp = exp.abs
@@ -616,17 +642,17 @@ module Sequel
616
642
  sql << " * "
617
643
  end
618
644
  literal_append(sql, arg)
619
- sql << PAREN_CLOSE
645
+ sql << ')'
620
646
  if invert
621
647
  sql << "))"
622
648
  end
623
649
  end
624
650
  when :extract
625
- part = args.at(0)
651
+ part = args[0]
626
652
  raise(Sequel::Error, "unsupported extract argument: #{part.inspect}") unless format = EXTRACT_MAP[part]
627
- sql << EXTRACT_OPEN << format << COMMA
628
- literal_append(sql, args.at(1))
629
- sql << EXTRACT_CLOSE << (part == :second ? NUMERIC : INTEGER) << PAREN_CLOSE
653
+ sql << "CAST(strftime(" << format << ', '
654
+ literal_append(sql, args[1])
655
+ sql << ') AS ' << (part == :second ? 'NUMERIC' : 'INTEGER') << ')'
630
656
  else
631
657
  super
632
658
  end
@@ -669,7 +695,7 @@ module Sequel
669
695
 
670
696
  # SQLite uses the nonstandard ` (backtick) for quoting identifiers.
671
697
  def quoted_identifier_append(sql, c)
672
- sql << BACKTICK << c.to_s.gsub(BACKTICK_RE, DOUBLE_BACKTICK) << BACKTICK
698
+ sql << '`' << c.to_s.gsub('`', '``') << '`'
673
699
  end
674
700
 
675
701
  # When a qualified column is selected on SQLite and the qualifier
@@ -752,7 +778,7 @@ module Sequel
752
778
  def as_sql_append(sql, aliaz, column_aliases=nil)
753
779
  raise Error, "sqlite does not support derived column lists" if column_aliases
754
780
  aliaz = aliaz.value if aliaz.is_a?(SQL::Identifier)
755
- sql << AS
781
+ sql << ' AS '
756
782
  literal_append(sql, aliaz.to_s)
757
783
  end
758
784
 
@@ -780,19 +806,19 @@ module Sequel
780
806
 
781
807
  # SQL fragment specifying a list of identifiers
782
808
  def identifier_list(columns)
783
- columns.map{|i| quote_identifier(i)}.join(COMMA)
809
+ columns.map{|i| quote_identifier(i)}.join(', ')
784
810
  end
785
811
 
786
812
  # Add OR clauses to SQLite INSERT statements
787
813
  def insert_conflict_sql(sql)
788
814
  if resolution = @opts[:insert_conflict]
789
- sql << OR << resolution.to_s.upcase
815
+ sql << " OR " << resolution.to_s.upcase
790
816
  end
791
817
  end
792
818
 
793
819
  # SQLite uses a preceding X for hex escaping strings
794
820
  def literal_blob_append(sql, v)
795
- sql << BLOB_START << v.unpack(HSTAR).first << APOS
821
+ sql << "X'" << v.unpack("H*").first << "'"
796
822
  end
797
823
 
798
824
  # Respect the database integer_booleans setting, using 0 or 'f'.
@@ -811,6 +837,15 @@ module Sequel
811
837
  db.sqlite_version >= 30711 ? :values : :union
812
838
  end
813
839
 
840
+ # Emulate the char_length function with length
841
+ def native_function_name(emulated_function)
842
+ if emulated_function == :char_length
843
+ 'length'
844
+ else
845
+ super
846
+ end
847
+ end
848
+
814
849
  # SQLite does not support FOR UPDATE, but silently ignore it
815
850
  # instead of raising an error for compatibility with other
816
851
  # databases.
@@ -819,13 +854,13 @@ module Sequel
819
854
  end
820
855
 
821
856
  def select_only_offset_sql(sql)
822
- sql << ONLY_OFFSET
857
+ sql << " LIMIT -1 OFFSET "
823
858
  literal_append(sql, @opts[:offset])
824
859
  end
825
860
 
826
861
  # Support VALUES clause instead of the SELECT clause to return rows.
827
862
  def select_values_sql(sql)
828
- sql << SELECT_VALUES
863
+ sql << "VALUES "
829
864
  expression_list_append(sql, opts[:values])
830
865
  end
831
866
 
@@ -37,12 +37,14 @@ module Sequel
37
37
  }.each do |k,v|
38
38
  k.each{|n| SQLANYWHERE_TYPES[n] = v}
39
39
  end
40
+ # SQLANYWHERE_TYPES.freeze # SEQUEL5
40
41
 
41
42
  # Database class for SQLAnywhere databases used with Sequel.
42
43
  class Database < Sequel::Database
43
44
  include Sequel::SqlAnywhere::DatabaseMethods
44
45
 
45
46
  DEFAULT_CONFIG = { :user => 'dba', :password => 'sql' }
47
+ Sequel::Deprecation.deprecate_constant(self, :DEFAULT_CONFIG)
46
48
 
47
49
  attr_accessor :api
48
50
 
@@ -106,6 +108,7 @@ module Sequel
106
108
  private
107
109
 
108
110
  LAST_INSERT_ID = 'SELECT @@IDENTITY'.freeze
111
+ Sequel::Deprecation.deprecate_constant(self, :LAST_INSERT_ID)
109
112
  def _execute(conn, type, sql, opts)
110
113
  unless rs = log_connection_yield(sql, conn){@api.sqlany_execute_direct(conn, sql)}
111
114
  result, errstr = @api.sqlany_error(conn)
@@ -118,7 +121,7 @@ module Sequel
118
121
  when :rows
119
122
  return @api.sqlany_affected_rows(rs)
120
123
  when :insert
121
- _execute(conn, :select, LAST_INSERT_ID, opts){|r| return @api.sqlany_get_column(r, 0)[1] if r && @api.sqlany_fetch_next(r) == 1}
124
+ _execute(conn, :select, 'SELECT @@IDENTITY', opts){|r| return @api.sqlany_get_column(r, 0)[1] if r && @api.sqlany_fetch_next(r) == 1}
122
125
  end
123
126
  ensure
124
127
  @api.sqlany_commit(conn) unless in_transaction?
@@ -133,6 +136,10 @@ module Sequel
133
136
  raise LoadError, "Could not initialize SQLAnywhere DBCAPI library" if @api.sqlany_init == 0
134
137
  end
135
138
 
139
+ def dataset_class_default
140
+ Dataset
141
+ end
142
+
136
143
  def log_connection_execute(conn, sql)
137
144
  _execute(conn, nil, sql, OPTS)
138
145
  end
@@ -143,6 +150,7 @@ module Sequel
143
150
  include Sequel::SqlAnywhere::DatasetMethods
144
151
 
145
152
  Database::DatasetClass = self
153
+ Sequel::Deprecation.deprecate_constant(Database, :DatasetClass)
146
154
 
147
155
  # Yield all rows matching this dataset. If the dataset is set to
148
156
  # split multiple statements, yield arrays of hashes one per statement
@@ -74,6 +74,7 @@ module Sequel
74
74
  }.each do |k,v|
75
75
  k.each{|n| SQLITE_TYPES[n] = v}
76
76
  end
77
+ # SQLITE_TYPES.freeze # SEQUEL5
77
78
 
78
79
  # Database class for SQLite databases used with Sequel and the
79
80
  # ruby-sqlite3 driver.
@@ -275,6 +276,10 @@ module Sequel
275
276
  [SQLite3::Exception, ArgumentError]
276
277
  end
277
278
 
279
+ def dataset_class_default
280
+ Dataset
281
+ end
282
+
278
283
  # Support SQLite exception codes if ruby-sqlite3 supports them.
279
284
  # This is disabled by default because ruby-sqlite3 doesn't currently
280
285
  # support them (returning nil), and even if it did, it doesn't support
@@ -289,8 +294,10 @@ module Sequel
289
294
  include ::Sequel::SQLite::DatasetMethods
290
295
 
291
296
  Database::DatasetClass = self
297
+ Sequel::Deprecation.deprecate_constant(Database, :DatasetClass)
292
298
 
293
299
  PREPARED_ARG_PLACEHOLDER = ':'.freeze
300
+ Sequel::Deprecation.deprecate_constant(self, :PREPARED_ARG_PLACEHOLDER)
294
301
 
295
302
  # SQLite already supports named bind arguments, so use directly.
296
303
  module ArgumentMapper
@@ -367,7 +374,7 @@ module Sequel
367
374
 
368
375
  # SQLite uses a : before the name of the argument as a placeholder.
369
376
  def prepared_arg_placeholder
370
- PREPARED_ARG_PLACEHOLDER
377
+ ':'
371
378
  end
372
379
  end
373
380
  end
@@ -116,6 +116,10 @@ module Sequel
116
116
  [::Swift::Error]
117
117
  end
118
118
 
119
+ def dataset_class_default
120
+ Dataset
121
+ end
122
+
119
123
  # Set the :db entry to the same as the :database entry, since
120
124
  # Swift uses :db.
121
125
  def server_opts(o)
@@ -133,6 +137,7 @@ module Sequel
133
137
 
134
138
  class Dataset < Sequel::Dataset
135
139
  Database::DatasetClass = self
140
+ Sequel::Deprecation.deprecate_constant(Database, :DatasetClass)
136
141
 
137
142
  # Set the columns and yield the hashes to the block.
138
143
  def fetch_rows(sql)
@@ -34,13 +34,15 @@ module Sequel
34
34
  # Dataset class for MySQL datasets accessed via Swift.
35
35
  class Dataset < Swift::Dataset
36
36
  include Sequel::MySQL::DatasetMethods
37
- APOS = Dataset::APOS
37
+
38
+ APOS = "'".freeze
39
+ Sequel::Deprecation.deprecate_constant(self, :APOS)
38
40
 
39
41
  private
40
42
 
41
43
  # Use Swift's escape method for quoting.
42
44
  def literal_string_append(sql, s)
43
- sql << APOS << db.synchronize(@opts[:server]){|c| c.escape(s)} << APOS
45
+ sql << "'" << db.synchronize(@opts[:server]){|c| c.escape(s)} << "'"
44
46
  end
45
47
  end
46
48
  end
@@ -40,7 +40,7 @@ module Sequel
40
40
 
41
41
  # Use Swift's escape method for quoting.
42
42
  def literal_string_append(sql, s)
43
- sql << APOS << db.synchronize(@opts[:server]){|c| c.escape(s)} << APOS
43
+ sql << "'" << db.synchronize(@opts[:server]){|c| c.escape(s)} << "'"
44
44
  end
45
45
  end
46
46
  end
@@ -131,10 +131,16 @@ module Sequel
131
131
  end
132
132
  end
133
133
 
134
+ def dataset_class_default
135
+ Dataset
136
+ end
137
+
134
138
  TINYTDS_DISCONNECT_ERRORS = /\A(Attempt to initiate a new Adaptive Server operation with results pending|The request failed to run because the batch is aborted, this can be caused by abort signal sent from client|Adaptive Server connection timed out)/
139
+ Sequel::Deprecation.deprecate_constant(self, :TINYTDS_DISCONNECT_ERRORS)
140
+
135
141
  # Return true if the :conn argument is present and not active.
136
142
  def disconnect_error?(e, opts)
137
- super || (opts[:conn] && !opts[:conn].active?) || ((e.is_a?(::TinyTds::Error) && TINYTDS_DISCONNECT_ERRORS.match(e.message)))
143
+ super || (opts[:conn] && !opts[:conn].active?) || ((e.is_a?(::TinyTds::Error) && /\A(Attempt to initiate a new Adaptive Server operation with results pending|The request failed to run because the batch is aborted, this can be caused by abort signal sent from client|Adaptive Server connection timed out)/.match(e.message)))
138
144
  end
139
145
 
140
146
  # Dispose of any possible results of execution.
@@ -180,6 +186,7 @@ module Sequel
180
186
  include Sequel::MSSQL::DatasetMethods
181
187
 
182
188
  Database::DatasetClass = self
189
+ Sequel::Deprecation.deprecate_constant(Database, :DatasetClass)
183
190
 
184
191
  # SQLite already supports named bind arguments, so use directly.
185
192
  module ArgumentMapper
@@ -247,8 +254,8 @@ module Sequel
247
254
 
248
255
  # Properly escape the given string +v+.
249
256
  def literal_string_append(sql, v)
250
- sql << (mssql_unicode_strings ? UNICODE_STRING_START : APOS)
251
- sql << db.synchronize(@opts[:server]){|c| c.escape(v)}.gsub(BACKSLASH_CRLF_RE, BACKSLASH_CRLF_REPLACE) << APOS
257
+ sql << (mssql_unicode_strings ? "N'" : "'")
258
+ sql << db.synchronize(@opts[:server]){|c| c.escape(v)}.gsub(/\\((?:\r\n)|\n)/, '\\\\\\\\\\1\\1') << "'"
252
259
  end
253
260
 
254
261
  def prepared_statement_modules
@@ -32,7 +32,7 @@ module Sequel
32
32
  row_count = @opts[:offset_total_count] || ds.clone(:append_sql=>String.new, :placeholder_literal_null=>true).count
33
33
  dsa1 = dataset_alias(1)
34
34
 
35
- if o.is_a?(Symbol) && @opts[:bind_vars] && (match = Sequel::Dataset::PreparedStatementMethods::PLACEHOLDER_RE.match(o.to_s))
35
+ if o.is_a?(Symbol) && @opts[:bind_vars] && (match = /\A\$(.*)\z/.match(o.to_s))
36
36
  # Handle use of bound variable offsets. Unfortunately, prepared statement
37
37
  # bound variable offsets cannot be handled, since the bound variable value
38
38
  # isn't available until later.
@@ -36,7 +36,7 @@ module Sequel
36
36
  sql = @opts[:append_sql] || String.new
37
37
  subselect_sql_append(sql, unlimited.
38
38
  unordered.
39
- select_append{ROW_NUMBER{}.over(:order=>order).as(rn)}.
39
+ select_append(Sequel.function(:ROW_NUMBER).over(:order=>order).as(rn)).
40
40
  from_self(:alias=>dsa1).
41
41
  select(*columns).
42
42
  limit(@opts[:limit]).
@@ -13,6 +13,7 @@ module Sequel
13
13
  Can't connect to local MySQL server through socket
14
14
  MySQL server has gone away
15
15
  Lost connection to MySQL server during query
16
+ MySQL client is not connected
16
17
  This connection is still waiting for a result, try again once you have the result
17
18
  closed MySQL connection
18
19
  END