sequel 3.34.0 → 3.35.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 (102) hide show
  1. data/CHANGELOG +56 -0
  2. data/README.rdoc +3 -1
  3. data/Rakefile +2 -10
  4. data/doc/active_record.rdoc +1 -0
  5. data/doc/migration.rdoc +18 -7
  6. data/doc/model_hooks.rdoc +6 -0
  7. data/doc/opening_databases.rdoc +3 -0
  8. data/doc/prepared_statements.rdoc +0 -1
  9. data/doc/release_notes/3.35.0.txt +144 -0
  10. data/doc/schema_modification.rdoc +16 -1
  11. data/doc/thread_safety.rdoc +17 -0
  12. data/lib/sequel/adapters/do/postgres.rb +1 -52
  13. data/lib/sequel/adapters/do/sqlite.rb +0 -5
  14. data/lib/sequel/adapters/do.rb +2 -2
  15. data/lib/sequel/adapters/firebird.rb +1 -1
  16. data/lib/sequel/adapters/ibmdb.rb +2 -2
  17. data/lib/sequel/adapters/jdbc/db2.rb +0 -5
  18. data/lib/sequel/adapters/jdbc/derby.rb +29 -2
  19. data/lib/sequel/adapters/jdbc/firebird.rb +0 -5
  20. data/lib/sequel/adapters/jdbc/h2.rb +1 -1
  21. data/lib/sequel/adapters/jdbc/hsqldb.rb +7 -0
  22. data/lib/sequel/adapters/jdbc/informix.rb +0 -5
  23. data/lib/sequel/adapters/jdbc/jtds.rb +0 -5
  24. data/lib/sequel/adapters/jdbc/mysql.rb +0 -5
  25. data/lib/sequel/adapters/jdbc/postgresql.rb +4 -35
  26. data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
  27. data/lib/sequel/adapters/jdbc/sqlserver.rb +0 -5
  28. data/lib/sequel/adapters/jdbc/transactions.rb +4 -4
  29. data/lib/sequel/adapters/jdbc.rb +23 -19
  30. data/lib/sequel/adapters/mysql2.rb +1 -1
  31. data/lib/sequel/adapters/odbc/mssql.rb +14 -1
  32. data/lib/sequel/adapters/odbc.rb +3 -3
  33. data/lib/sequel/adapters/oracle.rb +6 -18
  34. data/lib/sequel/adapters/postgres.rb +36 -53
  35. data/lib/sequel/adapters/shared/db2.rb +16 -2
  36. data/lib/sequel/adapters/shared/mssql.rb +40 -9
  37. data/lib/sequel/adapters/shared/mysql.rb +16 -4
  38. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +2 -2
  39. data/lib/sequel/adapters/shared/oracle.rb +2 -0
  40. data/lib/sequel/adapters/shared/postgres.rb +135 -211
  41. data/lib/sequel/adapters/sqlite.rb +2 -2
  42. data/lib/sequel/adapters/swift/postgres.rb +1 -71
  43. data/lib/sequel/adapters/swift.rb +1 -1
  44. data/lib/sequel/adapters/tinytds.rb +3 -3
  45. data/lib/sequel/core.rb +27 -4
  46. data/lib/sequel/database/connecting.rb +7 -8
  47. data/lib/sequel/database/logging.rb +6 -1
  48. data/lib/sequel/database/misc.rb +20 -4
  49. data/lib/sequel/database/query.rb +38 -18
  50. data/lib/sequel/database/schema_generator.rb +5 -2
  51. data/lib/sequel/database/schema_methods.rb +34 -8
  52. data/lib/sequel/dataset/prepared_statements.rb +1 -1
  53. data/lib/sequel/dataset/sql.rb +18 -24
  54. data/lib/sequel/extensions/core_extensions.rb +0 -23
  55. data/lib/sequel/extensions/migration.rb +22 -8
  56. data/lib/sequel/extensions/pg_auto_parameterize.rb +4 -0
  57. data/lib/sequel/extensions/schema_dumper.rb +1 -1
  58. data/lib/sequel/model/associations.rb +95 -70
  59. data/lib/sequel/model/base.rb +19 -20
  60. data/lib/sequel/model.rb +2 -2
  61. data/lib/sequel/plugins/dirty.rb +214 -0
  62. data/lib/sequel/plugins/identity_map.rb +1 -1
  63. data/lib/sequel/plugins/json_serializer.rb +16 -1
  64. data/lib/sequel/plugins/many_through_many.rb +22 -32
  65. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +2 -2
  66. data/lib/sequel/plugins/prepared_statements.rb +22 -8
  67. data/lib/sequel/plugins/prepared_statements_associations.rb +2 -3
  68. data/lib/sequel/plugins/prepared_statements_with_pk.rb +1 -1
  69. data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
  70. data/lib/sequel/plugins/subclasses.rb +10 -2
  71. data/lib/sequel/plugins/timestamps.rb +1 -1
  72. data/lib/sequel/plugins/xml_serializer.rb +12 -1
  73. data/lib/sequel/sql.rb +1 -1
  74. data/lib/sequel/version.rb +1 -1
  75. data/spec/adapters/postgres_spec.rb +30 -79
  76. data/spec/core/database_spec.rb +46 -2
  77. data/spec/core/dataset_spec.rb +28 -22
  78. data/spec/core/schema_generator_spec.rb +1 -1
  79. data/spec/core/schema_spec.rb +51 -0
  80. data/spec/extensions/arbitrary_servers_spec.rb +0 -4
  81. data/spec/extensions/association_autoreloading_spec.rb +17 -0
  82. data/spec/extensions/association_proxies_spec.rb +4 -4
  83. data/spec/extensions/core_extensions_spec.rb +1 -24
  84. data/spec/extensions/dirty_spec.rb +155 -0
  85. data/spec/extensions/json_serializer_spec.rb +13 -0
  86. data/spec/extensions/migration_spec.rb +28 -15
  87. data/spec/extensions/named_timezones_spec.rb +6 -8
  88. data/spec/extensions/pg_auto_parameterize_spec.rb +6 -5
  89. data/spec/extensions/schema_dumper_spec.rb +3 -1
  90. data/spec/extensions/single_table_inheritance_spec.rb +5 -0
  91. data/spec/extensions/xml_serializer_spec.rb +13 -0
  92. data/spec/files/{transactionless_migrations → transaction_specified_migrations}/001_create_alt_basic.rb +1 -1
  93. data/spec/integration/associations_test.rb +5 -7
  94. data/spec/integration/dataset_test.rb +25 -7
  95. data/spec/integration/plugin_test.rb +1 -1
  96. data/spec/integration/schema_test.rb +16 -1
  97. data/spec/model/associations_spec.rb +2 -2
  98. metadata +14 -9
  99. data/lib/sequel/adapters/odbc/db2.rb +0 -17
  100. /data/spec/files/{transactionless_migrations → transaction_specified_migrations}/002_create_basic.rb +0 -0
  101. /data/spec/files/{transaction_migrations → transaction_unspecified_migrations}/001_create_alt_basic.rb +0 -0
  102. /data/spec/files/{transaction_migrations → transaction_unspecified_migrations}/002_create_basic.rb +0 -0
