sequel 3.12.1 → 3.13.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 (150) hide show
  1. data/CHANGELOG +42 -0
  2. data/README.rdoc +137 -118
  3. data/Rakefile +21 -66
  4. data/doc/active_record.rdoc +9 -9
  5. data/doc/advanced_associations.rdoc +59 -188
  6. data/doc/association_basics.rdoc +15 -2
  7. data/doc/cheat_sheet.rdoc +38 -33
  8. data/doc/dataset_filtering.rdoc +16 -7
  9. data/doc/prepared_statements.rdoc +7 -7
  10. data/doc/querying.rdoc +5 -4
  11. data/doc/release_notes/3.13.0.txt +210 -0
  12. data/doc/sharding.rdoc +1 -1
  13. data/doc/sql.rdoc +5 -5
  14. data/doc/validations.rdoc +11 -11
  15. data/lib/sequel/adapters/ado.rb +1 -1
  16. data/lib/sequel/adapters/do.rb +3 -3
  17. data/lib/sequel/adapters/firebird.rb +3 -3
  18. data/lib/sequel/adapters/jdbc/h2.rb +39 -0
  19. data/lib/sequel/adapters/jdbc/mysql.rb +5 -0
  20. data/lib/sequel/adapters/jdbc/oracle.rb +3 -3
  21. data/lib/sequel/adapters/mysql.rb +7 -4
  22. data/lib/sequel/adapters/oracle.rb +3 -3
  23. data/lib/sequel/adapters/shared/mssql.rb +10 -1
  24. data/lib/sequel/adapters/shared/mysql.rb +63 -0
  25. data/lib/sequel/adapters/shared/postgres.rb +61 -3
  26. data/lib/sequel/adapters/sqlite.rb +105 -18
  27. data/lib/sequel/connection_pool.rb +31 -30
  28. data/lib/sequel/core.rb +58 -58
  29. data/lib/sequel/core_sql.rb +52 -43
  30. data/lib/sequel/database/misc.rb +11 -0
  31. data/lib/sequel/database/query.rb +55 -17
  32. data/lib/sequel/dataset/actions.rb +2 -1
  33. data/lib/sequel/dataset/query.rb +2 -3
  34. data/lib/sequel/dataset/sql.rb +24 -11
  35. data/lib/sequel/extensions/schema_dumper.rb +1 -1
  36. data/lib/sequel/metaprogramming.rb +4 -0
  37. data/lib/sequel/model.rb +37 -19
  38. data/lib/sequel/model/associations.rb +33 -25
  39. data/lib/sequel/model/base.rb +2 -2
  40. data/lib/sequel/model/plugins.rb +7 -2
  41. data/lib/sequel/plugins/active_model.rb +1 -1
  42. data/lib/sequel/plugins/association_pks.rb +2 -2
  43. data/lib/sequel/plugins/association_proxies.rb +1 -1
  44. data/lib/sequel/plugins/boolean_readers.rb +2 -2
  45. data/lib/sequel/plugins/class_table_inheritance.rb +10 -2
  46. data/lib/sequel/plugins/identity_map.rb +3 -3
  47. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  48. data/lib/sequel/plugins/json_serializer.rb +212 -0
  49. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  50. data/lib/sequel/plugins/list.rb +174 -0
  51. data/lib/sequel/plugins/many_through_many.rb +2 -2
  52. data/lib/sequel/plugins/rcte_tree.rb +6 -7
  53. data/lib/sequel/plugins/tree.rb +118 -0
  54. data/lib/sequel/plugins/xml_serializer.rb +321 -0
  55. data/lib/sequel/sql.rb +315 -206
  56. data/lib/sequel/timezones.rb +40 -17
  57. data/lib/sequel/version.rb +8 -2
  58. data/spec/adapters/firebird_spec.rb +2 -2
  59. data/spec/adapters/informix_spec.rb +1 -1
  60. data/spec/adapters/mssql_spec.rb +2 -2
  61. data/spec/adapters/mysql_spec.rb +2 -2
  62. data/spec/adapters/oracle_spec.rb +1 -1
  63. data/spec/adapters/postgres_spec.rb +36 -6
  64. data/spec/adapters/spec_helper.rb +2 -2
  65. data/spec/adapters/sqlite_spec.rb +1 -1
  66. data/spec/core/connection_pool_spec.rb +3 -3
  67. data/spec/core/core_sql_spec.rb +31 -13
  68. data/spec/core/database_spec.rb +39 -2
  69. data/spec/core/dataset_spec.rb +24 -12
  70. data/spec/core/expression_filters_spec.rb +5 -1
  71. data/spec/core/object_graph_spec.rb +1 -1
  72. data/spec/core/schema_generator_spec.rb +1 -1
  73. data/spec/core/schema_spec.rb +1 -1
  74. data/spec/core/spec_helper.rb +1 -1
  75. data/spec/core/version_spec.rb +1 -1
  76. data/spec/extensions/active_model_spec.rb +82 -67
  77. data/spec/extensions/association_dependencies_spec.rb +1 -1
  78. data/spec/extensions/association_pks_spec.rb +1 -1
  79. data/spec/extensions/association_proxies_spec.rb +1 -1
  80. data/spec/extensions/blank_spec.rb +1 -1
  81. data/spec/extensions/boolean_readers_spec.rb +1 -1
  82. data/spec/extensions/caching_spec.rb +1 -1
  83. data/spec/extensions/class_table_inheritance_spec.rb +3 -2
  84. data/spec/extensions/composition_spec.rb +2 -5
  85. data/spec/extensions/force_encoding_spec.rb +3 -1
  86. data/spec/extensions/hook_class_methods_spec.rb +1 -1
  87. data/spec/extensions/identity_map_spec.rb +1 -1
  88. data/spec/extensions/inflector_spec.rb +1 -1
  89. data/spec/extensions/instance_filters_spec.rb +1 -1
  90. data/spec/extensions/instance_hooks_spec.rb +1 -1
  91. data/spec/extensions/json_serializer_spec.rb +154 -0
  92. data/spec/extensions/lazy_attributes_spec.rb +1 -2
  93. data/spec/extensions/list_spec.rb +251 -0
  94. data/spec/extensions/looser_typecasting_spec.rb +1 -1
  95. data/spec/extensions/many_through_many_spec.rb +3 -3
  96. data/spec/extensions/migration_spec.rb +1 -1
  97. data/spec/extensions/named_timezones_spec.rb +5 -6
  98. data/spec/extensions/nested_attributes_spec.rb +1 -1
  99. data/spec/extensions/optimistic_locking_spec.rb +1 -1
  100. data/spec/extensions/pagination_spec.rb +1 -1
  101. data/spec/extensions/pretty_table_spec.rb +1 -1
  102. data/spec/extensions/query_spec.rb +1 -1
  103. data/spec/extensions/rcte_tree_spec.rb +1 -1
  104. data/spec/extensions/schema_dumper_spec.rb +3 -2
  105. data/spec/extensions/schema_spec.rb +1 -1
  106. data/spec/extensions/serialization_spec.rb +6 -2
  107. data/spec/extensions/sharding_spec.rb +1 -1
  108. data/spec/extensions/single_table_inheritance_spec.rb +1 -1
  109. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  110. data/spec/extensions/spec_helper.rb +7 -3
  111. data/spec/extensions/sql_expr_spec.rb +1 -1
  112. data/spec/extensions/string_date_time_spec.rb +1 -1
  113. data/spec/extensions/string_stripper_spec.rb +1 -1
  114. data/spec/extensions/subclasses_spec.rb +1 -1
  115. data/spec/extensions/tactical_eager_loading_spec.rb +1 -1
  116. data/spec/extensions/thread_local_timezones_spec.rb +1 -1
  117. data/spec/extensions/timestamps_spec.rb +1 -1
  118. data/spec/extensions/touch_spec.rb +1 -1
  119. data/spec/extensions/tree_spec.rb +119 -0
  120. data/spec/extensions/typecast_on_load_spec.rb +1 -1
  121. data/spec/extensions/update_primary_key_spec.rb +1 -1
  122. data/spec/extensions/validation_class_methods_spec.rb +1 -1
  123. data/spec/extensions/validation_helpers_spec.rb +1 -1
  124. data/spec/extensions/xml_serializer_spec.rb +142 -0
  125. data/spec/integration/associations_test.rb +1 -1
  126. data/spec/integration/database_test.rb +1 -1
  127. data/spec/integration/dataset_test.rb +29 -14
  128. data/spec/integration/eager_loader_test.rb +1 -1
  129. data/spec/integration/migrator_test.rb +1 -1
  130. data/spec/integration/model_test.rb +1 -1
  131. data/spec/integration/plugin_test.rb +316 -1
  132. data/spec/integration/prepared_statement_test.rb +1 -1
  133. data/spec/integration/schema_test.rb +8 -8
  134. data/spec/integration/spec_helper.rb +1 -1
  135. data/spec/integration/timezone_test.rb +1 -1
  136. data/spec/integration/transaction_test.rb +35 -20
  137. data/spec/integration/type_test.rb +1 -1
  138. data/spec/model/association_reflection_spec.rb +1 -1
  139. data/spec/model/associations_spec.rb +49 -34
  140. data/spec/model/base_spec.rb +1 -1
  141. data/spec/model/dataset_methods_spec.rb +4 -4
  142. data/spec/model/eager_loading_spec.rb +1 -1
  143. data/spec/model/hooks_spec.rb +1 -1
  144. data/spec/model/inflector_spec.rb +1 -1
  145. data/spec/model/model_spec.rb +7 -1
  146. data/spec/model/plugins_spec.rb +1 -1
  147. data/spec/model/record_spec.rb +1 -3
  148. data/spec/model/spec_helper.rb +2 -2
  149. data/spec/model/validations_spec.rb +1 -1
  150. metadata +29 -5
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper.rb')
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  # H2 and MSSQL don't support USING joins
4
4
  unless [:h2, :mssql].include?(INTEGRATION_DB.database_type)
