sequel 4.45.0 → 4.46.0

Sign up to get free protection for your applications and to get access to all the features.
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