@@ -0,0 +1,155 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "Sequel::Plugins::Dirty" do
4
+ before do
5
+ @db = Sequel.mock(:fetch=>{:initial=>'i', :initial_changed=>'ic'}, :numrows=>1)
6
+ @c = Class.new(Sequel::Model(@db[:c]))
7
+ @c.plugin :dirty
8
+ @c.columns :initial, :initial_changed, :missing, :missing_changed
9
+ end
10
+
11
+ shared_examples_for "dirty plugin" do
12
+ it "initial_value should be the current value if value has not changed" do
13
+ @o.initial_value(:initial).should == 'i'
14
+ @o.initial_value(:missing).should == nil
15
+ end
16
+
17
+ it "initial_value should be the intial value if value has changed" do
18
+ @o.initial_value(:initial_changed).should == 'ic'
19
+ @o.initial_value(:missing_changed).should == nil
20
+ end
21
+
22
+ it "initial_value should handle case where initial value is reassigned later" do
23
+ @o.initial_changed = 'ic'
24
+ @o.initial_value(:initial_changed).should == 'ic'
25
+ @o.missing_changed = nil
26
+ @o.initial_value(:missing_changed).should == nil
27
+ end
28
+
29
+ it "changed_columns should handle case where initial value is reassigned later" do
30
+ @o.changed_columns.should == [:initial_changed, :missing_changed]
31
+ @o.initial_changed = 'ic'
32
+ @o.changed_columns.should == [:missing_changed]
33
+ @o.missing_changed = nil
34
+ @o.changed_columns.should == [:missing_changed]
35
+ end
36
+
37
+ it "column_change should give initial and current values if there has been a change made" do
38
+ @o.column_change(:initial_changed).should == ['ic', 'ic2']
39
+ @o.column_change(:missing_changed).should == [nil, 'mc2']
40
+ end
41
+
42
+ it "column_change should be nil if no change has been made" do
43
+ @o.column_change(:initial).should == nil
44
+ @o.column_change(:missing).should == nil
45
+ end
46
+
47
+ it "column_changed? should return whether the column has changed" do
48
+ @o.column_changed?(:initial).should == false
49
+ @o.column_changed?(:initial_changed).should == true
50
+ @o.column_changed?(:missing).should == false
51
+ @o.column_changed?(:missing_changed).should == true
52
+ end
53
+
54
+ it "column_changed? should handle case where initial value is reassigned later" do
55
+ @o.initial_changed = 'ic'
56
+ @o.column_changed?(:initial_changed).should == false
57
+ @o.missing_changed = nil
58
+ @o.column_changed?(:missing_changed).should == false
59
+ end
60
+
61
+ it "changed_columns should handle case where initial value is reassigned later" do
62
+ @o.changed_columns.should == [:initial_changed, :missing_changed]
63
+ @o.initial_changed = 'ic'
64
+ @o.changed_columns.should == [:missing_changed]
65
+ @o.missing_changed = nil
66
+ @o.changed_columns.should == [:missing_changed]
67
+ end
68
+
69
+ it "column_changes should give initial and current values" do
70
+ @o.column_changes.should == {:initial_changed=>['ic', 'ic2'], :missing_changed=>[nil, 'mc2']}
71
+ end
72
+
73
+ it "reset_column should reset the column to its initial value" do
74
+ @o.reset_column(:initial)
75
+ @o.initial.should == 'i'
76
+ @o.reset_column(:initial_changed)
77
+ @o.initial_changed.should == 'ic'
78
+ @o.reset_column(:missing)
79
+ @o.missing.should == nil
80
+ @o.reset_column(:missing_changed)
81
+ @o.missing_changed.should == nil
82
+ end
83
+
84
+ it "reset_column should remove missing values from the values" do
85
+ @o.reset_column(:missing)
86
+ @o.values.has_key?(:missing).should == false
87
+ @o.reset_column(:missing_changed)
88
+ @o.values.has_key?(:missing_changed).should == false
89
+ end
90
+
91
+ it "refresh should clear the cached initial values" do
92
+ @o.refresh
93
+ @o.column_changes.should == {}
94
+ end
95
+
96
+ it "will_change_column should be used to signal in-place modification to column" do
97
+ @o.will_change_column(:initial)
98
+ @o.initial << 'b'
99
+ @o.column_change(:initial).should == ['i', 'ib']
100
+ @o.will_change_column(:initial_changed)
101
+ @o.initial_changed << 'b'
102
+ @o.column_change(:initial_changed).should == ['ic', 'ic2b']
103
+ @o.will_change_column(:missing)
104
+ @o.values[:missing] = 'b'
105
+ @o.column_change(:missing).should == [nil, 'b']
106
+ @o.will_change_column(:missing_changed)
107
+ @o.missing_changed << 'b'
108
+ @o.column_change(:missing_changed).should == [nil, 'mc2b']
109
+ end
110
+
111
+ it "will_change_column should different types of existing objects" do
112
+ [nil, true, false, Class.new{undef_method :clone}.new, Class.new{def clone; raise TypeError; end}.new].each do |v|
113
+ o = @c.new(:initial=>v)
114
+ o.will_change_column(:initial)
115
+ o.initial = 'a'
116
+ o.column_change(:initial).should == [v, 'a']
117
+ end
118
+ end
119
+
120
+ it "save should clear the cached initial values" do
121
+ @o.save
122
+ @o.column_changes.should == {}
123
+ end
124
+
125
+ it "save_changes should clear the cached initial values" do
126
+ @o.save_changes
127
+ @o.column_changes.should == {}
128
+ end
129
+ end
130
+
131
+ describe "with new instance" do
132
+ before do
133
+ @o = @c.new(:initial=>'i', :initial_changed=>'ic')
134
+ @o.initial_changed = 'ic2'
135
+ @o.missing_changed = 'mc2'
136
+ end
137
+
138
+ it_should_behave_like "dirty plugin"
139
+ end
140
+
141
+ describe "with existing instance" do
142
+ before do
143
+ @o = @c[1]
144
+ @o.initial_changed = 'ic2'
145
+ @o.missing_changed = 'mc2'
146
+ end
147
+
148
+ it_should_behave_like "dirty plugin"
149
+
150
+ it "previous_changes should be the previous changes after saving" do
151
+ @o.save
152
+ @o.previous_changes.should == {:initial_changed=>['ic', 'ic2'], :missing_changed=>[nil, 'mc2']}
153
+ end
154
+ end
155
+ end
@@ -116,6 +116,19 @@ describe "Sequel::Plugins::JsonSerializer" do
116
116
  JSON.parse(ds.to_json).should == [@album.values.inject({}){|h, (k, v)| h[k.to_s] = v; h}]