@@ -962,3 +962,318 @@ describe "AssociationPks plugin" do
962
962
  @db[:albums_tags].filter(:album_id=>@al1).select_order_map(:tag_id).should == []
963
963
  end
964
964
  end
965
+
966
+
967
+ describe "List plugin without a scope" do
968
+ before do
969
+ @db = INTEGRATION_DB
970
+ @db.create_table :sites do
971
+ primary_key :id
972
+ String :name
973
+ Integer :position
974
+ end
975
+
976
+ @c = Class.new(Sequel::Model(@db[:sites]))
977
+ @c.plugin :list
978
+ @c.delete
979
+ @c.create :name => "hig", :position => 3
980
+ @c.create :name => "def", :position => 2
981
+ @c.create :name => "abc", :position => 1
982
+ end
983
+
984
+ after do
985
+ @db.drop_table(:sites)
986
+ end
987
+
988
+ it "should return rows in order of position" do
989
+ @c.map(:position).should == [1,2,3]
990
+ @c.map(:name).should == %w[ abc def hig ]
991
+ end
992
+
993
+ it "should define prev and next" do
994
+ i = @c[:name => "abc"]
995
+ i.prev.should == nil
996
+ i = @c[:name => "def"]
997
+ i.prev.should == @c[:name => "abc"]
998
+ i.next.should == @c[:name => "hig"]
999
+ i = @c[:name => "hig"]
1000
+ i.next.should == nil
1001
+ end
1002
+
1003
+ it "should define move_to" do
1004
+ @c[:name => "def"].move_to(1)
1005
+ @c.map(:name).should == %w[ def abc hig ]
1006
+
1007
+ @c[:name => "abc"].move_to(3)
1008
+ @c.map(:name).should == %w[ def hig abc ]
1009
+
1010
+ proc { @c[:name => "abc"].move_to(-1) }.should raise_error(Sequel::Error)
1011
+ proc { @c[:name => "abc"].move_to(10) }.should raise_error(Sequel::Error)
1012
+ end
1013
+
1014
+ it "should define move_to_top and move_to_bottom" do
1015
+ @c[:name => "def"].move_to_top
1016
+ @c.map(:name).should == %w[ def abc hig ]
1017
+
1018
+ @c[:name => "def"].move_to_bottom
1019
+ @c.map(:name).should == %w[ abc hig def ]
1020
+ end
1021
+
1022
+ it "should define move_up and move_down" do
1023
+ @c[:name => "def"].move_up
1024
+ @c.map(:name).should == %w[ def abc hig ]
1025
+
1026
+ @c[:name => "abc"].move_down
1027
+ @c.map(:name).should == %w[ def hig abc ]
1028
+
1029
+ @c[:name => "abc"].move_up(2)
1030
+ @c.map(:name).should == %w[ abc def hig ]
1031
+
1032
+ @c[:name => "abc"].move_down(2)
1033
+ @c.map(:name).should == %w[ def hig abc ]
1034
+
1035
+ proc { @c[:name => "def"].move_up(10) }.should raise_error(Sequel::Error)
1036
+ proc { @c[:name => "def"].move_down(10) }.should raise_error(Sequel::Error)
1037
+ end
1038
+ end
1039
+
1040
+ describe "List plugin with a scope" do
1041
+ before do
1042
+ @db = INTEGRATION_DB
1043
+ @db.create_table :pages do
1044
+ primary_key :id
1045
+ String :name
1046
+ Integer :pos
1047
+ Integer :parent_id
1048
+ end
1049
+
1050
+ @c = Class.new(Sequel::Model(@db[:pages]))
1051
+ @c.plugin :list, :field => :pos, :scope => :parent_id
1052
+ p1 = @c.create :name => "Hm", :pos => 1, :parent_id => 0
1053
+ p2 = @c.create :name => "Ps", :pos => 1, :parent_id => p1.id
1054
+ @c.create :name => "P1", :pos => 1, :parent_id => p2.id
1055
+ @c.create :name => "P2", :pos => 2, :parent_id => p2.id
1056
+ @c.create :name => "P3", :pos => 3, :parent_id => p2.id
1057
+ @c.create :name => "Au", :pos => 2, :parent_id => p1.id
1058
+ end
1059
+
1060
+ after do
1061
+ @db.drop_table(:pages)
1062
+ end
1063
+
1064
+ it "should return rows in order of position" do
1065
+ @c.map(:name).should == %w[ Hm Ps Au P1 P2 P3 ]
1066
+ end
1067
+
1068
+ it "should define prev and next" do
1069
+ @c[:name => "Ps"].next.name.should == 'Au'
1070
+ @c[:name => "Au"].prev.name.should == 'Ps'
1071
+ @c[:name => "P1"].next.name.should == 'P2'
1072
+ @c[:name => "P2"].prev.name.should == 'P1'
1073
+
1074
+ @c[:name => "P1"].next(2).name.should == 'P3'
1075
+ @c[:name => "P2"].next(-1).name.should == 'P1'
1076
+ @c[:name => "P3"].prev(2).name.should == 'P1'
1077
+ @c[:name => "P2"].prev(-1).name.should == 'P3'
1078
+
1079
+ @c[:name => "Ps"].prev.should == nil
1080
+ @c[:name => "Au"].next.should == nil
1081
+ @c[:name => "P1"].prev.should == nil
1082
+ @c[:name => "P3"].next.should == nil
1083
+ end
1084
+
1085
+ it "should define move_to" do
1086
+ @c[:name => "P2"].move_to(1)
1087
+ @c.map(:name).should == %w[ Hm Ps Au P2 P1 P3 ]
1088
+
1089
+ @c[:name => "P2"].move_to(3)
1090
+ @c.map(:name).should == %w[ Hm Ps Au P1 P3 P2 ]
1091
+
1092
+ proc { @c[:name => "P2"].move_to(-1) }.should raise_error(Sequel::Error)
1093
+ proc { @c[:name => "P2"].move_to(10) }.should raise_error(Sequel::Error)
1094
+ end
1095
+
1096
+ it "should define move_to_top and move_to_bottom" do
1097
+ @c[:name => "Au"].move_to_top
1098
+ @c.map(:name).should == %w[ Hm Au Ps P1 P2 P3 ]
1099
+
1100
+ @c[:name => "Au"].move_to_bottom
1101
+ @c.map(:name).should == %w[ Hm Ps Au P1 P2 P3 ]
1102
+ end
1103
+
1104
+ it "should define move_up and move_down" do
1105
+ @c[:name => "P2"].move_up
1106
+ @c.map(:name).should == %w[ Hm Ps Au P2 P1 P3 ]
1107
+
1108
+ @c[:name => "P1"].move_down
1109
+ @c.map(:name).should == %w[ Hm Ps Au P2 P3 P1 ]
1110
+
1111
+ proc { @c[:name => "P1"].move_up(10) }.should raise_error(Sequel::Error)
1112
+ proc { @c[:name => "P1"].move_down(10) }.should raise_error(Sequel::Error)
1113
+ end
1114
+ end
1115
+
1116
+ describe "Sequel::Plugins::Tree" do
1117
+ before do
1118
+ @db = INTEGRATION_DB
1119
+ end
1120
+
1121
+ describe "with natural database order" do
1122
+ before do
1123
+ @db.create_table!(:nodes) do
1124
+ Integer :id, :primary_key=>true
1125
+ String :name
1126
+ Integer :parent_id
1127
+ Integer :position
1128
+ end
1129
+
1130
+ @nodes = [{:id => 1, :name => 'one', :parent_id => nil, :position => 1},
1131
+ {:id => 2, :name => 'two', :parent_id => nil, :position => 2},
1132
+ {:id => 3, :name => 'three', :parent_id => nil, :position => 3},
1133
+ {:id => 4, :name => "two.one", :parent_id => 2, :position => 1},
1134
+ {:id => 5, :name => "two.two", :parent_id => 2, :position => 2},
1135
+ {:id => 6, :name => "two.two.one", :parent_id => 5, :position => 1},
1136
+ {:id => 7, :name => "one.two", :parent_id => 1, :position => 2},
1137
+ {:id => 8, :name => "one.one", :parent_id => 1, :position => 1},
1138
+ {:id => 9, :name => "five", :parent_id => nil, :position => 5},
1139
+ {:id => 10, :name => "four", :parent_id => nil, :position => 4},
1140
+ {:id => 11, :name => "five.one", :parent_id => 9, :position => 1},
1141
+ {:id => 12, :name => "two.three", :parent_id => 2, :position => 3}]
1142
+ @nodes.each{|node| @db[:nodes].insert(node)}
1143
+
1144
+ class ::Node < Sequel::Model
1145
+ plugin :tree
1146
+ end
1147
+ end
1148
+ after do
1149
+ @db.drop_table(:nodes)
1150
+ Object.send(:remove_const, :Node)
1151
+ end
1152
+
1153
+ it "should instantiate" do
1154
+ Node.all.size.should == 12
1155
+ end
1156
+
1157
+ it "should find top level nodes" do
1158
+ Node.roots_dataset.count.should == 5
1159
+ end
1160
+
1161
+ it "should find all descendants of a node" do
1162
+ two = Node.find(:id => 2)
1163
+ two.name.should == "two"
1164
+ two.descendants.map{|m| m[:id]}.should == [4, 5, 12, 6]
1165
+ end
1166
+
1167
+ it "should find all ancestors of a node" do
1168
+ twotwoone = Node.find(:id => 6)
1169
+ twotwoone.name.should == "two.two.one"
1170
+ twotwoone.ancestors.map{|m| m[:id]}.should == [5, 2]
1171
+ end
1172
+
1173
+ it "should find all siblings of a node, excepting self" do
1174
+ twoone = Node.find(:id => 4)
1175
+ twoone.name.should == "two.one"
1176
+ twoone.siblings.map{|m| m[:id]}.should == [5, 12]
1177
+ end
1178
+
1179
+ it "should find all siblings of a node, including self" do
1180
+ twoone = Node.find(:id => 4)
1181
+ twoone.name.should == "two.one"
1182
+ twoone.self_and_siblings.map{|m| m[:id]}.should == [4, 5, 12]
1183
+ end
1184
+
1185
+ it "should find siblings for root nodes" do
1186
+ three = Node.find(:id => 3)
1187
+ three.name.should == "three"
1188
+ three.self_and_siblings.map{|m| m[:id]}.should == [1, 2, 3, 9, 10]
1189
+ end
1190
+
1191
+ it "should find correct root for a node" do
1192
+ twotwoone = Node.find(:id => 6)
1193
+ twotwoone.name.should == "two.two.one"
1194
+ twotwoone.root[:id].should == 2
1195
+
1196
+ three = Node.find(:id => 3)
1197
+ three.name.should == "three"
1198
+ three.root[:id].should == 3
1199
+
1200
+ fiveone = Node.find(:id => 11)
1201
+ fiveone.name.should == "five.one"
1202
+ fiveone.root[:id].should == 9
1203
+ end
1204
+
1205
+ it "iterate top-level nodes in natural database order" do
1206
+ Node.roots_dataset.count.should == 5
1207
+ Node.roots.inject([]){|ids, p| ids << p.position}.should == [1, 2, 3, 5, 4]
1208
+ end
1209
+
1210
+ it "should have children" do
1211
+ one = Node.find(:id => 1)
1212
+ one.name.should == "one"
1213
+ one.children.size.should == 2
1214
+ end
1215
+
1216
+ it "children should be natural database order" do
1217
+ one = Node.find(:id => 1)
1218
+ one.name.should == "one"
1219
+ one.children.map{|m| m[:position]}.should == [2, 1]
1220
+ end
1221
+
1222
+ describe "Nodes in specified order" do
1223
+ before do
1224
+ class ::OrderedNode < Sequel::Model(:nodes)
1225
+ plugin :tree, :order => :position
1226
+ end
1227
+ end
1228
+ after do
1229
+ Object.send(:remove_const, :OrderedNode)
1230
+ end
1231
+
1232
+ it "iterate top-level nodes in order by position" do
1233
+ OrderedNode.roots_dataset.count.should == 5
1234
+ OrderedNode.roots.inject([]){|ids, p| ids << p.position}.should == [1, 2, 3, 4, 5]
1235
+ end
1236
+
1237
+ it "children should be in specified order" do
1238
+ one = OrderedNode.find(:id => 1)
1239
+ one.name.should == "one"
1240
+ one.children.map{|m| m[:position]}.should == [1, 2]
1241
+ end
1242
+ end
1243
+ end
1244
+
1245
+ describe "Lorems in specified order" do
1246
+ before do
1247
+ @db.create_table!(:lorems) do
1248
+ Integer :id, :primary_key=>true
1249
+ String :name
1250
+ Integer :ipsum_id
1251
+ Integer :neque
1252
+ end
1253
+
1254
+ @lorems = [{:id => 1, :name => 'Lorem', :ipsum_id => nil, :neque => 4},
1255
+ {:id => 2, :name => 'Ipsum', :ipsum_id => nil, :neque => 3},
1256
+ {:id => 4, :name => "Neque", :ipsum_id => 2, :neque => 2},
1257
+ {:id => 5, :name => "Porro", :ipsum_id => 2, :neque => 1}]
1258
+ @lorems.each{|lorem| @db[:lorems].insert(lorem)}
1259
+
1260
+ class ::Lorem < Sequel::Model
1261
+ plugin :tree, :key => :ipsum_id, :order => :neque
1262
+ end
1263
+ end
1264
+ after do
1265
+ @db.drop_table(:lorems)
1266
+ Object.send(:remove_const, :Lorem)
1267
+ end
1268
+
1269
+ it "iterate top-level nodes in order by position" do
1270
+ Lorem.roots_dataset.count.should == 2
1271
+ Lorem.roots.inject([]){|ids, p| ids << p.neque}.should == [3, 4]
1272
+ end
1273
+
1274
+ it "children should be specified order" do
1275
+ one = Lorem.find(:id => 2)
1276
+ one.children.map{|m| m[:neque]}.should == [1, 2]
1277
+ end
1278
+ end
1279
+ end
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper.rb')
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  describe "Prepared Statements and Bound Arguments" do
4
4
  before do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper.rb')
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  if INTEGRATION_DB.respond_to?(:schema_parse_table, true)
4
4
  describe "Database schema parser" do
