sequel 5.58.0 → 5.78.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +288 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +24 -23
- data/bin/sequel +11 -3
- data/doc/advanced_associations.rdoc +16 -14
- data/doc/association_basics.rdoc +53 -17
- data/doc/cheat_sheet.rdoc +3 -3
- data/doc/mass_assignment.rdoc +1 -1
- data/doc/migration.rdoc +15 -0
- data/doc/model_hooks.rdoc +1 -1
- data/doc/object_model.rdoc +8 -8
- data/doc/opening_databases.rdoc +20 -12
- data/doc/postgresql.rdoc +8 -8
- data/doc/querying.rdoc +1 -1
- data/doc/release_notes/5.59.0.txt +73 -0
- data/doc/release_notes/5.60.0.txt +22 -0
- data/doc/release_notes/5.61.0.txt +43 -0
- data/doc/release_notes/5.62.0.txt +132 -0
- data/doc/release_notes/5.63.0.txt +33 -0
- data/doc/release_notes/5.64.0.txt +50 -0
- data/doc/release_notes/5.65.0.txt +21 -0
- data/doc/release_notes/5.66.0.txt +24 -0
- data/doc/release_notes/5.67.0.txt +32 -0
- data/doc/release_notes/5.68.0.txt +61 -0
- data/doc/release_notes/5.69.0.txt +26 -0
- data/doc/release_notes/5.70.0.txt +35 -0
- data/doc/release_notes/5.71.0.txt +21 -0
- data/doc/release_notes/5.72.0.txt +33 -0
- data/doc/release_notes/5.73.0.txt +66 -0
- data/doc/release_notes/5.74.0.txt +45 -0
- data/doc/release_notes/5.75.0.txt +35 -0
- data/doc/release_notes/5.76.0.txt +86 -0
- data/doc/release_notes/5.77.0.txt +63 -0
- data/doc/release_notes/5.78.0.txt +67 -0
- data/doc/schema_modification.rdoc +3 -3
- data/doc/security.rdoc +9 -9
- data/doc/sharding.rdoc +3 -1
- data/doc/sql.rdoc +14 -14
- data/doc/testing.rdoc +16 -12
- data/doc/transactions.rdoc +6 -6
- data/doc/virtual_rows.rdoc +1 -1
- data/lib/sequel/adapters/ibmdb.rb +1 -1
- data/lib/sequel/adapters/jdbc/h2.rb +3 -0
- data/lib/sequel/adapters/jdbc/hsqldb.rb +2 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +3 -0
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +15 -0
- data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -0
- data/lib/sequel/adapters/jdbc.rb +10 -6
- data/lib/sequel/adapters/mysql.rb +19 -7
- data/lib/sequel/adapters/mysql2.rb +2 -2
- data/lib/sequel/adapters/odbc/mssql.rb +1 -1
- data/lib/sequel/adapters/oracle.rb +1 -0
- data/lib/sequel/adapters/postgres.rb +62 -16
- data/lib/sequel/adapters/shared/access.rb +9 -1
- data/lib/sequel/adapters/shared/db2.rb +12 -0
- data/lib/sequel/adapters/shared/mssql.rb +71 -9
- data/lib/sequel/adapters/shared/mysql.rb +80 -1
- data/lib/sequel/adapters/shared/oracle.rb +17 -7
- data/lib/sequel/adapters/shared/postgres.rb +494 -164
- data/lib/sequel/adapters/shared/sqlanywhere.rb +18 -5
- data/lib/sequel/adapters/shared/sqlite.rb +40 -4
- data/lib/sequel/adapters/sqlite.rb +42 -3
- data/lib/sequel/adapters/trilogy.rb +117 -0
- data/lib/sequel/connection_pool/sharded_threaded.rb +16 -11
- data/lib/sequel/connection_pool/sharded_timed_queue.rb +374 -0
- data/lib/sequel/connection_pool/threaded.rb +14 -8
- data/lib/sequel/connection_pool/timed_queue.rb +270 -0
- data/lib/sequel/connection_pool.rb +57 -31
- data/lib/sequel/database/connecting.rb +25 -1
- data/lib/sequel/database/dataset.rb +16 -6
- data/lib/sequel/database/misc.rb +65 -14
- data/lib/sequel/database/query.rb +72 -1
- data/lib/sequel/database/schema_generator.rb +2 -1
- data/lib/sequel/database/schema_methods.rb +13 -3
- data/lib/sequel/database/transactions.rb +6 -0
- data/lib/sequel/dataset/actions.rb +60 -13
- data/lib/sequel/dataset/deprecated_singleton_class_methods.rb +42 -0
- data/lib/sequel/dataset/features.rb +15 -1
- data/lib/sequel/dataset/misc.rb +12 -2
- data/lib/sequel/dataset/placeholder_literalizer.rb +20 -9
- data/lib/sequel/dataset/query.rb +62 -37
- data/lib/sequel/dataset/sql.rb +58 -36
- data/lib/sequel/dataset.rb +4 -0
- data/lib/sequel/exceptions.rb +5 -0
- data/lib/sequel/extensions/_model_pg_row.rb +0 -12
- data/lib/sequel/extensions/_pretty_table.rb +1 -1
- data/lib/sequel/extensions/any_not_empty.rb +2 -2
- data/lib/sequel/extensions/async_thread_pool.rb +21 -13
- data/lib/sequel/extensions/auto_cast_date_and_time.rb +94 -0
- data/lib/sequel/extensions/auto_literal_strings.rb +1 -1
- data/lib/sequel/extensions/connection_expiration.rb +15 -9
- data/lib/sequel/extensions/connection_validator.rb +16 -11
- data/lib/sequel/extensions/constraint_validations.rb +1 -1
- data/lib/sequel/extensions/date_arithmetic.rb +36 -8
- data/lib/sequel/extensions/duplicate_columns_handler.rb +10 -9
- data/lib/sequel/extensions/index_caching.rb +5 -1
- data/lib/sequel/extensions/is_distinct_from.rb +3 -1
- data/lib/sequel/extensions/looser_typecasting.rb +3 -0
- data/lib/sequel/extensions/migration.rb +65 -15
- data/lib/sequel/extensions/named_timezones.rb +22 -6
- data/lib/sequel/extensions/pg_array.rb +33 -4
- data/lib/sequel/extensions/pg_auto_parameterize.rb +509 -0
- data/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +110 -0
- data/lib/sequel/extensions/pg_enum.rb +1 -2
- data/lib/sequel/extensions/pg_extended_date_support.rb +38 -27
- data/lib/sequel/extensions/pg_extended_integer_support.rb +116 -0
- data/lib/sequel/extensions/pg_hstore.rb +5 -0
- data/lib/sequel/extensions/pg_inet.rb +10 -11
- data/lib/sequel/extensions/pg_interval.rb +10 -11
- data/lib/sequel/extensions/pg_json.rb +10 -10
- data/lib/sequel/extensions/pg_json_ops.rb +52 -0
- data/lib/sequel/extensions/pg_multirange.rb +6 -11
- data/lib/sequel/extensions/pg_range.rb +9 -14
- data/lib/sequel/extensions/pg_row.rb +20 -19
- data/lib/sequel/extensions/pg_timestamptz.rb +27 -3
- data/lib/sequel/extensions/round_timestamps.rb +1 -1
- data/lib/sequel/extensions/schema_caching.rb +1 -1
- data/lib/sequel/extensions/schema_dumper.rb +32 -9
- data/lib/sequel/extensions/server_block.rb +2 -1
- data/lib/sequel/extensions/set_literalizer.rb +58 -0
- data/lib/sequel/extensions/sqlite_json_ops.rb +76 -18
- data/lib/sequel/extensions/symbol_aref.rb +2 -0
- data/lib/sequel/extensions/transaction_connection_validator.rb +78 -0
- data/lib/sequel/model/associations.rb +50 -11
- data/lib/sequel/model/base.rb +45 -21
- data/lib/sequel/model/dataset_module.rb +3 -0
- data/lib/sequel/model/exceptions.rb +15 -3
- data/lib/sequel/plugins/auto_validations.rb +53 -15
- data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/column_encryption.rb +27 -6
- data/lib/sequel/plugins/composition.rb +2 -2
- data/lib/sequel/plugins/concurrent_eager_loading.rb +4 -4
- data/lib/sequel/plugins/constraint_validations.rb +8 -5
- data/lib/sequel/plugins/defaults_setter.rb +16 -0
- data/lib/sequel/plugins/dirty.rb +1 -1
- data/lib/sequel/plugins/finder.rb +4 -2
- data/lib/sequel/plugins/list.rb +8 -3
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -38
- data/lib/sequel/plugins/nested_attributes.rb +4 -4
- data/lib/sequel/plugins/optimistic_locking.rb +9 -42
- data/lib/sequel/plugins/optimistic_locking_base.rb +55 -0
- data/lib/sequel/plugins/paged_operations.rb +181 -0
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +9 -3
- data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +109 -0
- data/lib/sequel/plugins/prepared_statements.rb +2 -1
- data/lib/sequel/plugins/prepared_statements_safe.rb +2 -1
- data/lib/sequel/plugins/primary_key_lookup_check_values.rb +154 -0
- data/lib/sequel/plugins/rcte_tree.rb +7 -4
- data/lib/sequel/plugins/require_valid_schema.rb +67 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +8 -0
- data/lib/sequel/plugins/sql_comments.rb +5 -5
- data/lib/sequel/plugins/static_cache.rb +38 -0
- data/lib/sequel/plugins/static_cache_cache.rb +5 -1
- data/lib/sequel/plugins/tactical_eager_loading.rb +21 -14
- data/lib/sequel/plugins/validate_associated.rb +22 -12
- data/lib/sequel/plugins/validation_helpers.rb +29 -2
- data/lib/sequel/plugins/validation_helpers_generic_type_messages.rb +73 -0
- data/lib/sequel/version.rb +1 -1
- metadata +76 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d821d7a1270874ced864c3a4bc66b519b3b5e3c050d2792e8dfc907a677e36a
|
4
|
+
data.tar.gz: 67390870d998d266a1a07d44e72dc85e357226e7f5dd215ca695ab9037840638
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50b737d3a944ec7d1df62dce2df68b6558e912c0d333d0cdf1d32bccd18ecb5dad8439e73f8c5497b4e627ea8caee34f131dee5a57217a479acfab95287f306d
|
7
|
+
data.tar.gz: 3b9631235606432b44cc57aa624c6509dd14833fdc0e5e900945232c3593904a249dbe3106aef1e4e863cf939517cb1abbd16ca179eec6e5b1de90b815de941f
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,291 @@
|
|
1
|
+
=== 5.78.0 (2024-03-01)
|
2
|
+
|
3
|
+
* Support SQLite 3.45+ jsonb functions in the sqlite_json_ops extension (jeremyevans) (#2133)
|
4
|
+
|
5
|
+
* Support compounds (e.g. UNION) in conjunction with Database#values on PostgreSQL (jeremyevans) (#2137)
|
6
|
+
|
7
|
+
* Support :use_advisory_lock option to Migrator.run to use advisory locks when running migrations (jeremyevans) (#2089)
|
8
|
+
|
9
|
+
* Support Database#with_advisory_lock on PostgreSQL, MySQL, and Microsoft SQL Server (jeremyevans) (#2089)
|
10
|
+
|
11
|
+
=== 5.77.0 (2024-02-01)
|
12
|
+
|
13
|
+
* Support create_table :without_rowid option on SQLite (loranger32) (#2126)
|
14
|
+
|
15
|
+
* Warn by default if trying to eager_graph/association_join an association that uses a block, when the block would be ignored (jeremyevans)
|
16
|
+
|
17
|
+
* Speed up validates_unique in validation_helpers plugin by using empty? instead of count == 0 (numbata) (#2122)
|
18
|
+
|
19
|
+
* Speed up regexp matches in sqlite adapter on Ruby 2.4+ (jeremyevans)
|
20
|
+
|
21
|
+
* Add sqlite adapter :regexp_function_cache option for specifying the cache object to use (paddor, jeremyevans) (#2116)
|
22
|
+
|
23
|
+
* Respect list plugin :top option when inserting the first row into the model's table (johanmagnusson) (#2115)
|
24
|
+
|
25
|
+
* Switch default connection pool to timed_queue on Ruby 3.4+ (jeremyevans)
|
26
|
+
|
27
|
+
* Support on_duplicate_columns={raise,warn} parameter in connection URL when using duplicate_columns_handler extension (jeremyevans)
|
28
|
+
|
29
|
+
* Add transaction_connection_validator extension for retrying transactions on new connection if there is a disconnect error when starting transaction (jeremyevans)
|
30
|
+
|
31
|
+
=== 5.76.0 (2024-01-01)
|
32
|
+
|
33
|
+
* Improve performance and flexibility of regexp matching in sqlite adapter (paddor) (#2108)
|
34
|
+
|
35
|
+
* Support SQL::Identifier for Database#tables :schema option values on PostgreSQL (jeremyevans)
|
36
|
+
|
37
|
+
* Support generating rcte queries using UNION or UNION ALL in the rcte plugin (jonathanfrias) (#2107)
|
38
|
+
|
39
|
+
* Make Database#table_exists? on PostgreSQL handle lock or statement timeout errors as evidence the table exists (jeremyevans) (#2106)
|
40
|
+
|
41
|
+
* Work around DateTime.jd fractional second bug on JRuby in named_timezones extension (jeremyevans)
|
42
|
+
|
43
|
+
* Support fractional times and timestamps on SQLAnywhere (jeremyevans)
|
44
|
+
|
45
|
+
* Make round_timestamps extension use Dataset#sqltime_precision for rounding Sequel::SQLTime values (jeremyevans)
|
46
|
+
|
47
|
+
* Remove special handling of %N modifier in Dataset#default_timestamp_format (jeremyevans)
|
48
|
+
|
49
|
+
* Add Dataset#default_time_format private method, for adapters to override for time (not timestamp) formatting (jeremyevans)
|
50
|
+
|
51
|
+
* Remove Dataset#format_timestamp_offset private method (jeremyevans)
|
52
|
+
|
53
|
+
* Remove special handling of %z modifier in Dataset#default_timestamp_format (jeremyevans)
|
54
|
+
|
55
|
+
* Add Dataset#literal_date_or_time, for simpler use by bound argument code (jeremyevans)
|
56
|
+
|
57
|
+
* Add auto_cast_date_and_time extension, for casting date and time values using SQL standard functions (jeremyevans)
|
58
|
+
|
59
|
+
=== 5.75.0 (2023-12-01)
|
60
|
+
|
61
|
+
* Make any_not_empty? extension support passing pattern argument to any? (jeremyevans) (#2100)
|
62
|
+
|
63
|
+
* Respect :skip_transaction option in PostgreSQL Dataset#paged_each (jeremyevans) (#2097)
|
64
|
+
|
65
|
+
* Add TimestampMigrator.run_single to run a single migration file up or down (opya, jeremyevans) (#2093)
|
66
|
+
|
67
|
+
* Support INSERT RETURNING on MariaDB 10.5+, and use it when saving new model objects (jeremyevans)
|
68
|
+
|
69
|
+
* Add Database#{defer,immediate}_constraints on PostgreSQL for changing handling of deferrable constraints in a transaction (jeremyevans)
|
70
|
+
|
71
|
+
=== 5.74.0 (2023-11-01)
|
72
|
+
|
73
|
+
* Make generated columns show up in Database#schema when using SQLite 3.37+ (jeremyevans) (#2087)
|
74
|
+
|
75
|
+
* Add revert method for Sequel.migration blocks, to revert changes inside the block on up, and apply the changes on down (jeremyevans)
|
76
|
+
|
77
|
+
* Re-add is_json and is_not_json methods to the pg_json_ops extension, as the support was re-added in PostgreSQL 16 (jeremyevans)
|
78
|
+
|
79
|
+
* Avoid infinite loop when handling exceptions with a cause loop in jdbc adapter (jeremyevans)
|
80
|
+
|
81
|
+
=== 5.73.0 (2023-10-01)
|
82
|
+
|
83
|
+
* Handle disconnect errors in ibmdb and jdbc/db2 adapters (jeremyevans) (#2083)
|
84
|
+
|
85
|
+
* Support skipping transactions in Dataset#{import,paged_each} using :skip_transaction option (jeremyevans)
|
86
|
+
|
87
|
+
* Add Database#transaction :skip_transaction option to skip creating a transaction or savepoint (jeremyevans)
|
88
|
+
|
89
|
+
* Stop using a transaction for a single query if calling Dataset#import with a dataset (jeremyevans)
|
90
|
+
|
91
|
+
* Add paged_operations plugin for paged deletes and updates and other custom operations (jeremyevans) (#2080)
|
92
|
+
|
93
|
+
* Support to_tsquery: :websearch option to Dataset#full_text_search on PostgreSQL 11+ (jeremyevans) (#2075)
|
94
|
+
|
95
|
+
* Add MassAssignmentRestriction#model and #column for getting the model instance and related column for mass assignment errors (artofhuman, jeremyevans) (#2079)
|
96
|
+
|
97
|
+
* Stop using base64 library in column_encryption plugin (jeremyevans)
|
98
|
+
|
99
|
+
=== 5.72.0 (2023-09-01)
|
100
|
+
|
101
|
+
* Sort caches before marshalling when using schema_caching, index_caching, static_cache_cache, and pg_auto_constraint_validations (jeremyevans)
|
102
|
+
|
103
|
+
* Change the defaults_setter plugin do a deep-copy of database default hash/array values and delegates (jeremyevans) (#2069)
|
104
|
+
|
105
|
+
* Add pg_auto_parameterize_in_array extension, for converting IN/NOT IN to = ANY or != ALL for more types (jeremyevans)
|
106
|
+
|
107
|
+
* Fix literalization of infinite and NaN float values in PostgreSQL array bound variables (jeremyevans)
|
108
|
+
|
109
|
+
=== 5.71.0 (2023-08-01)
|
110
|
+
|
111
|
+
* Support ILIKE ANY on PostgreSQL by not forcing the use of ESCAPE for ILIKE (gilesbowkett) (#2066)
|
112
|
+
|
113
|
+
* Add pg_xmin_optimistic_locking plugin for optimistic locking for all models without database changes (jeremyevans)
|
114
|
+
|
115
|
+
* Recognize the xid PostgreSQL type as an integer type in the jdbc/postgresql adapter (jeremyevans)
|
116
|
+
|
117
|
+
* Make set_column_allow_null method reversible in migrations (enescakir) (#2060)
|
118
|
+
|
119
|
+
=== 5.70.0 (2023-07-01)
|
120
|
+
|
121
|
+
* Make static_cache plugin better handle cases where forbid_lazy_load plugin is already loaded (jeremyevans)
|
122
|
+
|
123
|
+
* Fix ShardedThreadedConnectionPool#remove_server to disconnect all connections if removing multiple servers (jeremyevans)
|
124
|
+
|
125
|
+
* Support SEQUEL_DEFAULT_CONNECTION_POOL environment variable for choosing connection pool when :pool_class Database option is not set (jeremyevans)
|
126
|
+
|
127
|
+
* Add sharded_timed_queue connection pool (jeremyevans)
|
128
|
+
|
129
|
+
* Make connection_{validator,expiration} and async_thread_pool extensions work with timed_queue connection pool (jeremyevans)
|
130
|
+
|
131
|
+
* Make connection_{validator,expiration} extensions raise error when used with single threaded pools (HoneyryderChuck, jeremyevans) (#2049)
|
132
|
+
|
133
|
+
* Workaround possible resource starvation in threaded connection pool (ioquatix) (#2048)
|
134
|
+
|
135
|
+
=== 5.69.0 (2023-06-01)
|
136
|
+
|
137
|
+
* Avoid unsupported flag warning when using the mysql adapter with ruby-mysql 3+ (jeremyevans)
|
138
|
+
|
139
|
+
* Make mysql adapter work with ruby-mysql 4+ (jeremyevans)
|
140
|
+
|
141
|
+
* Add Model::DatasetModule#model accessor (davekaro) (#2040)
|
142
|
+
|
143
|
+
* Add trilogy adapter (jeremyevans)
|
144
|
+
|
145
|
+
=== 5.68.0 (2023-05-01)
|
146
|
+
|
147
|
+
* Add validation_helpers_generic_type_messages plugin for more useful type validation failure messages (jeremyevans) (#2028)
|
148
|
+
|
149
|
+
* Make constraint_validations plugin not validate missing columns that have a default value (jeremyevans) (#2023)
|
150
|
+
|
151
|
+
* Skip normal type name parsing for enum/array/composite/range/multirange types on PostgreSQL (jeremyevans) (#2019)
|
152
|
+
|
153
|
+
* Fix corner case where pg_extended_date_support did not work correctly when using the jdbc/postgresql adapter (jeremyevans)
|
154
|
+
|
155
|
+
* Include :min_value and :max_value schema entries for date/timestamp/timestamptz columns on PostgreSQL 9.6+ (jeremyevans)
|
156
|
+
|
157
|
+
=== 5.67.0 (2023-04-01)
|
158
|
+
|
159
|
+
* Fix dumping of string column sizes in the schema dumper on MSSQL (jeremyevans) (#2013)
|
160
|
+
|
161
|
+
* Improve dumping of tables in non-default schemas in the schema_dumper extension (jeremyevans) (#2006)
|
162
|
+
|
163
|
+
* Make Database#{tables,views} support :qualify option on Microsoft SQL Server (jeremyevans)
|
164
|
+
|
165
|
+
* Avoid use of singleton classes for datasets instances on Ruby 2.4+ (jeremyevans) (#2007)
|
166
|
+
|
167
|
+
* Deprecate registering datasets extensions using an object other than a module (jeremyevans)
|
168
|
+
|
169
|
+
* Add set_literalizer extension, for treating set usage in datasets similar to array usage (jeremyevans) (#1997)
|
170
|
+
|
171
|
+
=== 5.66.0 (2023-03-01)
|
172
|
+
|
173
|
+
* Recognize SQLite error related to strict tables as a constraint violation when using the amalgalite adapter (jeremyevans)
|
174
|
+
|
175
|
+
* Make Dataset#count work correctly for datasets using Dataset#values (jeremyevans) (#1992)
|
176
|
+
|
177
|
+
* Make Dataset#count with no argument/block handle dataset with custom SQL using ORDER BY on MSSQL (jeremyevans)
|
178
|
+
|
179
|
+
* Make Dataset#empty? correctly handle datasets with custom SQL or using Dataset#values where the first value is NULL (andy-k, jeremyevans) (#1990)
|
180
|
+
|
181
|
+
=== 5.65.0 (2023-02-01)
|
182
|
+
|
183
|
+
* Allow pg_auto_parameterize extension to use placeholder loaders (jeremyevans)
|
184
|
+
|
185
|
+
* Do not include :min_value and :max_value schema entries for decimal/numeric columns on MySQL versions not supporting check constraints (jeremyevans)
|
186
|
+
|
187
|
+
* Make Database#indexes return indexes for partitioned tables on PostgreSQL 11+ (jeremyevans)
|
188
|
+
|
189
|
+
=== 5.64.0 (2023-01-01)
|
190
|
+
|
191
|
+
* Make :db_type column schema entries on SQLAnywhere include precision/scale information (jeremyevans)
|
192
|
+
|
193
|
+
* Include :min_value and :max_value schema entries for decimal/numeric columns on most databases (rolftimmermans, jeremyevans) (#1975)
|
194
|
+
|
195
|
+
* Support :graph_use_association_block association option to make eager_graph use the association block (jeremyevans)
|
196
|
+
|
197
|
+
* Make many_through_many and many_through_one associations support eager_graph callbacks (jeremyevans)
|
198
|
+
|
199
|
+
=== 5.63.0 (2022-12-01)
|
200
|
+
|
201
|
+
* Make validates_associated plugin avoid database type errors for non-integer association keys (jeremyevans) (#1968)
|
202
|
+
|
203
|
+
* Make tactical_eager_loading plugin work better with table inheritance plugins (rolftimmermans, jeremyevans) (#1962)
|
204
|
+
|
205
|
+
* Add support for pool_class: :timed_queue on Ruby 3.2+, using a Queue for available connections (jeremyevans)
|
206
|
+
|
207
|
+
* Allow :pool_class Database option to be specified as a string to more easily choose a different pool type (jeremyevans)
|
208
|
+
|
209
|
+
* Use compare_by_identity hashes for Thread-keyed hashes in threaded connection pools (jeremyevans)
|
210
|
+
|
211
|
+
* Skip use of JRuby workaround on JRuby 9.3.9.0+ in named_timezones extension as JRuby fixed the related bug (jeremyevans)
|
212
|
+
|
213
|
+
=== 5.62.0 (2022-11-01)
|
214
|
+
|
215
|
+
* Add back the pg_auto_parameterize extension for automatically using bound variables when using postgres adapter with pg driver (jeremyevans)
|
216
|
+
|
217
|
+
* Add pg_extended_integer_support extension for customizing behavior when literalizing a Ruby integer outside PostgreSQL bigint range (jeremyevans)
|
218
|
+
|
219
|
+
* Raise Postgres::IntegerOutsideBigintRange if attempting to literalize a Ruby integer outside PostgreSQL bigint range (jeremyevans)
|
220
|
+
|
221
|
+
* Add primary_key_lookup_check_values plugin for typecasting and checking primary key values during lookup (jeremyevans)
|
222
|
+
|
223
|
+
* Setup validation of minimum and maximum values for integer columns in auto_validations (jeremyevans)
|
224
|
+
|
225
|
+
* Add validates_max_value and validates_min_value to validation_helpers (jeremyevans)
|
226
|
+
|
227
|
+
* Include :min_value and :max_value schema entries for integer columns on most databases (jeremyevans)
|
228
|
+
|
229
|
+
* Don't wrap multi-inserts in a transaction when it's not required (shannoncole, jeremyevans) (#1945)
|
230
|
+
|
231
|
+
* Update mock PostgreSQL adapter to default to PostgreSQL 15 instead of PostgreSQL 14 (jeremyevans)
|
232
|
+
|
233
|
+
* Support fractional seconds in the named_timezones extension (jeremyevans) (#1943)
|
234
|
+
|
235
|
+
* Cache reflection datasets in the postgres adapter to improve performance (jeremyevans)
|
236
|
+
|
237
|
+
* Handle BC dates and timestamps in bound variables when using the pg_extended_date_support extension (jeremyevans)
|
238
|
+
|
239
|
+
* Correctly format hstore[] types in bound variables on PostgreSQL (jeremyevans)
|
240
|
+
|
241
|
+
* Fix corner case in eager loading where window function eager limit strategy is used, but row number entry is not removed (jeremyevans)
|
242
|
+
|
243
|
+
* Support server/shard specific :after_connect and :connect_sqls Database options (jeremyevans) (#1935)
|
244
|
+
|
245
|
+
=== 5.61.0 (2022-10-01)
|
246
|
+
|
247
|
+
* Make Database#foreign_key_list on PostgreSQL return results for partitioned tables (jeremyevans)
|
248
|
+
|
249
|
+
* Add Database#check_string_typecast_bytesize for checking bytesize of strings before typecasting (jeremyevans)
|
250
|
+
|
251
|
+
* Treat negative hexidecimal strings similar to positive hexidecimal strings when typecasting to integer (jeremyevans)
|
252
|
+
|
253
|
+
* Remove is_json and is_not_json methods from the pg_json_ops extension, as the support was removed in PostgreSQL 15 beta 4 (jeremyevans)
|
254
|
+
|
255
|
+
* Fix handling of timestamps before the date of calendar reform when using pg_extended_date_support extension on Ruby 3.2 (jeremyevans)
|
256
|
+
|
257
|
+
=== 5.60.1 (2022-09-02)
|
258
|
+
|
259
|
+
* Revert conversion of respond_to? to defined?, as it breaks with unused refinements on Ruby 2 (jeremyevans) (#1919)
|
260
|
+
|
261
|
+
=== 5.60.0 (2022-09-01)
|
262
|
+
|
263
|
+
* Support arbitrary expressions for date_arithmetic interval values on PostgreSQL 9.4+ (jeremyevans)
|
264
|
+
|
265
|
+
* Support native IS DISTINCT FROM on SQLite 3.39+ instead of emulating support in the is_distinct_from extension (jeremyevans)
|
266
|
+
|
267
|
+
* Support HAVING without GROUP BY on SQLite 3.39+ (jeremyevans)
|
268
|
+
|
269
|
+
* Convert most respond_to? calls to equivalent defined? for better performance (jeremyevans)
|
270
|
+
|
271
|
+
=== 5.59.0 (2022-08-01)
|
272
|
+
|
273
|
+
* Set :allow_eager association option to false for instance specific associations without eager loaders (jeremyevans)
|
274
|
+
|
275
|
+
* Add require_valid_schema plugin for checking that model classes have schema parsed as expected (jeremyevans)
|
276
|
+
|
277
|
+
* Model classes created from aliased expressions and literal strings no longer use the simple table optimization (jeremyevans)
|
278
|
+
|
279
|
+
* Model code that does not swallow connection errors will now also not swallow disconnect errors (jeremyevans) (#1892)
|
280
|
+
|
281
|
+
* Add is_json and is_not_json methods to the pg_json_ops extension, for the PostgreSQL 15+ IS [NOT] JSON operator (jeremyevans)
|
282
|
+
|
283
|
+
* Support :security_invoker view option on PostgreSQL 15+, for views where access uses permissions of user instead of owner (jeremyevans)
|
284
|
+
|
285
|
+
* Support :nulls_distinct index option on PostgreSQL 15+, for NULLS [NOT] DISTINCT (jeremyevans)
|
286
|
+
|
287
|
+
* Support sequel-postgres-pr driver in the postgres adapter (jeremyevans)
|
288
|
+
|
1
289
|
=== 5.58.0 (2022-07-01)
|
2
290
|
|
3
291
|
* Support :disable_split_materialized Database option on MySQL to work around optimizer bug in MariaDB 10.5+ affecting association tests (jeremyevans)
|
data/MIT-LICENSE
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
Copyright (c) 2007-2008 Sharon Rosner
|
2
|
-
Copyright (c) 2008-
|
2
|
+
Copyright (c) 2008-2023 Jeremy Evans
|
3
3
|
|
4
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
of this software and associated documentation files (the "Software"), to
|
data/README.rdoc
CHANGED
@@ -13,7 +13,7 @@ toolkit for Ruby.
|
|
13
13
|
database sharding.
|
14
14
|
* Sequel currently has adapters for ADO, Amalgalite,
|
15
15
|
IBM_DB, JDBC, MySQL, Mysql2, ODBC, Oracle,
|
16
|
-
PostgreSQL, SQLAnywhere, SQLite3, and
|
16
|
+
PostgreSQL, SQLAnywhere, SQLite3, TinyTDS, and Trilogy.
|
17
17
|
|
18
18
|
== Resources
|
19
19
|
|
@@ -24,8 +24,9 @@ Bug tracking (GitHub Issues) :: https://github.com/jeremyevans/sequel/issues
|
|
24
24
|
Discussion Forum (GitHub Discussions) :: https://github.com/jeremyevans/sequel/discussions
|
25
25
|
Alternate Discussion Forum (sequel-talk Google Group) :: http://groups.google.com/group/sequel-talk
|
26
26
|
|
27
|
-
If you have questions about how to use Sequel, please ask on
|
28
|
-
sequel-talk Google Group.
|
27
|
+
If you have questions about how to use Sequel, please ask on
|
28
|
+
GitHub Discussions or the sequel-talk Google Group.
|
29
|
+
Only use the the bug tracker to report
|
29
30
|
bugs in Sequel, not to ask for help on using Sequel.
|
30
31
|
|
31
32
|
To check out the source code:
|
@@ -55,9 +56,9 @@ If you have any comments or suggestions please post to the Google group.
|
|
55
56
|
items = DB[:items] # Create a dataset
|
56
57
|
|
57
58
|
# Populate the table
|
58
|
-
items.insert(:
|
59
|
-
items.insert(:
|
60
|
-
items.insert(:
|
59
|
+
items.insert(name: 'abc', price: rand * 100)
|
60
|
+
items.insert(name: 'def', price: rand * 100)
|
61
|
+
items.insert(name: 'ghi', price: rand * 100)
|
61
62
|
|
62
63
|
# Print out the number of records
|
63
64
|
puts "Item count: #{items.count}"
|
@@ -83,7 +84,7 @@ Sequel uses the concept of datasets to retrieve data. A Dataset object encapsula
|
|
83
84
|
|
84
85
|
For example, the following one-liner returns the average GDP for countries in the middle east region:
|
85
86
|
|
86
|
-
DB[:countries].where(:
|
87
|
+
DB[:countries].where(region: 'Middle East').avg(:GDP)
|
87
88
|
|
88
89
|
Which is equivalent to:
|
89
90
|
|
@@ -91,7 +92,7 @@ Which is equivalent to:
|
|
91
92
|
|
92
93
|
Since datasets retrieve records only when needed, they can be stored and later reused. Records are fetched as hashes, and are accessed using an +Enumerable+ interface:
|
93
94
|
|
94
|
-
middle_east = DB[:countries].where(:
|
95
|
+
middle_east = DB[:countries].where(region: 'Middle East')
|
95
96
|
middle_east.order(:name).each{|r| puts r[:name]}
|
96
97
|
|
97
98
|
Sequel also offers convenience methods for extracting data from Datasets, such as an extended +map+ method:
|
@@ -209,12 +210,12 @@ If the dataset is ordered, you can also ask for the last record:
|
|
209
210
|
|
210
211
|
You can also provide a filter when asking for a single record:
|
211
212
|
|
212
|
-
posts.first(:
|
213
|
+
posts.first(id: 1)
|
213
214
|
# SELECT * FROM posts WHERE id = 1 LIMIT 1
|
214
215
|
|
215
216
|
Or retrieve a single value for a specific record:
|
216
217
|
|
217
|
-
posts.where(:
|
218
|
+
posts.where(id: 1).get(:name)
|
218
219
|
# SELECT name FROM posts WHERE id = 1 LIMIT 1
|
219
220
|
|
220
221
|
=== Filtering Records
|
@@ -410,13 +411,13 @@ As with +delete+, +update+ affects all rows in the dataset, so +where+ first,
|
|
410
411
|
+update+ second:
|
411
412
|
|
412
413
|
# DO THIS:
|
413
|
-
posts.where(Sequel[:stamp] < Date.today - 7).update(:
|
414
|
+
posts.where(Sequel[:stamp] < Date.today - 7).update(state: 'archived')
|
414
415
|
# NOT THIS:
|
415
|
-
posts.update(:
|
416
|
+
posts.update(state: 'archived').where(Sequel[:stamp] < Date.today - 7)
|
416
417
|
|
417
418
|
=== Merging records
|
418
419
|
|
419
|
-
Merging records using the SQL MERGE
|
420
|
+
Merging records using the SQL MERGE statement is done using <tt>merge*</tt> methods.
|
420
421
|
You use +merge_using+ to specify the merge source and join conditions.
|
421
422
|
You can use +merge_insert+, +merge_delete+, and/or +merge_update+ to set the
|
422
423
|
INSERT, DELETE, and UPDATE clauses for the merge. +merge_insert+ takes the same
|
@@ -447,7 +448,7 @@ You can wrap a block of code in a database transaction using the <tt>Database#tr
|
|
447
448
|
# BEGIN
|
448
449
|
posts.insert(category: 'ruby', author: 'david')
|
449
450
|
# INSERT
|
450
|
-
posts.where(Sequel[:stamp] < Date.today - 7).update(:
|
451
|
+
posts.where(Sequel[:stamp] < Date.today - 7).update(state: 'archived')
|
451
452
|
# UPDATE
|
452
453
|
end
|
453
454
|
# COMMIT
|
@@ -460,9 +461,9 @@ and not raise an exception outside the block, you can raise the
|
|
460
461
|
|
461
462
|
DB.transaction do
|
462
463
|
# BEGIN
|
463
|
-
posts.insert(:
|
464
|
+
posts.insert(category: 'ruby', author: 'david')
|
464
465
|
# INSERT
|
465
|
-
if posts.where('stamp < ?', Date.today - 7).update(:
|
466
|
+
if posts.where('stamp < ?', Date.today - 7).update(state: 'archived') == 0
|
466
467
|
# UPDATE
|
467
468
|
raise Sequel::Rollback
|
468
469
|
end
|
@@ -705,8 +706,8 @@ You can delete individual records by calling +delete+ or +destroy+. The only dif
|
|
705
706
|
|
706
707
|
Records can also be deleted en-masse by calling <tt>delete</tt> and <tt>destroy</tt> on the model's dataset. As stated above, you can specify filters for the deleted records:
|
707
708
|
|
708
|
-
Post.where(:
|
709
|
-
Post.where(:
|
709
|
+
Post.where(category: 32).delete # => bypasses hooks
|
710
|
+
Post.where(category: 32).destroy # => runs hooks
|
710
711
|
|
711
712
|
Please note that if <tt>destroy</tt> is called, each record is deleted
|
712
713
|
separately, but <tt>delete</tt> deletes all matching records with a single
|
@@ -719,9 +720,9 @@ Associations are used in order to specify relationships between model classes th
|
|
719
720
|
class Post < Sequel::Model
|
720
721
|
many_to_one :author
|
721
722
|
one_to_many :comments
|
722
|
-
one_to_one :first_comment, :
|
723
|
+
one_to_one :first_comment, class: :Comment, order: :id
|
723
724
|
many_to_many :tags
|
724
|
-
one_through_one :first_tag, :
|
725
|
+
one_through_one :first_tag, class: :Tag, order: :name, right_key: :tag_id
|
725
726
|
end
|
726
727
|
|
727
728
|
+many_to_one+ and +one_to_one+ create a getter and setter for each model object:
|
@@ -760,7 +761,7 @@ All associations add a dataset method that can be used to further filter or reor
|
|
760
761
|
Associations can be eagerly loaded via +eager+ and the <tt>:eager</tt> association option. Eager loading is used when loading a group of objects. It loads all associated objects for all of the current objects in one query, instead of using a separate query to get the associated objects for each current object. Eager loading requires that you retrieve all model objects at once via +all+ (instead of individually by +each+). Eager loading can be cascaded, loading association's associated objects.
|
761
762
|
|
762
763
|
class Person < Sequel::Model
|
763
|
-
one_to_many :posts, :
|
764
|
+
one_to_many :posts, eager: [:tags]
|
764
765
|
end
|
765
766
|
|
766
767
|
class Post < Sequel::Model
|
@@ -824,7 +825,7 @@ You can dynamically customize eager loads for both +eager+ and +eager_graph+ whi
|
|
824
825
|
|
825
826
|
=== Joining with Associations
|
826
827
|
|
827
|
-
You can use the +association_join+ method to add a join to the model's dataset based on the
|
828
|
+
You can use the +association_join+ method to add a join to the model's dataset based on the association:
|
828
829
|
|
829
830
|
Post.association_join(:author)
|
830
831
|
# SELECT * FROM posts
|
@@ -926,7 +927,7 @@ Sequel fully supports the currently supported versions of Ruby (MRI) and JRuby.
|
|
926
927
|
support unsupported versions of Ruby or JRuby, but such support may be dropped in any
|
927
928
|
minor version if keeping it becomes a support issue. The minimum Ruby version
|
928
929
|
required to run the current version of Sequel is 1.9.2, and the minimum JRuby version is
|
929
|
-
9.
|
930
|
+
9.2.0.0 (due to the bigdecimal dependency).
|
930
931
|
|
931
932
|
== Maintainer
|
932
933
|
|
data/bin/sequel
CHANGED
@@ -194,7 +194,11 @@ begin
|
|
194
194
|
TO_DB = connect_proc[db2]
|
195
195
|
same_db = DB.database_type==TO_DB.database_type
|
196
196
|
index_opts = {:same_db=>same_db}
|
197
|
+
|
198
|
+
# :nocov:
|
197
199
|
index_opts[:index_names] = :namespace if !DB.global_index_namespace? && TO_DB.global_index_namespace?
|
200
|
+
# :nocov:
|
201
|
+
|
198
202
|
if DB.database_type == :sqlite && !same_db
|
199
203
|
# SQLite integer types allows 64-bit integers
|
200
204
|
TO_DB.extension :integer64
|
@@ -212,18 +216,20 @@ begin
|
|
212
216
|
puts "Begin copying data"
|
213
217
|
DB.transaction do
|
214
218
|
TO_DB.transaction do
|
219
|
+
all_status_lines = ENV['SEQUEL_BIN_STATUS_ALL_LINES']
|
220
|
+
|
215
221
|
DB.tables.each do |table|
|
216
222
|
puts "Begin copying records for table: #{table}"
|
217
223
|
time = Time.now
|
218
224
|
to_ds = TO_DB.from(table)
|
219
225
|
j = 0
|
220
226
|
DB.from(table).each do |record|
|
221
|
-
|
227
|
+
to_ds.insert(record)
|
228
|
+
j += 1
|
229
|
+
if Time.now - time > 5 || all_status_lines
|
222
230
|
puts "Status: #{j} records copied"
|
223
231
|
time = Time.now
|
224
232
|
end
|
225
|
-
to_ds.insert(record)
|
226
|
-
j += 1
|
227
233
|
end
|
228
234
|
puts "Finished copying #{j} records for table: #{table}"
|
229
235
|
end
|
@@ -260,8 +266,10 @@ if !ARGV.empty?
|
|
260
266
|
ARGV.each{|v| load(v)}
|
261
267
|
elsif !$stdin.isatty
|
262
268
|
eval($stdin.read)
|
269
|
+
# :nocov:
|
263
270
|
else
|
264
271
|
require 'irb'
|
265
272
|
puts "Your database is stored in DB..."
|
266
273
|
IRB.start
|
267
274
|
end
|
275
|
+
# :nocov:
|
@@ -115,7 +115,7 @@ These two approaches can also be nested, with +eager+ -> +eager_graph+ -> +eager
|
|
115
115
|
|
116
116
|
Or with 2 separate +eager_graph+ queries:
|
117
117
|
|
118
|
-
Artist.eager_graph(:albums).eager_graph_eager([:albums], :
|
118
|
+
Artist.eager_graph(:albums).eager_graph_eager([:albums], tracks: proc{|ds| ds.eager_graph(:lyric)})
|
119
119
|
# 2 Queries:
|
120
120
|
# SELECT artists.id, artists.name, ...
|
121
121
|
# albums.id AS albums_id, albums.name AS albums_name, ...
|
@@ -238,9 +238,9 @@ have the following associations
|
|
238
238
|
|
239
239
|
and the following three albums in the database:
|
240
240
|
|
241
|
-
album1 = Album.create(:
|
242
|
-
album2 = Album.create(:
|
243
|
-
album3 = Album.create(:
|
241
|
+
album1 = Album.create(artist_id: 3) # id: 1
|
242
|
+
album2 = Album.create(artist_id: 3) # id: 2
|
243
|
+
album3 = Album.create(artist_id: 2) # id: 3
|
244
244
|
|
245
245
|
If you try to eager load this dataset:
|
246
246
|
|
@@ -256,7 +256,7 @@ the are both in the array related to that key. album3 has a different
|
|
256
256
|
artist_id, so it is in a different array. Eager loading of artists is
|
257
257
|
done by looking for any artist having one of the keys in the hash:
|
258
258
|
|
259
|
-
artists = Artist.where(:
|
259
|
+
artists = Artist.where(id: id_map.keys).all
|
260
260
|
|
261
261
|
When the artists are retrieved, you can iterate over them, find entries
|
262
262
|
with matching keys, and manually associate them to the albums:
|
@@ -281,7 +281,7 @@ case each array only has a single object, because id is the primary key). So wh
|
|
281
281
|
looking for tracks to eagerly load, you only need to look for ones that have an
|
282
282
|
album_id with one of the keys in the hash:
|
283
283
|
|
284
|
-
tracks = Track.where(:
|
284
|
+
tracks = Track.where(album_id: id_map.keys).all
|
285
285
|
|
286
286
|
When the tracks are retrieved, you can iterate over them, find entries with matching
|
287
287
|
keys, and manually associate them to the albums:
|
@@ -314,10 +314,10 @@ artist or tracks method on the album will not do another database lookup.
|
|
314
314
|
|
315
315
|
So putting everything together, the artist eager loader looks like:
|
316
316
|
|
317
|
-
Album.many_to_one :artist, :
|
317
|
+
Album.many_to_one :artist, eager_loader: (proc do |eo_opts|
|
318
318
|
eo_opts[:rows].each{|album| album.associations[:artist] = nil}
|
319
319
|
id_map = eo_opts[:id_map]
|
320
|
-
Artist.where(:
|
320
|
+
Artist.where(id: id_map.keys).all do |artist|
|
321
321
|
if albums = id_map[artist.id]
|
322
322
|
albums.each do |album|
|
323
323
|
album.associations[:artist] = artist
|
@@ -328,10 +328,10 @@ So putting everything together, the artist eager loader looks like:
|
|
328
328
|
|
329
329
|
and the tracks eager loader looks like:
|
330
330
|
|
331
|
-
Album.one_to_many :tracks, :
|
331
|
+
Album.one_to_many :tracks, eager_loader: (proc do |eo_opts|
|
332
332
|
eo_opts[:rows].each{|album| album.associations[:tracks] = []}
|
333
333
|
id_map = eo_opts[:id_map]
|
334
|
-
Track.where(:
|
334
|
+
Track.where(album_id: id_map.keys).all do |track|
|
335
335
|
if albums = id_map[track.album_id]
|
336
336
|
albums.each do |album|
|
337
337
|
album.associations[:tracks] << track
|
@@ -405,7 +405,7 @@ the window function strategy:
|
|
405
405
|
|
406
406
|
Artist.one_to_many :first_10_albums, class: :Album, order: :release_date, limit: 10,
|
407
407
|
eager_limit_strategy: :window_function
|
408
|
-
Artist.where(:
|
408
|
+
Artist.where(id: [1,2]).eager(:first_10_albums).all
|
409
409
|
# SELECT * FROM (
|
410
410
|
# SELECT *, row_number() OVER (PARTITION BY albums.artist_id ORDER BY release_date) AS x_sequel_row_number_x
|
411
411
|
# FROM albums
|
@@ -483,7 +483,7 @@ function:
|
|
483
483
|
The :correlated_subquery approach JOINs to a nested subquery using a correlated
|
484
484
|
subquery:
|
485
485
|
|
486
|
-
Artist.eager_graph_with_options(:first_10_albums, :
|
486
|
+
Artist.eager_graph_with_options(:first_10_albums, limit_strategy: :correlated_subquery).all
|
487
487
|
# SELECT artists.id, artists.name, first_10_albums.id AS first_10_albums_id,
|
488
488
|
# first_10_albums.name AS first_10_albums_name, first_10_albums.artist_id,
|
489
489
|
# first_10_albums.release_date
|
@@ -670,8 +670,10 @@ polymorphic associations in Sequel about as easy as it is in ActiveRecord. Howe
|
|
670
670
|
here's how they can be done using Sequel's custom associations (the sequel_polymorphic
|
671
671
|
external plugin is just a generic version of this code):
|
672
672
|
|
673
|
+
Sequel.extension :inflector # for attachable_type.constantize
|
674
|
+
|
673
675
|
class Asset < Sequel::Model
|
674
|
-
many_to_one :attachable, reciprocal: :assets,
|
676
|
+
many_to_one :attachable, reciprocal: :assets, reciprocal_type: :one_to_many,
|
675
677
|
setter: (lambda do |attachable|
|
676
678
|
self[:attachable_id] = (attachable.pk if attachable)
|
677
679
|
self[:attachable_type] = (attachable.class.name if attachable)
|
@@ -853,7 +855,7 @@ associated tickets.
|
|
853
855
|
class Project < Sequel::Model
|
854
856
|
one_to_many :tickets
|
855
857
|
many_to_one :ticket_hours, read_only: true, key: :id,
|
856
|
-
dataset: proc{Ticket.where(:
|
858
|
+
dataset: proc{Ticket.where(project_id: id).select{sum(hours).as(hours)}},
|
857
859
|
eager_loader: (lambda do |eo|
|
858
860
|
eo[:rows].each{|p| p.associations[:ticket_hours] = nil}
|
859
861
|
Ticket.where(project_id: eo[:id_map].keys).
|