117
117
  end
118
118
 
119
+ it "should have dataset to_json method respect :array option for the array to use" do
120
+ a = Album.load(:id=>1, :name=>'RF', :artist_id=>3)
121
+ JSON.parse(Album.to_json(:array=>[a])).should == [a]
122
+
123
+ a.associations[:artist] = artist = Artist.load(:id=>3, :name=>'YJM')
124
+ JSON.parse(Album.to_json(:array=>[a], :include=>:artist)).first.artist.should == artist
125
+
126
+ artist.associations[:albums] = [a]
127
+ x = JSON.parse(Artist.to_json(:array=>[artist], :include=>:albums))
128
+ x.should == [artist]
129
+ x.first.albums.should == [a]
130
+ end
131
+
119
132
  it "should propagate class default options to instance to_json output" do
120
133
  class ::Album2 < Sequel::Model
121
134
  attr_accessor :blah
@@ -320,23 +320,30 @@ describe "Sequel::IntegerMigrator" do
320
320
  proc{Sequel::IntegerMigrator.apply(@db, "spec/files/timestamped_migrations")}.should raise_error(Sequel::Migrator::Error)
321
321
  end
322
322
 
323
- specify "should use transactions by default" do
324
- Sequel::Migrator.apply(@db, "spec/files/transaction_migrations")
323
+ specify "should not use transactions by default" do
324
+ Sequel::Migrator.apply(@db, "spec/files/transaction_unspecified_migrations")
325
+ @db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2"]
326
+ end
327
+
328
+ specify "should use transactions by default if the database supports transactional ddl" do
329
+ @db.meta_def(:supports_transactional_ddl?){true}
330
+ Sequel::Migrator.apply(@db, "spec/files/transaction_unspecified_migrations")
325
331
  @db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2", "COMMIT"]
