sequel 5.43.0 → 5.47.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +40 -0
  3. data/README.rdoc +1 -2
  4. data/doc/association_basics.rdoc +70 -11
  5. data/doc/migration.rdoc +11 -5
  6. data/doc/release_notes/5.44.0.txt +32 -0
  7. data/doc/release_notes/5.45.0.txt +34 -0
  8. data/doc/release_notes/5.46.0.txt +87 -0
  9. data/doc/release_notes/5.47.0.txt +59 -0
  10. data/doc/sql.rdoc +12 -0
  11. data/doc/testing.rdoc +5 -0
  12. data/doc/virtual_rows.rdoc +1 -1
  13. data/lib/sequel/adapters/odbc.rb +5 -1
  14. data/lib/sequel/adapters/shared/mysql.rb +17 -0
  15. data/lib/sequel/adapters/shared/postgres.rb +0 -12
  16. data/lib/sequel/adapters/shared/sqlite.rb +55 -9
  17. data/lib/sequel/core.rb +11 -0
  18. data/lib/sequel/database/schema_generator.rb +25 -46
  19. data/lib/sequel/database/schema_methods.rb +1 -1
  20. data/lib/sequel/dataset/query.rb +2 -4
  21. data/lib/sequel/dataset/sql.rb +7 -0
  22. data/lib/sequel/extensions/date_arithmetic.rb +29 -15
  23. data/lib/sequel/extensions/pg_enum.rb +1 -1
  24. data/lib/sequel/extensions/pg_loose_count.rb +3 -1
  25. data/lib/sequel/extensions/schema_dumper.rb +11 -0
  26. data/lib/sequel/model/associations.rb +275 -89
  27. data/lib/sequel/plugins/async_thread_pool.rb +1 -1
  28. data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
  29. data/lib/sequel/plugins/column_encryption.rb +20 -3
  30. data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
  31. data/lib/sequel/plugins/many_through_many.rb +108 -9
  32. data/lib/sequel/plugins/pg_array_associations.rb +52 -38
  33. data/lib/sequel/plugins/prepared_statements.rb +10 -1
  34. data/lib/sequel/plugins/rcte_tree.rb +27 -19
  35. data/lib/sequel/plugins/timestamps.rb +1 -1
  36. data/lib/sequel/plugins/unused_associations.rb +520 -0
  37. data/lib/sequel/version.rb +1 -1
  38. metadata +14 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69c695b559f3d5c19284905e8bad5a8775cced221f5cd3f5bb1d89daa9c0785c
4
- data.tar.gz: 03cd2d01139038c3e6d1e1232f6b48a104657391aeefd82feab2636044480eba
3
+ metadata.gz: 191a57b6bd41c00e023891afaddbebffeb1f54017c663d2a9b32faf83584bf1f
4
+ data.tar.gz: d158aa702dfe28dbe624b551ed455615017942caf990c599f077a4fb53f6b533
5
5
  SHA512:
6
- metadata.gz: 4b6f0b096657603c11cf54b1b15b660c5b85a697e8b31b69f97f33d579401a73915a315b771467e56159313243c5643bb3ca5fd8c208f2c443d8c7536cba9fc0
7
- data.tar.gz: 1a44276ab427bc2f9a82e2f651950100360df998af75a9d3ca08618acfa3778b02764f544738569c5947b350ac8b2485b825052869ac882728707014e90633a8
6
+ metadata.gz: 5c91ce33e0191d342f34dbeb4a402153bedc6d46a1df56d99b1393cf559bb9edd837e3eca8f259e1f7856990015e40098cbb269cbc9e915fa4dac9fc254c8e0c
7
+ data.tar.gz: 9d789484e942ac7380e6dbae64b3e0fb27aeaf9d3fc6764f2e6d6e86c17296cdab116cd6c8d53c429044604a429fdaf18536b6f68b728f5031a81aba81f4107b
data/CHANGELOG CHANGED
@@ -1,3 +1,43 @@
1
+ === 5.47.0 (2021-08-01)
2
+
3
+ * Make the unused_associations plugin track access to association reflections to determine whether associations are used (jeremyevans)
4
+
5
+ * Support :db option for join tables in {many,one}_through_many to use a separate query for each join table (jeremyevans)
6
+
7
+ * Support :join_table_db option for many_to_many/one_through_one associations, to use a separate query for the join table (jeremyevans)
8
+
9
+ * Support :allow_eager_graph and :allow_filtering_by association options (jeremyevans)
10
+
11
+ * Add Database#rename_tables on MySQL, for renaming multiple tables in a single call (nick96) (#1774)
12
+
13
+ * Support Dataset#returning on SQLite 3.35+ (jeremyevans)
14
+
15
+ === 5.46.0 (2021-07-01)
16
+
17
+ * Add unused_associations plugin, for determining which associations and association methods are not used (jeremyevans)
18
+
19
+ * Make nil :setter/:adder/:remover/:clearer association options not create related methods (jeremyevans)
20
+
21
+ === 5.45.0 (2021-06-01)
22
+
23
+ * Fix handling of NULL values in boolean columns in the ODBC adapter (jeremyevans) (#1765)
24
+
25
+ * Add auto_validations_constraint_validations_presence_message plugin for auto_validations/constraint_validations presence message integration (jeremyevans)
26
+
27
+ * Support Dataset#with :materialized option on SQLite 3.35+ for [NOT] MATERIALIZED (jeremyevans)
28
+
29
+ * Use ALTER TABLE DROP COLUMN for dropping columns on SQLite 3.35+ (jeremyevans)
30
+
31
+ === 5.44.0 (2021-05-01)
32
+
33
+ * Add concurrent_eager_loading plugin, for eager loading multiple associations concurrently using separate threads (jeremyevans)
34
+
35
+ * Support :weeks as a interval unit in the date_arithmetic extension (jeremyevans) (#1759)
36
+
37
+ * Raise an exception if an interval hash with an unsupported key is passed in the date_arithmetic extension (jeremyevans) (#1759)
38
+
39
+ * Support dropping non-composite unique constraints on SQLite (jeremyevans) (#1755)
40
+
1
41
  === 5.43.0 (2021-04-01)
2
42
 
3
43
  * Add column_encryption plugin, for encrypting column values (jeremyevans)
data/README.rdoc CHANGED
@@ -22,10 +22,9 @@ RDoc Documentation :: http://sequel.jeremyevans.net/rdoc
22
22
  Source Code :: https://github.com/jeremyevans/sequel
23
23
  Bug tracking (GitHub Issues) :: http://github.com/jeremyevans/sequel/issues
24
24
  Discussion Forum (sequel-talk Google Group) :: http://groups.google.com/group/sequel-talk
25
- IRC Channel (#sequel) :: irc://irc.freenode.net/sequel
26
25
 
27
26
  If you have questions about how to use Sequel, please ask on the
28
- sequel-talk Google Group or IRC. Only use the the bug tracker to report
27
+ sequel-talk Google Group. Only use the the bug tracker to report
29
28
  bugs in Sequel, not to ask for help on using Sequel.
30
29
 
31
30
  To check out the source code:
@@ -41,7 +41,7 @@ As is the code to add a related album to an artist:
41
41
 
42
42
  @artist.add_album(name: 'RF')
43
43
 
44
- It also makes it easier to creating queries that use joins based on the association:
44
+ It also makes it easier to create queries that use joins based on the association:
45
45
 
46
46
  Artist.association_join(:albums)
47
47
  # SELECT * FROM artists
@@ -63,8 +63,8 @@ It ships with additional association types via plugins.
63
63
 
64
64
  The many_to_one association is used when the table for the current class
65
65
  contains a foreign key that references the primary key in the table for the
66
- associated class. It is named because there can be many rows in the current
67
- table for each row in the associated table.
66
+ associated class. It is named 'many_to_one' because there can be many rows
67
+ in the current table for each row in the associated table.
68
68
 
69
69
  # Database schema:
70
70
  # albums artists
@@ -81,8 +81,8 @@ table for each row in the associated table.
81
81
 
82
82
  The one_to_many association is used when the table for the associated class
83
83
  contains a foreign key that references the primary key in the table for the
84
- current class. It is named because for each row in the current table there
85
- can be many rows in the associated table:
84
+ current class. It is named 'one_to_many' because for each row in the
85
+ current table there can be many rows in the associated table:
86
86
 
87
87
  The one_to_one association can be thought of as a subset of the one_to_many association,
88
88
  but where there can only be either 0 or 1 records in the associated table. This is
@@ -344,7 +344,7 @@ instance method:
344
344
 
345
345
  == Dataset Method
346
346
 
347
- In addition to the above methods, associations also add a instance method
347
+ In addition to the above methods, associations also add an instance method
348
348
  ending in +_dataset+ that returns a dataset representing the objects in the associated table:
349
349
 
350
350
  @album.artist_id
@@ -826,6 +826,8 @@ you also wanted to handle the Artist#add_album method:
826
826
  end)
827
827
  end
828
828
 
829
+ You can set this to +nil+ to not create a add_<i>association</i> method.
830
+
829
831
  === :remover (\_remove_<i>association</i> method)
830
832
 
831
833
  Continuing with the same example, here's how you would handle the same case if
@@ -837,6 +839,8 @@ you also wanted to handle the Artist#remove_album method:
837
839
  end)
838
840
  end
839
841
 
842
+ You can set this to +nil+ to not create a remove_<i>association</i> method.
843
+
840
844
  === :clearer (\_remove_all_<i>association</i> method)
841
845
 
842
846
  Continuing with the same example, here's how you would handle the same case if
@@ -850,6 +854,22 @@ you also wanted to handle the Artist#remove_all_albums method:
850
854
  end)
851
855
  end
852
856
 
857
+ You can set this to +nil+ to not create a remove_all_<i>association</i> method.
858
+
859
+ === :no_dataset_method
860
+
861
+ Setting this to true will not result in the <i>association</i>_dataset method
862
+ not being defined. This can save memory if you only use the <i>association</i>
863
+ method and do not call the <i>association</i>_dataset method directly or
864
+ indirectly.
865
+
866
+ === :no_association_method
867
+
868
+ Setting this to true will not result in the <i>association</i> method
869
+ not being defined. This can save memory if you only use the
870
+ <i>association</i>_dataset method and do not call the <i>association</i> method
871
+ directly or indirectly.
872
+
853
873
  == Association Options
854
874
 
855
875
  Sequel's associations mostly share the same options. For ease of understanding,
@@ -1087,7 +1107,7 @@ already applied, and the proc should return a modified copy of this dataset.
1087
1107
  Here's an example of an association of songs to artists through lyrics, where
1088
1108
  the artist can perform any one of four tasks for the lyric:
1089
1109
 
1090
- Album.one_to_many :songs, dataset: (lambda do |r|
1110
+ Artist.one_to_many :songs, dataset: (lambda do |r|
1091
1111
  r.associated_dataset.select_all(:songs).
1092
1112
  join(:lyrics, id: :lyricid, id=>[:composer_id, :arranger_id, :vocalist_id, :lyricist_id])
1093
1113
  end)
@@ -1146,6 +1166,23 @@ when deleting.
1146
1166
  ds.where(instrument_id: 5)
1147
1167
  end)
1148
1168
 
1169
+ ==== :join_table_db [+many_to_many+, +one_through_one+]
1170
+
1171
+ A Sequel::Database to use for the join table. Specifying this option switches the
1172
+ loading to use a separate query for the join table. This is useful if the
1173
+ join table is not located in the same database as the associated table, or
1174
+ if the database account with access to the associated table doesn't have
1175
+ access to the join table.
1176
+
1177
+ For example, if the Album class uses a different Sequel::Database than the Artist
1178
+ class, and the join table is in the database that the Artist class uses:
1179
+
1180
+ Artist.many_to_many :lead_guitar_albums, class: :Album, :join_table_db=>Artist.db
1181
+
1182
+ This option also affects the add/remove/remove_all methods, by changing
1183
+ which database is used for inserts/deletes from the join table (add/remove/remove_all
1184
+ defaults to use the current model's database instead of the associated model's database).
1185
+
1149
1186
  === Callback Options
1150
1187
 
1151
1188
  All callbacks can be specified as a Symbol, Proc, or array of both/either
@@ -1638,9 +1675,8 @@ For +many_to_one+ and +one_to_one+ associations, do not add a setter method.
1638
1675
  For +one_to_many+ and +many_to_many+, do not add the add_<i>association</i>,
1639
1676
  remove_<i>association</i>, or remove_all_<i>association</i> methods.
1640
1677
 
1641
- If the default modification methods would not do what you want, and you
1642
- don't plan on overriding the internal modification methods to do what you
1643
- want, it may be best to set this option to true.
1678
+ If you are not using the association modification methods, setting this
1679
+ value to true will save memory.
1644
1680
 
1645
1681
  ==== :validate
1646
1682
 
@@ -1667,12 +1703,35 @@ If set to false, you cannot load the association eagerly via eager or
1667
1703
  eager_graph.
1668
1704
 
1669
1705
  Artist.one_to_many :albums, allow_eager: false
1670
- Artist.eager(:albums) # Raises Sequel::Error
1706
+ Artist.eager(:albums) # Raises Sequel::Error
1707
+ Artist.eager_graph(:albums) # Raises Sequel::Error
1671
1708
 
1672
1709
  This is usually used if the association dataset depends on specific values in
1673
1710
  model instance that would not be valid when eager loading for multiple
1674
1711
  instances.
1675
1712
 
1713
+ ==== :allow_eager_graph
1714
+
1715
+ If set to false, you cannot load the association eagerly via eager_graph.
1716
+
1717
+ Artist.one_to_many :albums, allow_eager_graph: false
1718
+ Artist.eager(:albums) # Allowed
1719
+ Artist.eager_graph(:albums) # Raises Sequel::Error
1720
+
1721
+ This is useful if you still want to allow loading via eager, but do not want
1722
+ to allow loading via eager graph, possibly because the association does not
1723
+ support joins.
1724
+
1725
+ ==== :allow_filtering_by
1726
+
1727
+ If set to false, you cannot use the association when filtering.
1728
+
1729
+ Artist.one_to_many :albums, allow_filtering_by: false
1730
+ Artist.where(:albums=>Album.where(:name=>'A')).all # Raises Sequel::Error
1731
+
1732
+ This is useful if such filtering cannot work, such as when a subquery cannot
1733
+ be used because the necessary tables are not in the same database.
1734
+
1676
1735
  ==== :instance_specific
1677
1736
 
1678
1737
  This allows you to override the setting of whether the dataset contains instance
data/doc/migration.rdoc CHANGED
@@ -543,16 +543,22 @@ The main difference between the two is that <tt>-d</tt> will use the type method
543
543
  with the database independent ruby class types, while <tt>-D</tt> will use
544
544
  the +column+ method with string types.
545
545
 
546
- Note that Sequel cannot dump constraints other than primary key and possibly
547
- foreign key constraints. If you are using database features such
548
- as constraints or triggers, you should use your database's dump and restore
549
- programs instead of Sequel's schema dumper.
550
-
551
546
  You can take the migration created by the schema dumper to another computer
552
547
  with an empty database, and attempt to recreate the schema using:
553
548
 
554
549
  sequel -m db/migrations postgres://host/database
555
550
 
551
+ The schema_dumper extension is quite limited in what types of
552
+ database objects it supports. In general, it only supports
553
+ dumping tables, columns, primary key and foreign key constraints,
554
+ and some indexes. It does not support most table options, CHECK
555
+ constraints, partial indexes, database functions, triggers,
556
+ security grants/revokes, and a wide variety of other useful
557
+ database properties. Be aware of the limitations when using the
558
+ schema_dumper extension. If you are dumping the schema to restore
559
+ to the same database type, it is recommended to use your database's
560
+ dump and restore programs instead of the schema_dumper extension.
561
+
556
562
  == Checking for Current Migrations
557
563
 
558
564
  In your application code, you may want to check that you are up to date in
@@ -0,0 +1,32 @@
1
+ = New Features
2
+
3
+ * A concurrent_eager_loading plugin has been added. This plugin
4
+ builds on top of the async_thread_pool Database extension and
5
+ allows eager loading multiple associations concurrently in
6
+ separate threads. With this plugin, you can mark datasets for
7
+ concurrent eager loading using eager_load_concurrently:
8
+
9
+ Album.eager_load_concurrently.eager(:artist, :genre, :tracks).all
10
+
11
+ Datasets that are marked for concurrent eager loading will use
12
+ concurrent eager loading if they are eager loading more than one
13
+ association. If you would like to make concurrent eager loading
14
+ the default, you can load the plugin with the :always option.
15
+
16
+ All of the association types that ship with Sequel now support
17
+ concurrent eager loading when using this plugin. For custom eager
18
+ loaders using the :eager_loader association option, please see the
19
+ documentation for the plugin for how to enable custom eager loading
20
+ for them.
21
+
22
+ = Other Improvements
23
+
24
+ * The date_arithmetic extension now handles ActiveSupport::Duration
25
+ values with weeks, as well as :weeks as a key in a hash value. Weeks
26
+ are converted into 7 days internally.
27
+
28
+ * The shared SQLite adapter now emulates the dropping of non-composite
29
+ unique constraints. Non-composite unique constraints are now
30
+ treated similarly to composite unique constraints, in that dropping
31
+ any unique constraints on a table will drop all unique constraints
32
+ on that table.
@@ -0,0 +1,34 @@
1
+ = New Features
2
+
3
+ * A auto_validations_constraint_validations_presence_message plugin
4
+ has been added that provides integration for the auto_validations
5
+ and constraint_validations plugin in the following conditions:
6
+
7
+ * The column has a NOT NULL constraint
8
+ * The column has a presence constraint validation with both
9
+ the :message and :allow_nil options used.
10
+
11
+ In this case, when saving a nil value in the column, the plugin
12
+ will make it so the more specific message from the presence
13
+ constraint validation is used, instead of the generic message
14
+ from auto_validations.
15
+
16
+ = Other Improvements
17
+
18
+ * On SQLite 3.35.0+, Sequel now uses ALTER TABLE DROP COLUMN for
19
+ dropping columns, instead of emulating the dropped column by
20
+ recreating the table.
21
+
22
+ * The Dataset#with :materialized option is now supported on SQLite
23
+ 3.35.0+ for specifying whether common table expressions should be
24
+ materialized.
25
+
26
+ * The odbc adapter now correct handles boolean columns with NULL
27
+ values. Previously, such values were returned as false instead
28
+ of nil.
29
+
30
+ = Backwards Compatibility
31
+
32
+ * The change to use ALTER TABLE DROP COLUMN on SQLite 3.35.0+ can
33
+ cause backwards compatibility issues if SQLite 3.35.0+ does
34
+ not allow dropping the column.
@@ -0,0 +1,87 @@
1
+ = New Features
2
+
3
+ * An unused_associations plugin has been added, which allows you to
4
+ determine which associations and association methods are not used.
5
+ You can use this to avoid defining the unused associations and
6
+ association methods, which can save memory.
7
+
8
+ This plugin is supported on Ruby 2.5+, and uses method coverage to
9
+ determine if the plugin's methods are called. Because Sequel::Model
10
+ adds association methods to an anonymous module included in the
11
+ class, directly using the method coverage data to determine which
12
+ associations are used is challenging.
13
+
14
+ This plugin is mostly designed for reporting. You can have a
15
+ test suite that runs with method coverage enabled, and use the
16
+ coverage information to get data on unused associations:
17
+
18
+ # Calls Coverage.result
19
+ cov_data = Sequel::Model.update_associations_coverage
20
+ unused_associations_data = Sequel::Model.update_unused_associations_data(coverage_data: cov_data)
21
+ Sequel::Model.unused_associations(unused_associations_data: unused_associations_data)
22
+ # => [["Class1", "assoc1"], ...]
23
+
24
+ unused_associations returns an array of two element arrays, where
25
+ the first element is the class name and the second element is the
26
+ association name. The returned values will be associations where
27
+ all of the association methods are not used.
28
+
29
+ In addition to determining which associations are not used, you can
30
+ also use this to determine if you are defining association methods
31
+ that are not used:
32
+
33
+ Sequel::Model.unused_association_options(unused_associations_data: unused_associations_data)
34
+ # => [["Class2", "assoc2", {:read_only=>true}], ...]
35
+
36
+ unused_association_options is similar to unused_associations, but
37
+ returns an array of three element arrays, where the third element
38
+ is a hash of association options that should be used to avoid
39
+ defining the unused association methods. It's common in Sequel to
40
+ define associations and only use them for reading data and not for
41
+ modifications, and you can use this to easily see which associations
42
+ are only used for reading data.
43
+
44
+ As the determination of whether associations are used is based on
45
+ method coverage, this will report as unused any associations that are
46
+ used but where the association methods are not called. These cases
47
+ are rare, but can happen if you have libraries that use the
48
+ association reflection metadata without calling the association
49
+ methods, or use the association only in combination with another
50
+ plugin such as dataset_associations. You can set the :is_used
51
+ association option to explicitly mark an association as used, and
52
+ have this plugin avoid reporting it as unused.
53
+
54
+ In addition to just reporting on unused associations, you can also
55
+ directly use the unused associations metadata to automatically avoid
56
+ defining unused associations or unused associations methods. You
57
+ can set a :file option when loading the plugin:
58
+
59
+ Sequel::Model.plugin :unused_associations, file: 'unused_associations.json'
60
+
61
+ Then run the method coverage testing. This will save the unused
62
+ associations metadata to the file. Then you can use this metadata
63
+ automatically by also setting the :modify_associations option:
64
+
65
+ Sequel::Model.plugin :unused_associations, file: 'unused_associations.json',
66
+ modify_associations: true
67
+
68
+ With the :modify_associations option, unused associations are
69
+ skipped instead of being defined, and the options returned by
70
+ unused_association_options are automatically used. Note that using
71
+ the :modify_associations option is risky unless you have complete
72
+ coverage and do not have cases where the associations are used
73
+ without calling methods.
74
+
75
+ It is common to have multiple test suites where you need to combine
76
+ coverage. The plugin supports this by using a :coverage_file option:
77
+
78
+ Sequel::Model.plugin :unused_associations, coverage_file: 'unused_associations_coverage.json'
79
+
80
+ In this case, you would run update_associations_coverage after each
81
+ test suite, and update_unused_associations_data only after all test
82
+ suites have been run.
83
+
84
+ * Passing nil as the value of the :setter, :adder, :remover, or
85
+ :clearer association options will cause the related method to not be
86
+ defined, instead of using the default value. This allows you to
87
+ only define the methods you will actually be using.
@@ -0,0 +1,59 @@
1
+ = New Features
2
+
3
+ * Sequel now supports using separate queries for each table for both
4
+ lazy and eager loading of the following associations:
5
+
6
+ * many_to_many
7
+ * one_through_one
8
+ * many_through_many # many_through_many plugin
9
+ * one_through_many # many_through_many plugin
10
+
11
+ For many_to_many/one_through_one, you specify the :join_table_db
12
+ association option, which should be a Sequel::Database instance
13
+ containing the join table. It is possible for the current table,
14
+ join table, and associated table all to be in separate databases:
15
+
16
+ JOIN_TABLE_DB = Sequel.connect('...')
17
+ Album.many_to_many :artists, join_table_db: JOIN_TABLE_DB
18
+
19
+ For many_through_many/one_through_many, you can use the :db option
20
+ in each join table specification. All join tables can be in
21
+ separate databases:
22
+
23
+ JTDB1 = Sequel.connect('...')
24
+ JTDB2 = Sequel.connect('...')
25
+ # Tracks on all albums this artist appears on
26
+ Artist.many_through_many :album_tracks, [
27
+ {table: :albums_artists, left: :artist_id, right: :album_id, db: JTDB1},
28
+ {table: :artists, left: :id, right: :id, db: JTDB2}
29
+ ],
30
+ class: :Track, right_primary_key: :album_id
31
+
32
+ * The :allow_eager_graph association option has been added. Setting
33
+ this option to false will disallow eager loading via #eager_graph.
34
+ This is useful if you can eager load the association via #eager,
35
+ but not with #eager_graph.
36
+
37
+ * The :allow_filtering_by association option has been added. Setting
38
+ this option to false will disallow the use of filtering by
39
+ associations for the association.
40
+
41
+ * Dataset#returning is now supported on SQLite 3.35.0+. To work around
42
+ bugs in the SQLite implementation, identifiers used in the RETURNING
43
+ clause are automatically aliased. Additionally, prepared statements
44
+ that use the RETURNING clause on SQLite seem to have issues, so the
45
+ prepared_statements plugin does not automatically use prepared
46
+ statements on SQLite for queries that use the RETURNING clause.
47
+
48
+ * Database#rename_tables has been added on MySQL to support renaming
49
+ multiple tables in the same query.
50
+
51
+ = Other Improvements
52
+
53
+ * The unused_associations plugin now tracks access to the association
54
+ reflection for associations, so it will no longer show an
55
+ association as completely unused if something is accessing the
56
+ association reflection for it. This eliminates most of the false
57
+ positives, where the plugin would show an association as unused
58
+ even though something was using it without calling the association
59
+ methods.