@@ -78,7 +78,7 @@ describe "Database schema parser" do
78
78
  INTEGRATION_DB.schema(:items).first.last[:ruby_default].should == 'blah'
79
79
  end
80
80
 
81
- cspecify "should parse types from the schema properly", [:jdbc, :mysql] do
81
+ specify "should parse types from the schema properly" do
82
82
  INTEGRATION_DB.create_table!(:items){Integer :number}
83
83
  INTEGRATION_DB.schema(:items).first.last[:type].should == :integer
84
84
  INTEGRATION_DB.create_table!(:items){Fixnum :number}
@@ -244,24 +244,24 @@ describe "Database schema modifiers" do
244
244
  @ds.all.should == [{:n2=>'blah'}, {:n2=>'blah'}]
245
245
  end
246
246
 
247
- cspecify "should rename columns with not null constraints", [:mysql, :mysql] do
248
- @db.create_table!(:items){String :n, :null=>false}
247
+ specify "should rename columns with not null constraints" do
248
+ @db.create_table!(:items, :engine=>:InnoDB){String :n, :null=>false}
249
249
  @ds.insert(:n=>'blah')
250
250
  @db.alter_table(:items){rename_column :n, :n2}
251
251
  @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:n2]
252
252
  @ds.columns!.should == [:n2]