326
332
  end
327
333
 
328
- specify "should not use transactions for migrations that disable it" do
329
- Sequel::Migrator.apply(@db, "spec/files/transactionless_migrations")
330
- @db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2"]
334
+ specify "should respect transaction use on a per migration basis" do
335
+ @db.meta_def(:supports_transactional_ddl?){true}
336
+ Sequel::Migrator.apply(@db, "spec/files/transaction_specified_migrations")
337
+ @db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "COMMIT", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2"]
331
338
  end
332
339
 
333
340
  specify "should force transactions if enabled in the migrator" do
334
- Sequel::Migrator.run(@db, "spec/files/transactionless_migrations", :use_transactions=>true)
341
+ Sequel::Migrator.run(@db, "spec/files/transaction_specified_migrations", :use_transactions=>true)
335
342
  @db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2", "COMMIT"]
336
343
  end
337
344
 
338
345
  specify "should not use transactions if disabled in the migrator" do
339
- Sequel::Migrator.run(@db, "spec/files/transaction_migrations", :use_transactions=>false)
346
+ Sequel::Migrator.run(@db, "spec/files/transaction_unspecified_migrations", :use_transactions=>false)
340
347
  @db.sqls.should == ["CREATE TABLE schema_info (version integer DEFAULT 0 NOT NULL)", "SELECT 1 AS one FROM schema_info LIMIT 1", "INSERT INTO schema_info (version) VALUES (0)", "SELECT version FROM schema_info LIMIT 1", "CREATE TABLE sm11111 (smc1 integer)", "UPDATE schema_info SET version = 1", "CREATE TABLE sm (smc1 integer)", "UPDATE schema_info SET version = 2"]
341
348
  end
342
349
  end
@@ -598,26 +605,32 @@ describe "Sequel::TimestampMigrator" do
598
605
 
599
606
  specify "should use TimestampMigrator if TimestampMigrator.apply is called even for integer migrations directory" do
600
607
  Sequel::TimestampMigrator.apply(@db, "spec/files/integer_migrations")
601
- @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm1111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_sessions.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm2222 (smc2 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_nodes.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm3333 (smc3 integer)", "INSERT INTO schema_migrations (filename) VALUES ('003_3_create_users.rb')", "COMMIT"]
608
+ @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm1111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_sessions.rb')", "CREATE TABLE sm2222 (smc2 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_nodes.rb')", "CREATE TABLE sm3333 (smc3 integer)", "INSERT INTO schema_migrations (filename) VALUES ('003_3_create_users.rb')"]
602
609
  end
603
610
 
604
- specify "should use transactions by default" do
605
- Sequel::TimestampMigrator.apply(@db, "spec/files/transaction_migrations")
611
+ specify "should not use transactions by default" do
612
+ Sequel::TimestampMigrator.apply(@db, "spec/files/transaction_unspecified_migrations")
613
+ @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
614
+ end
615
+
616
+ specify "should use transactions by default if database supports transactional ddl" do
617
+ @db.meta_def(:supports_transactional_ddl?){true}
618
+ Sequel::TimestampMigrator.apply(@db, "spec/files/transaction_unspecified_migrations")
606
619
  @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')", "COMMIT"]
607
620
  end
608
621
 
609
- specify "should not use transactions for migrations that disable it" do
610
- Sequel::TimestampMigrator.apply(@db, "spec/files/transactionless_migrations")
611
- @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
622
+ specify "should support transaction use on a per migration basis" do
623
+ Sequel::TimestampMigrator.apply(@db, "spec/files/transaction_specified_migrations")
624
+ @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
612
625
  end
613
626
 
614
627
  specify "should force transactions if enabled by the migrator" do
615
- Sequel::TimestampMigrator.run(@db, "spec/files/transactionless_migrations", :use_transactions=>true)
628
+ Sequel::TimestampMigrator.run(@db, "spec/files/transaction_specified_migrations", :use_transactions=>true)
616
629
  @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')", "COMMIT"]
617
630
  end
618
631
 
619
632
  specify "should not use transactions if disabled in the migrator" do
