sequel 5.82.0 → 5.84.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/bin/sequel +9 -17
  3. data/lib/sequel/adapters/jdbc/derby.rb +1 -1
  4. data/lib/sequel/adapters/shared/db2.rb +1 -1
  5. data/lib/sequel/adapters/shared/mssql.rb +14 -2
  6. data/lib/sequel/adapters/shared/postgres.rb +42 -4
  7. data/lib/sequel/adapters/shared/sqlite.rb +3 -1
  8. data/lib/sequel/database/connecting.rb +1 -4
  9. data/lib/sequel/database/misc.rb +27 -7
  10. data/lib/sequel/database/schema_methods.rb +17 -1
  11. data/lib/sequel/dataset/sql.rb +13 -0
  12. data/lib/sequel/extensions/pg_json_ops.rb +328 -1
  13. data/lib/sequel/extensions/stdio_logger.rb +48 -0
  14. data/lib/sequel/extensions/string_agg.rb +15 -2
  15. data/lib/sequel/plugins/defaults_setter.rb +16 -4
  16. data/lib/sequel/plugins/optimistic_locking.rb +2 -0
  17. data/lib/sequel/sql.rb +8 -5
  18. data/lib/sequel/version.rb +1 -1
  19. metadata +4 -235
  20. data/CHANGELOG +0 -1377
  21. data/README.rdoc +0 -936
  22. data/doc/advanced_associations.rdoc +0 -884
  23. data/doc/association_basics.rdoc +0 -1859
  24. data/doc/bin_sequel.rdoc +0 -146
  25. data/doc/cheat_sheet.rdoc +0 -255
  26. data/doc/code_order.rdoc +0 -104
  27. data/doc/core_extensions.rdoc +0 -405
  28. data/doc/dataset_basics.rdoc +0 -96
  29. data/doc/dataset_filtering.rdoc +0 -222
  30. data/doc/extensions.rdoc +0 -77
  31. data/doc/fork_safety.rdoc +0 -84
  32. data/doc/mass_assignment.rdoc +0 -98
  33. data/doc/migration.rdoc +0 -660
  34. data/doc/model_dataset_method_design.rdoc +0 -129
  35. data/doc/model_hooks.rdoc +0 -254
  36. data/doc/model_plugins.rdoc +0 -270
  37. data/doc/mssql_stored_procedures.rdoc +0 -43
  38. data/doc/object_model.rdoc +0 -563
  39. data/doc/opening_databases.rdoc +0 -439
  40. data/doc/postgresql.rdoc +0 -611
  41. data/doc/prepared_statements.rdoc +0 -144
  42. data/doc/querying.rdoc +0 -1070
  43. data/doc/reflection.rdoc +0 -120
  44. data/doc/release_notes/5.0.0.txt +0 -159
  45. data/doc/release_notes/5.1.0.txt +0 -31
  46. data/doc/release_notes/5.10.0.txt +0 -84
  47. data/doc/release_notes/5.11.0.txt +0 -83
  48. data/doc/release_notes/5.12.0.txt +0 -141
  49. data/doc/release_notes/5.13.0.txt +0 -27
  50. data/doc/release_notes/5.14.0.txt +0 -63
  51. data/doc/release_notes/5.15.0.txt +0 -39
  52. data/doc/release_notes/5.16.0.txt +0 -110
  53. data/doc/release_notes/5.17.0.txt +0 -31
  54. data/doc/release_notes/5.18.0.txt +0 -69
  55. data/doc/release_notes/5.19.0.txt +0 -28
  56. data/doc/release_notes/5.2.0.txt +0 -33
  57. data/doc/release_notes/5.20.0.txt +0 -89
  58. data/doc/release_notes/5.21.0.txt +0 -87
  59. data/doc/release_notes/5.22.0.txt +0 -48
  60. data/doc/release_notes/5.23.0.txt +0 -56
  61. data/doc/release_notes/5.24.0.txt +0 -56
  62. data/doc/release_notes/5.25.0.txt +0 -32
  63. data/doc/release_notes/5.26.0.txt +0 -35
  64. data/doc/release_notes/5.27.0.txt +0 -21
  65. data/doc/release_notes/5.28.0.txt +0 -16
  66. data/doc/release_notes/5.29.0.txt +0 -22
  67. data/doc/release_notes/5.3.0.txt +0 -121
  68. data/doc/release_notes/5.30.0.txt +0 -20
  69. data/doc/release_notes/5.31.0.txt +0 -148
  70. data/doc/release_notes/5.32.0.txt +0 -46
  71. data/doc/release_notes/5.33.0.txt +0 -24
  72. data/doc/release_notes/5.34.0.txt +0 -40
  73. data/doc/release_notes/5.35.0.txt +0 -56
  74. data/doc/release_notes/5.36.0.txt +0 -60
  75. data/doc/release_notes/5.37.0.txt +0 -30
  76. data/doc/release_notes/5.38.0.txt +0 -28
  77. data/doc/release_notes/5.39.0.txt +0 -19
  78. data/doc/release_notes/5.4.0.txt +0 -80
  79. data/doc/release_notes/5.40.0.txt +0 -40
  80. data/doc/release_notes/5.41.0.txt +0 -25
  81. data/doc/release_notes/5.42.0.txt +0 -136
  82. data/doc/release_notes/5.43.0.txt +0 -98
  83. data/doc/release_notes/5.44.0.txt +0 -32
  84. data/doc/release_notes/5.45.0.txt +0 -34
  85. data/doc/release_notes/5.46.0.txt +0 -87
  86. data/doc/release_notes/5.47.0.txt +0 -59
  87. data/doc/release_notes/5.48.0.txt +0 -14
  88. data/doc/release_notes/5.49.0.txt +0 -59
  89. data/doc/release_notes/5.5.0.txt +0 -61
  90. data/doc/release_notes/5.50.0.txt +0 -78
  91. data/doc/release_notes/5.51.0.txt +0 -47
  92. data/doc/release_notes/5.52.0.txt +0 -87
  93. data/doc/release_notes/5.53.0.txt +0 -23
  94. data/doc/release_notes/5.54.0.txt +0 -27
  95. data/doc/release_notes/5.55.0.txt +0 -21
  96. data/doc/release_notes/5.56.0.txt +0 -51
  97. data/doc/release_notes/5.57.0.txt +0 -23
  98. data/doc/release_notes/5.58.0.txt +0 -31
  99. data/doc/release_notes/5.59.0.txt +0 -73
  100. data/doc/release_notes/5.6.0.txt +0 -31
  101. data/doc/release_notes/5.60.0.txt +0 -22
  102. data/doc/release_notes/5.61.0.txt +0 -43
  103. data/doc/release_notes/5.62.0.txt +0 -132
  104. data/doc/release_notes/5.63.0.txt +0 -33
  105. data/doc/release_notes/5.64.0.txt +0 -50
  106. data/doc/release_notes/5.65.0.txt +0 -21
  107. data/doc/release_notes/5.66.0.txt +0 -24
  108. data/doc/release_notes/5.67.0.txt +0 -32
  109. data/doc/release_notes/5.68.0.txt +0 -61
  110. data/doc/release_notes/5.69.0.txt +0 -26
  111. data/doc/release_notes/5.7.0.txt +0 -108
  112. data/doc/release_notes/5.70.0.txt +0 -35
  113. data/doc/release_notes/5.71.0.txt +0 -21
  114. data/doc/release_notes/5.72.0.txt +0 -33
  115. data/doc/release_notes/5.73.0.txt +0 -66
  116. data/doc/release_notes/5.74.0.txt +0 -45
  117. data/doc/release_notes/5.75.0.txt +0 -35
  118. data/doc/release_notes/5.76.0.txt +0 -86
  119. data/doc/release_notes/5.77.0.txt +0 -63
  120. data/doc/release_notes/5.78.0.txt +0 -67
  121. data/doc/release_notes/5.79.0.txt +0 -28
  122. data/doc/release_notes/5.8.0.txt +0 -170
  123. data/doc/release_notes/5.80.0.txt +0 -40
  124. data/doc/release_notes/5.81.0.txt +0 -31
  125. data/doc/release_notes/5.82.0.txt +0 -61
  126. data/doc/release_notes/5.9.0.txt +0 -99
  127. data/doc/schema_modification.rdoc +0 -679
  128. data/doc/security.rdoc +0 -443
  129. data/doc/sharding.rdoc +0 -286
  130. data/doc/sql.rdoc +0 -648
  131. data/doc/testing.rdoc +0 -204
  132. data/doc/thread_safety.rdoc +0 -15
  133. data/doc/transactions.rdoc +0 -250
  134. data/doc/validations.rdoc +0 -558
  135. data/doc/virtual_rows.rdoc +0 -265