253
253
  @ds.insert(:n2=>'blah')
254
254
  @ds.all.should == [{:n2=>'blah'}, {:n2=>'blah'}]
255
- proc{@ds.insert}.should raise_error(Sequel::DatabaseError)
255
+ proc{@ds.insert(:n=>nil)}.should raise_error(Sequel::DatabaseError)
256
256
  end
257
257
 
258
- cspecify "should set column NULL/NOT NULL correctly", [:mysql, :mysql] do
259
- @db.create_table!(:items){Integer :id}
258
+ specify "should set column NULL/NOT NULL correctly" do
259
+ @db.create_table!(:items, :engine=>:InnoDB){Integer :id}
260
260
  @ds.insert(:id=>10)
261
261
  @db.alter_table(:items){set_column_allow_null :id, false}
262
262
  @db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
263
263
  @ds.columns!.should == [:id]
264
- proc{@ds.insert}.should raise_error(Sequel::DatabaseError)
264
+ proc{@ds.insert(:id=>nil)}.should raise_error(Sequel::DatabaseError)
265
265
  @db.alter_table(:items){set_column_allow_null :id, true}
266
266
  @ds.insert
267
267
  @ds.all.should == [{:id=>10}, {:id=>nil}]
@@ -1,7 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'logger'
3
3
  unless Object.const_defined?('Sequel')