620
- Sequel::TimestampMigrator.run(@db, "spec/files/transaction_migrations", :use_transactions=>false)
633
+ Sequel::TimestampMigrator.run(@db, "spec/files/transaction_unspecified_migrations", :use_transactions=>false)
621
634
  @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
622
635
  end
623
636
  end
@@ -35,14 +35,12 @@ describe "Sequel named_timezones extension" do
35
35
  Sequel.database_timezone.should == @tz_out
36
36
  end
37
37
 
38
- unless RUBY_VERSION == '1.8.6' && RUBY_PLATFORM =~ /win/
39
- it "should convert datetimes going into the database to named database_timezone" do
40
- ds = @db[:a]
41
- def ds.supports_timestamp_timezones?; true; end
42
- def ds.supports_timestamp_usecs?; false; end
43
- ds.insert([@dt, DateTime.civil(2009,6,1,3,20,30,-7/24.0), DateTime.civil(2009,6,1,6,20,30,-1/6.0)])
44
- @db.sqls.should == ["INSERT INTO a VALUES ('2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400')"]
45
- end
38
+ it "should convert datetimes going into the database to named database_timezone" do
39
+ ds = @db[:a]
40
+ def ds.supports_timestamp_timezones?; true; end
41
+ def ds.supports_timestamp_usecs?; false; end
42
+ ds.insert([@dt, DateTime.civil(2009,6,1,3,20,30,-7/24.0), DateTime.civil(2009,6,1,6,20,30,-1/6.0)])
43
+ @db.sqls.should == ["INSERT INTO a VALUES ('2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400')"]
46
44
  end
47
45
 
48
46
  it "should convert datetimes coming out of the database from database_timezone to application_timezone" do
@@ -3,8 +3,9 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
3
3
  describe "pg_auto_parameterize extension" do
4
4
  before do
5
5
  @db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
6
- @db.extend Sequel::Postgres::AutoParameterize::DatabaseMethods
7
6
  @db.synchronize{|c| def c.escape_bytea(v) v*2 end}
7
+ @db.extend_datasets{def use_cursor(*) clone end}
8
+ @db.extend Sequel::Postgres::AutoParameterize::DatabaseMethods
8
9
  end
9
10
 
10
11
  it "should automatically parameterize queries strings, blobs, numerics, dates, and times" do
@@ -44,10 +45,6 @@ describe "pg_auto_parameterize extension" do
44
45
 
45
46
  @db[:table].insert(:a=>1).should == 1
46
47
  @db.sqls.should == ['INSERT INTO table (a) VALUES ($1::int4) RETURNING id -- args: [1]']
47
-
48
- @db.server_version = 80000
49
- @db[:table].insert(:a=>1).should == 1
50
- @db.sqls.should == ['INSERT INTO table (a) VALUES ($1::int4) -- args: [1]']
51
48
  end
52
49
 
53
50
  it "should not automatically paramiterize if no_auto_parameterize is used" do
@@ -61,4 +58,8 @@ describe "pg_auto_parameterize extension" do
61
58
  it "should show args with string when inspecting SQL " do
62
59
  @db[:table].filter(:a=>1).sql.inspect.should == '"SELECT * FROM table WHERE (a = $1::int4); [1]"'
63
60
  end
61
+
62
+ it "should not auto parameterize when using cursors" do
63
+ @db[:table].filter(:a=>1).use_cursor.opts[:no_auto_parameterize].should be_true
64
+ end
64
65
  end
@@ -508,7 +508,7 @@ END_MIG
508
508
  ["double precision", "timestamp with time zone", "timestamp without time zone",
509
509
  "time with time zone", "time without time zone", "character varying(20)"] +
510
510
  %w"nvarchar ntext smalldatetime smallmoney binary varbinary nchar" +
511
- ["timestamp(6) without time zone", "timestamp(6) with time zone", "int(12) unsigned", 'bigint unsigned', 'tinyint(3) unsigned']
511
+ ["timestamp(6) without time zone", "timestamp(6) with time zone", "int(12) unsigned", 'bigint unsigned', 'tinyint(3) unsigned', 'identity', 'int identity']
512
512
  @d.meta_def(:schema) do |t, *o|
513
513
  i = 0
514
514
  types.map{|x| [:"c#{i+=1}", {:db_type=>x, :allow_null=>true}]}
@@ -581,6 +581,8 @@ create_table(:x) do
581
581
  Integer :c64
582
582
  Bignum :c65
583
583
  Integer :c66
584
+ Integer :c67
585
+ Integer :c68
584
586
  end
585
587
  END_MIG
586
588
  end
@@ -42,6 +42,11 @@ describe Sequel::Model, "#sti_key" do
42
42
  StiTest.all.collect{|x| x.class}.should == [StiTest, StiTestSub1, StiTestSub2]
43
43
  end
44
44
 
45
+ it "should return rows with the correct class based on the polymorphic_key value when retreiving by primary key" do
46
+ @ds._fetch = [{:kind=>'StiTestSub1'}]
47
+ StiTest[1].class.should == StiTestSub1
48
+ end
49
+
45
50
  it "should return rows with the correct class for subclasses based on the polymorphic_key value" do