data/doc/sharding.rdoc DELETED
@@ -1,286 +0,0 @@
1
- = Primary/Replica Configurations and Database Sharding
2
-
3
- Sequel has support for primary/replica configurations (writable primary
4
- database with read only replicas databases), as well as database sharding (where you can
5
- pick a server to use for a given dataset). Support for both
6
- features is database independent, and should work for all database adapters
7
- that ship with Sequel.
8
-
9
- == The :servers Database option
10
-
11
- Sharding and read_only support are both enabled via the :servers database
12
- option. Using the :servers database option makes Sequel use a connection pool
13
- class that supports sharding, and the minimum required to enable sharding
14
- support is to use the empty hash:
15
-
16
- DB=Sequel.connect('postgres://primary_server/database', servers: {})
17
-
18
- In most cases, you are probably not going to want to use an empty hash. Keys in the server hash are
19
- not restricted to type, but the general recommendation is to use a symbol
20
- unless you have special requirements. Values in the server hash should be
21
- either hashes or procs that return hashes. These hashes are merged into
22
- the Database object's default options hash to get the connection options
23
- for the shard, so you don't need to override all options, just the ones
24
- that need to be modified. For example, if you are using the same user,
25
- password, and database name and just the host is changing, you only need
26
- a :host entry in each shard's hash.
27
-
28
- Note that all servers should have the same schema for all
29
- tables you are accessing, unless you really know what you are doing.
30
-
31
- == Primary and Replica Database Configurations
32
-
33
- === Single Primary, Single Replica
34
-
35
- To use a single, read-only replica that handles SELECT queries, the following
36
- is the simplest configuration:
37
-
38
- DB=Sequel.connect('postgres://primary_server/database',
39
- servers: {read_only: {host: 'replica_server'}})
40
-
41
- This will use the replica_server for SELECT queries and primary_server for
42
- other queries. The :read_only key in the :servers hash is special in that
43
- it sets the default database for Dataset methods that use SELECT queries
44
- (which are generally read queries that do not modify the database).
45
-
46
- If you want to ensure your queries are going to a specific database, you
47
- can force this for a given query by using the .server method and passing
48
- the symbol name defined in the connect options. For example:
49
-
50
- # Force the SELECT to run on the primary server
51
- DB[:users].server(:default).all
52
-
53
- # Force the DELETE to run on the read-only replica
54
- DB[:users].server(:read_only).delete
55
-
56
- === Single Primary, Multiple Replicas
57
-
58
- Let's say you have 4 replica servers with names replica_server0,
59
- replica_server1, replica_server2, and replica_server3.
60
-
61
- num_read_only = 4
62
- read_only_host = rand(num_read_only)
63
- read_only_proc = proc do |db|
64
- {host: "replica_server#{(read_only_host+=1) % num_read_only}"}
65
- end
66
- DB=Sequel.connect('postgres://primary_server/database',
67
- servers: {read_only: read_only_proc})
68
-
69
- This will use one of the replica servers for SELECT queries and use the
70
- primary server for other queries. It's also possible to pick a random host
71
- instead of using the round robin approach presented above, but that can result
72
- in less optimal resource usage.
73
-
74
- === Multiple Primary, Multiple Replicas
75
-
76
- This involves the same basic idea as the multiple replicas, single primary, but
77
- it shows that the primary database is named :default. So for 4 primary servers and
78
- 4 replica servers:
79
-
80
- num_read_only = 4
81
- read_only_host = rand(num_read_only)
82
- read_only_proc = proc do |db|
83
- {host: "replica_server#{(read_only_host+=1) % num_read_only}"}
84
- end
85
- num_default = 4
86
- default_host = rand(num_default)
87
- default_proc = proc do |db|
88
- {host: "primary_server#{(default_host+=1) % num_default}"}
89
- end
90
- DB=Sequel.connect('postgres://primary_server/database',
91
- servers: {default: default_proc, read_only: read_only_proc})
92
-
93
- == Sharding
94
-
95
- There is specific support in Sequel for handling primary/replica database
96
- combinations, with the only necessary setup being the database configuration.
97
- However, since sharding is always going to be implementation dependent, Sequel
98
- supplies the basic infrastructure, but you have to tell it which server to use
99
- for each dataset. Let's assume a simple scenario, a distributed rainbow
100
- table for SHA-1 hashes, sharding based on the first hex character (for a total
101
- of 16 shards). First, you need to configure the database:
102
-
103
- servers = {}
104
- (('0'..'9').to_a + ('a'..'f').to_a).each do |hex|
105
- servers[hex.to_sym] = {host: "hash_host_#{hex}"}
106
- end
107
- DB=Sequel.connect('postgres://hash_host/hashes', servers: servers)
108
-
109
- This configures 17 servers, the 16 shard servers (/hash_host_[0-9a-f]/), and 1
110
- default server which will be used if no shard is specified ("hash_host"). If
111
- you want the default server to be one of the shard servers (e.g. hash_host_a),
112
- it's easiest to do:
113
-
114
- DB=Sequel.connect('postgres://hash_host_a/hashes', servers: servers)
115
-
116
- That will still set up a second pool of connections for the default server,
117
- since it considers the default server and shard servers independent. Note that
118
- if you always set the shard on a dataset before using it in queries, it will
119
- not attempt to connect to the default server. Sequel may use the default
120
- server in queries it generates itself, such as to get column names or table
121
- schemas, so you should always have a default server that works.
122
-
123
- To set the shard for a given query, you use the Dataset#server method:
124
-
125
- DB[:hashes].server(:a).where(hash: /31337/)
126
-
127
- That will return all matching rows on the hash_host_a shard that have a hash
128
- column that contains 31337.
129
-
130
- Rainbow tables are generally used to find specific hashes, so to save some
131
- work, you might want to add a method to the dataset that automatically sets
132
- the shard to use. This is fairly easy using a Sequel::Model:
133
-
134
- class Rainbow < Sequel::Model(:hashes)
135
- dataset_module do
136
- def plaintext_for_hash(hash)
137
- raise(ArgumentError, 'Invalid SHA-1 Hash') unless /\A[0-9a-f]{40}\z/.match(hash)
138
- server(hash[0...1].to_sym).where(hash: hash).get(:plaintext)
139
- end
140
- end
141
- end
142
-
143
- Rainbow.plaintext_for_hash("e580726d31f6e1ad216ffd87279e536d1f74e606")
144
-
145
- === :servers_hash Option
146
-
147
- The connection pool can be further controlled to change how it handles attempts
148
- to access shards that haven't been configured. The default is
149
- to assume the :default shard. However, you can specify a
150
- different shard using the :servers_hash option when connecting
151
- to the database:
152
-
153
- DB = Sequel.connect('postgres://...', servers_hash: Hash.new(:some_shard))
154
-
155
- You can also use this feature to raise an exception if an
156
- unconfigured shard is used:
157
-
158
- DB = Sequel.connect('postgres://...', servers_hash: Hash.new{raise 'foo'})
159
-
160
- If you specify a :servers_hash option to raise an exception for non configured
161
- shards you should also explicitly specify a :read_only entry in your :servers option
162
- for the case where a shard is not specified. In most cases it is sufficient
163
- to make the :read_only entry the same as the :default shard:
164
-
165
- servers = {read_only: {}}
166
- (('0'..'9').to_a + ('a'..'f').to_a).each do |hex|
167
- servers[hex.to_sym] = {host: "hash_host_#{hex}"}
168
- end
169
- DB=Sequel.connect('postgres://hash_host/hashes', servers: servers,
170
- servers_hash: Hash.new{raise "Invalid Server"})
171
-
172
- === Sharding Plugin
173
-
174
- Sequel comes with a sharding plugin that makes it easy to use sharding with model objects.
175
- It makes sure that objects retrieved from a specific shard are always saved back to that
176
- shard, allows you to create objects on specific shards, and even makes sure associations
177
- work well with shards. You just need to remember to set to model to use the plugin:
178
-
179
- class Rainbow < Sequel::Model(:hashes)
180
- plugin :sharding
181
- end
182
-
183
- Rainbow.server(:a).first(id: 1).update(plaintext: 'VGM')
184
-
185
- If all of your models are sharded, you can set all models to use the plugin via:
186
-
187
- Sequel::Model.plugin :sharding
188
-
189
- === server_block Extension
190
-
191
- By default, you must specify the server/shard you want to use for every dataset/action,
192
- or Sequel will use the default shard. If you have a group of queries that should use the
193
- same shard, it can get a bit redundant to specify the same shard for all of them.
194
-
195
- The server_block extension adds a Database#with_server method that scopes all database
196
- access inside the block to the given shard by default:
197
-
198
- DB.extension :server_block
199
- DB.with_server(:a) do
200
- # this SELECT query uses the "a" shard
201
- if r = Rainbow.first(hash: /31337/)
202
- r.count += 1
203
- # this UPDATE query also uses the "a" shard
204
- r.save
205
- end
206
- end
207
-
208
- The server_block extension doesn't currently integrate with the sharding plugin, as it
209
- ties into the Dataset#server method. This shouldn't present a problem in practice as
210
- long as you just access the models inside the with_server block, since they will use
211
- the shard set by with_server by default. However, you will probably have issues if
212
- you retrieve the models inside the block and save them outside of the block. If you
213
- need to do that, call the server method explicitly on the dataset used to retrieve the
214
- model objects.
215
-
216
- The with_server method also supports a second argument for the default read_only server
217
- to use, which can be useful if you are mixing sharding and primary/replica servers:
218
-
219
- DB.extension :server_block
220
- DB.with_server(:a, :a_read_only) do
221
- # this SELECT query uses the "a_read_only" shard
222
- if r = Rainbow.first(hash: /31337/)
223
- r.count += 1
224
- # this UPDATE query also uses the "a" shard
225
- r.save
226
- end
227
- end
228
-
229
- === arbitrary_servers Extension
230
-
231
- By default, Sequel's sharding support is designed to work with predefined shards. It ships
232
- with Database#add_servers and Database#remove_servers methods to modify these predefined
233
- shards on the fly, but it is a bit cumbersome to work with truly arbitrary servers
234
- (requiring you to call add_servers before use, then remove_servers after use).
235
-
236
- The arbitrary_servers extension allows you to pass a server/shard options hash as the
237
- server to use, and those options will be merged directly into the database's default options:
238
-
239
- DB.extension :arbitrary_servers
240
- DB[:rainbows].server(host: 'hash_host_a').all
241
- # or
242
- DB[:rainbows].server(host: 'hash_host_b', database: 'backup').all
243
-
244
- arbitrary_servers is designed to work well in conjunction with the server_block extension:
245
-
246
- DB.with_server(host: 'hash_host_b', database: 'backup') do
247
- DB.synchronize do
248
- # All queries here default to the backup database on hash_host_b
249
- end
250
- end
251
-
252
- If you are using arbitrary_servers with server_block, you may want to
253
- define the following method (or something similar) so that you don't
254
- need to call synchronize separately:
255
-
256
- def DB.with_server(*)
257
- super{synchronize{yield}}
258
- end
259
-
260
- The reason for the synchronize method is that it checks out a connection
261
- and makes the same connection available for the duration of the block.
262
- If you don't do that, Sequel will probably disconnect from the database
263
- and reconnect to the database on each request, since connections to
264
- arbitrary servers are not cached.
265
-
266
- Note that this extension only works with the sharded threaded connection
267
- pool. If you are using the sharded single connection pool, you need
268
- to switch to the sharded threaded connection pool before using this
269
- extension. If you are passing the :single_threaded option to
270
- the Database, just remove that option. If you are setting:
271
-
272
- Sequel.single_threaded = true
273
-
274
- just remove or comment out that code.
275
-
276
- == JDBC
277
-
278
- If you are using the jdbc adapter, note that it does not handle separate
279
- options such as +:host+, +:user+, and +:port+. If you would like to use
280
- the +:servers+ option when connecting to a JDBC database, each hash value in
281
- the +servers+ option should contain a +:uri+ key with a JDBC connection string
282
- for that shard as the value. Example:
283
-
284
- DB=Sequel.connect('jdbc:postgresql://primary_server/database',
285
- servers: {read_only: {uri: 'jdbc:postgresql://replica_server/database'}})
286
-