4
- $:.unshift(File.join(File.dirname(__FILE__), "../../lib/"))
4
+ $:.unshift(File.join(File.dirname(File.expand_path(__FILE__)), "../../lib/"))
5
5
  require 'sequel'
6
6
  end
7
7
  begin
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper.rb')
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  describe "Sequel timezone support" do
4
4
  def test_timezone
@@ -1,40 +1,36 @@
1
- require File.join(File.dirname(__FILE__), 'spec_helper.rb')
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  describe "Database transactions" do
4
4
  before do
5
- INTEGRATION_DB.drop_table(:items) if INTEGRATION_DB.table_exists?(:items)
6
- INTEGRATION_DB.create_table(:items, :engine=>'InnoDB'){String :name; Integer :value}
7
- @d = INTEGRATION_DB[:items]
5
+ @db = INTEGRATION_DB
6
+ @db.drop_table(:items) if @db.table_exists?(:items)
7
+ @db.create_table(:items, :engine=>'InnoDB'){String :name; Integer :value}
8
+ @d = @db[:items]
8
9
  clear_sqls
9
10
  end
10
11
  after do
11
- INTEGRATION_DB.drop_table(:items) if INTEGRATION_DB.table_exists?(:items)
12
+ @db.drop_table(:items) if @db.table_exists?(:items)
12
13
  end