46
51
  class ::StiTestSub1Sub < StiTestSub1; end
47
52
  StiTestSub1.dataset._fetch = [{:kind=>'StiTestSub1'}, {:kind=>'StiTestSub1Sub'}]
@@ -157,6 +157,19 @@ describe "Sequel::Plugins::XmlSerializer" do
157
157
  Album.array_from_xml(Album.dataset.to_xml(:only=>:name)).should == [Album.load(:name=>@album.name)]
158
158
  end
159
159
 
160
+ it "should have to_xml dataset method respect an :array option" do
161
+ a = Album.load(:id=>1, :name=>'RF', :artist_id=>3)
162
+ Album.array_from_xml(Album.to_xml(:array=>[a])).should == [a]
163
+
164
+ a.associations[:artist] = artist = Artist.load(:id=>3, :name=>'YJM')
165
+ Album.array_from_xml(Album.to_xml(:array=>[a], :include=>:artist)).first.artist.should == artist
166
+
167
+ artist.associations[:albums] = [a]
168
+ x = Artist.array_from_xml(Artist.to_xml(:array=>[artist], :include=>:albums))
169
+ x.should == [artist]
170
+ x.first.albums.should == [a]
171
+ end
172
+
160
173
  it "should raise an error if the dataset does not have a row_proc" do
161
174
  proc{Album.dataset.naked.to_xml}.should raise_error(Sequel::Error)
162
175
  end
@@ -1,4 +1,4 @@
1
1
  Sequel.migration do
2
- no_transaction
2
+ transaction
3
3
  change{create_table(:sm11111){Integer :smc1}}
4
4
  end
@@ -608,7 +608,7 @@ describe "Sequel::Model Simple Associations" do
608
608
  @els = {:eager_limit_strategy=>:correlated_subquery}
609
609
  end
610
610
  it_should_behave_like "eager limit strategies"
611
- end unless Sequel.guarded?(:mysql, :db2, :oracle)
611
+ end unless Sequel.guarded?(:mysql, :db2, :oracle, :h2)
612
612
 
613
613
  specify "should handle many_to_one associations with same name as :key" do
614
614
  Album.def_column_alias(:artist_id_id, :artist_id)
@@ -693,12 +693,10 @@ describe "Sequel::Model Simple Associations" do
693
693
  @album.artist(proc{|ds| ds.exclude(:id=>@artist.id)}).should == nil
694
694
  @album.artist(proc{|ds| ds.filter(:id=>@artist.id)}).should == @artist
695
695
 
696
- if RUBY_VERSION >= '1.8.7'
697
- @artist.albums{|ds| ds.exclude(:id=>@album.id)}.should == []
698
- @artist.albums{|ds| ds.filter(:id=>@album.id)}.should == [@album]
699
- @album.artist{|ds| ds.exclude(:id=>@artist.id)}.should == nil
700
- @album.artist{|ds| ds.filter(:id=>@artist.id)}.should == @artist
701
- end
696
+ @artist.albums{|ds| ds.exclude(:id=>@album.id)}.should == []
697
+ @artist.albums{|ds| ds.filter(:id=>@album.id)}.should == [@album]
698
+ @album.artist{|ds| ds.exclude(:id=>@artist.id)}.should == nil
699
+ @album.artist{|ds| ds.filter(:id=>@artist.id)}.should == @artist
702
700
  end
703
701
 
704
702
  specify "should handle dynamic callbacks for eager loading via eager and eager_graph" do
@@ -291,15 +291,26 @@ end
291
291
 
292
292
  describe Sequel::Database do
293
293
  specify "should correctly escape strings" do
294
- INTEGRATION_DB.get("\\dingo".as(:a)) == "\\dingo"
295
- end
296
-
297
- specify "should correctly escape strings with quotes" do
298
- INTEGRATION_DB.get("\\'dingo".as(:a)) == "\\'dingo"
294
+ ["\\\n",
295
+ "\\\\\n",
296
+ "\\\r\n",
297
+ "\\\\\r\n",
298
+ "\\\\\n\n",
299
+ "\\\\\r\n\r\n",
300
+ "\\dingo",
301
+ "\\'dingo",
302
+ "\\\\''dingo",
303
+ ].each do |str|
304
+ INTEGRATION_DB.get(str.as(:a)).should == str
305
+ str = "1#{str}1"
306
+ INTEGRATION_DB.get(str.as(:a)).should == str
307
+ str = "#{str}#{str}"
308
+ INTEGRATION_DB.get(str.as(:a)).should == str
309
+ end
299
310
  end
300
311
 
301
- specify "should properly escape binary data" do
302
- INTEGRATION_DB.get("\1\2\3".to_sequel_blob.as(:a)) == "\1\2\3"
312
+ cspecify "should properly escape binary data", [:odbc], [:jdbc, :hsqldb], [:swift], :oracle do
313
+ INTEGRATION_DB.get("\1\2\3".to_sequel_blob.cast(File).as(:a)).should == "\1\2\3"
303
314
  end
304
315
 
305
316
  specify "should have a working table_exists?" do
@@ -1115,6 +1126,13 @@ describe "Sequel::Dataset DSL support" do
1115
1126
  @ds.get{a.sql_number ^ b ^ 1}.to_i.should == 7
1116
1127
  end
1117
1128
 
1129
+ specify "should work with the modulus operator" do
1130
+ @ds.insert(3, 5)
1131
+ @ds.get{a.sql_number % 4}.to_i.should == 3
1132
+ @ds.get{b.sql_number % 4}.to_i.should == 1
1133
+ @ds.get{a.sql_number % 4 % 2}.to_i.should == 1
1134
+ end
1135
+
1118
1136
  specify "should work with inequality operators" do
1119
1137
  @ds.insert(10, 11)
1120
1138
  @ds.insert(11, 11)
@@ -914,7 +914,7 @@ if INTEGRATION_DB.dataset.supports_cte? and !Sequel.guarded?(:db2)
914
914
  nodes[0].associations.fetch(:parent, 1).should == nil
915
915
  nodes[1].associations[:parent].should == @aa
916
916
  nodes[1].associations[:parent].associations[:parent].should == @a
917
- nodes[1].associations[:parent].associations[:parent].associations.fetch(:parent, 1) == nil
917
+ nodes[1].associations[:parent].associations[:parent].associations.fetch(:parent, 1).should == nil
918
918
  nodes[2].associations[:parent].should == @aaaa
919
919
  nodes[2].associations[:parent].associations[:parent].should == @aaa
920
920
  nodes[2].associations[:parent].associations[:parent].associations[:parent].should == @aa
@@ -239,7 +239,7 @@ describe "Database schema modifiers" do
239
239
  @ds = @db[:items]
240
240
  end
241
241
  after do
242
- @db.drop_table?(:items)
242
+ @db.drop_table?(:items, :items2)
243
243
  end
244
244
 
245
245
  specify "should create tables correctly" do
@@ -250,6 +250,21 @@ describe "Database schema modifiers" do
250
250
  @ds.columns!.should == [:number]
251
251
  end
252
252
 
253
+ specify "should create tables from select statements correctly" do
254
+ @db.create_table!(:items){Integer :number}
255
+ @ds.insert([10])
256
+ @db.create_table(:items2, :as=>@db[:items])
257
+ @db.schema(:items2, :reload=>true).map{|x| x.first}.should == [:number]
258
+ @db[:items2].columns.should == [:number]
259
+ @db[:items2].all.should == [{:number=>10}]
260
+ end
261
+
262
+ specify "should handle create table in a rolled back transaction" do
263
+ @db.drop_table?(:items)
264
+ @db.transaction(:rollback=>:always){@db.create_table(:items){Integer :number}}
265
+ @db.table_exists?(:items).should be_false
266
+ end if INTEGRATION_DB.supports_transactional_ddl?
267
+
253
268
  describe "join tables" do
254
269
  after do
255
270
  @db.drop_join_table(:cat_id=>:cats, :dog_id=>:dogs) if @db.table_exists?(:cats_dogs)
@@ -382,7 +382,7 @@ describe Sequel::Model, "many_to_one" do
382
382
  MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.id = 234) AND (name > 'M')) LIMIT 1"]
383
383
  end
384
384
 
385
- it "should use a block given to the association method as a callback on ruby 1.8.7+" do
385
+ it "should use a block given to the association method as a callback" do
386
386
  @c2.many_to_one :parent, :class => @c2
387
387
 
388
388
  d = @c2.create(:id => 1)
@@ -391,7 +391,7 @@ describe Sequel::Model, "many_to_one" do
391
391
  d.associations[:parent] = 42
392
392
  d.parent{|ds| ds.filter{name > 'M'}}.should_not == 42
393
393
  MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((nodes.id = 234) AND (name > 'M')) LIMIT 1"]
394
- end if RUBY_VERSION >= '1.8.7'
394
+ end
395
395
 
396
396
  it "should have the setter add to the reciprocal one_to_many cached association list if it exists" do
397
397
  @c2.many_to_one :parent, :class => @c2
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.34.0
4
+ version: 3.35.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-02 00:00:00.000000000 Z
12
+ date: 2012-05-01 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: The Database Toolkit for Ruby
15
15
  email: code@jeremyevans.net
@@ -40,6 +40,7 @@ extra_rdoc_files:
40
40
  - doc/testing.rdoc
41
41
  - doc/schema_modification.rdoc
42
42
  - doc/transactions.rdoc
43
+ - doc/thread_safety.rdoc
43
44
  - doc/release_notes/1.0.txt
44
45
  - doc/release_notes/1.1.txt
45
46
  - doc/release_notes/1.3.txt