13
14
 
14
15
  specify "should support transactions" do
15
- INTEGRATION_DB.transaction do
16
- @d << {:name => 'abc', :value => 1}
17
- end
18
-
16
+ @db.transaction{@d << {:name => 'abc', :value => 1}}
19
17
  @d.count.should == 1
20
18
  end
21
19
 
22
20
  specify "should have #transaction yield the connection" do
23
- INTEGRATION_DB.transaction do |conn|
24
- conn.should_not == nil
25
- end
21
+ @db.transaction{|conn| conn.should_not == nil}
26
22
  end
27
23
 
28
24
  specify "should correctly rollback transactions" do
29
25
  proc do
30
- INTEGRATION_DB.transaction do
26
+ @db.transaction do
31
27
  @d << {:name => 'abc', :value => 1}
32
28
  raise Interrupt, 'asdf'
33
29
  end
34
30
  end.should raise_error(Interrupt)
35
31
 
36
32
  proc do
37
- INTEGRATION_DB.transaction do
33
+ @db.transaction do
38
34
  @d << {:name => 'abc', :value => 1}
39
35
  raise Sequel::Rollback
40
36
  end
@@ -44,7 +40,6 @@ describe "Database transactions" do
44
40
  end
45
41
 
46
42
  specify "should support nested transactions" do