@@ -93,6 +94,7 @@ extra_rdoc_files:
93
94
  - doc/release_notes/3.32.0.txt
94
95
  - doc/release_notes/3.33.0.txt
95
96
  - doc/release_notes/3.34.0.txt
97
+ - doc/release_notes/3.35.0.txt
96
98
  files:
97
99
  - MIT-LICENSE
98
100
  - CHANGELOG
@@ -164,6 +166,7 @@ files:
164
166
  - doc/release_notes/3.32.0.txt
165
167
  - doc/release_notes/3.33.0.txt
166
168
  - doc/release_notes/3.34.0.txt
169
+ - doc/release_notes/3.35.0.txt
167
170
  - doc/sharding.rdoc
168
171
  - doc/sql.rdoc
169
172
  - doc/validations.rdoc
@@ -172,6 +175,7 @@ files:
172
175
  - doc/testing.rdoc
173
176
  - doc/schema_modification.rdoc
174
177
  - doc/transactions.rdoc
178
+ - doc/thread_safety.rdoc
175
179
  - spec/adapters/firebird_spec.rb
176
180
  - spec/adapters/informix_spec.rb
177
181
  - spec/adapters/mssql_spec.rb
@@ -185,9 +189,9 @@ files:
185
189
  - spec/core/dataset_spec.rb
186
190
  - spec/core/database_spec.rb
187
191
  - spec/core/expression_filters_spec.rb
192
+ - spec/core/schema_spec.rb
188
193
  - spec/core/object_graph_spec.rb
189
194
  - spec/core/schema_generator_spec.rb
190
- - spec/core/schema_spec.rb
191
195
  - spec/core/spec_helper.rb
192
196
  - spec/core/version_spec.rb
193
197
  - spec/core/mock_adapter_spec.rb
@@ -264,6 +268,7 @@ files:
264
268
  - spec/extensions/select_remove_spec.rb
265
269
  - spec/extensions/static_cache_spec.rb
266
270
  - spec/extensions/query_literals_spec.rb
271
+ - spec/extensions/dirty_spec.rb
267
272
  - spec/extensions/columns_introspection_spec.rb
268
273
  - spec/integration/associations_test.rb
269
274
  - spec/integration/database_test.rb
@@ -333,10 +338,10 @@ files:
333
338
  - spec/files/reversible_migrations/003_reversible.rb
334
339
  - spec/files/reversible_migrations/004_reversible.rb
335
340
  - spec/files/reversible_migrations/005_reversible.rb
336
- - spec/files/transaction_migrations/001_create_alt_basic.rb
337
- - spec/files/transaction_migrations/002_create_basic.rb
338
- - spec/files/transactionless_migrations/001_create_alt_basic.rb
339
- - spec/files/transactionless_migrations/002_create_basic.rb
341
+ - spec/files/transaction_specified_migrations/001_create_alt_basic.rb
342
+ - spec/files/transaction_specified_migrations/002_create_basic.rb
343
+ - spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb
344
+ - spec/files/transaction_unspecified_migrations/002_create_basic.rb
340
345
  - lib/sequel.rb
341
346
  - lib/sequel/adapters/ado.rb
342
347
  - lib/sequel/adapters/ado/mssql.rb
@@ -368,7 +373,6 @@ files:
368
373
  - lib/sequel/adapters/mysql.rb
369
374
  - lib/sequel/adapters/odbc.rb
370
375
  - lib/sequel/adapters/odbc/mssql.rb
371
- - lib/sequel/adapters/odbc/db2.rb
372
376
  - lib/sequel/adapters/openbase.rb
373
377
  - lib/sequel/adapters/oracle.rb
374
378
  - lib/sequel/adapters/postgres.rb
@@ -503,6 +507,7 @@ files:
503
507
  - lib/sequel/plugins/prepared_statements_associations.rb
504
508
  - lib/sequel/plugins/dataset_associations.rb
505
509
  - lib/sequel/plugins/many_to_one_pk_lookup.rb
510
+ - lib/sequel/plugins/dirty.rb
506
511
  - lib/sequel/timezones.rb
507
512
  - lib/sequel/version.rb
508
513
  - lib/sequel/ast_transformer.rb
@@ -527,7 +532,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
527
532
  requirements:
528
533
  - - ! '>='
529
534
  - !ruby/object:Gem::Version
530
- version: 1.8.4
535
+ version: 1.8.7
531
536
  required_rubygems_version: !ruby/object:Gem::Requirement
532
537
  none: false
533
538
  requirements:
@@ -1,17 +0,0 @@
1
- Sequel.require 'adapters/shared/db2'
2
-
3
- module Sequel
4
- module ODBC
5
- # Database and Dataset instance methods for DB2 specific
6
- # support via ODBC.
7
- module DB2
8
- module DatabaseMethods
9
- include ::Sequel::DB2::DatabaseMethods
10
- end
11
-
12
- class Dataset < ODBC::Dataset
13
- include ::Sequel::DB2::DatasetMethods
14
- end
15
- end
16
- end
17
- end