47
- @db = INTEGRATION_DB
48
43
  @db.transaction do
49
44
  @db.transaction do
50
45
  @d << {:name => 'abc', :value => 1}
@@ -72,7 +67,6 @@ describe "Database transactions" do
72
67
 
73
68
  if INTEGRATION_DB.supports_savepoints?
74
69
  cspecify "should support nested transactions through savepoints using the savepoint option", [:jdbc, :sqlite] do
75
- @db = INTEGRATION_DB
76
70
  @db.transaction do
77
71
  @d << {:name => '1'}
78
72
  @db.transaction(:savepoint=>true) do
@@ -98,7 +92,7 @@ describe "Database transactions" do
98
92
  end
99
93
 
100
94
  specify "should handle returning inside of the block by committing" do
101
- def INTEGRATION_DB.ret_commit
95
+ def @db.ret_commit
102
96
  transaction do
103
97
  self[:items] << {:name => 'abc'}
104
98
  return
@@ -107,16 +101,37 @@ describe "Database transactions" do
107
101
  end
108
102
 
109
103
  @d.count.should == 0
110
- INTEGRATION_DB.ret_commit
104
+ @db.ret_commit
111
105
  @d.count.should == 1
112
- INTEGRATION_DB.ret_commit
106
+ @db.ret_commit
113
107
  @d.count.should == 2
114
108
  proc do
115
- INTEGRATION_DB.transaction do
109
+ @db.transaction do
116
110
  raise Interrupt, 'asdf'
117
111
  end
118
112
  end.should raise_error(Interrupt)
119
113
 
120
114
  @d.count.should == 2
121
115
  end
116
+
117
+ if INTEGRATION_DB.supports_prepared_transactions?
118
+ specify "should commit prepared transactions using commit_prepared_transaction" do
119
+ @db.transaction(:prepare=>'XYZ'){@d << {:name => '1'}}
120
+ @db.commit_prepared_transaction('XYZ')
121
+ @d.select_order_map(:name).should == ['1']
122
+ end
123
+
124
+ specify "should rollback prepared transactions using rollback_prepared_transaction" do
125
+ @db.transaction(:prepare=>'XYZ'){@d << {:name => '1'}}
126
+ @db.rollback_prepared_transaction('XYZ')
127
+ @d.select_order_map(:name).should == []
128
+ end
129
+ end
130
+
131
+ specify "should support all transaction isolation levels" do
132
+ [:uncommitted, :committed, :repeatable, :serializable].each_with_index do |l, i|
133
+ @db.transaction(:isolation=>l){@d << {:name => 'abc', :value => 1}}
134
+ @d.count.should == i + 1
135
+ end
136
+ end
122
137
  end