sequel 3.21.0 → 3.39.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.
- data/CHANGELOG +1061 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +103 -63
- data/Rakefile +59 -27
- data/bin/sequel +50 -26
- data/doc/active_record.rdoc +67 -51
- data/doc/advanced_associations.rdoc +189 -75
- data/doc/association_basics.rdoc +327 -79
- data/doc/cheat_sheet.rdoc +21 -21
- data/doc/core_extensions.rdoc +374 -0
- data/doc/dataset_basics.rdoc +10 -10
- data/doc/dataset_filtering.rdoc +54 -42
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +89 -557
- data/doc/model_hooks.rdoc +80 -29
- data/doc/object_model.rdoc +547 -0
- data/doc/opening_databases.rdoc +114 -53
- data/doc/prepared_statements.rdoc +41 -15
- data/doc/querying.rdoc +137 -56
- data/doc/reflection.rdoc +36 -10
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/release_notes/3.33.0.txt +157 -0
- data/doc/release_notes/3.34.0.txt +671 -0
- data/doc/release_notes/3.35.0.txt +144 -0
- data/doc/release_notes/3.36.0.txt +245 -0
- data/doc/release_notes/3.37.0.txt +338 -0
- data/doc/release_notes/3.38.0.txt +234 -0
- data/doc/release_notes/3.39.0.txt +237 -0
- data/doc/schema_modification.rdoc +585 -0
- data/doc/sharding.rdoc +99 -8
- data/doc/sql.rdoc +154 -112
- data/doc/testing.rdoc +169 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +78 -43
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +17 -11
- data/lib/sequel/adapters/do/postgres.rb +2 -61
- data/lib/sequel/adapters/do/sqlite.rb +0 -10
- data/lib/sequel/adapters/do.rb +18 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +453 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +56 -0
- data/lib/sequel/adapters/jdbc/derby.rb +325 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
- data/lib/sequel/adapters/jdbc/h2.rb +73 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
- data/lib/sequel/adapters/jdbc/informix.rb +21 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
- data/lib/sequel/adapters/jdbc/progress.rb +21 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
- data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +279 -97
- data/lib/sequel/adapters/mock.rb +372 -0
- data/lib/sequel/adapters/mysql.rb +125 -222
- data/lib/sequel/adapters/mysql2.rb +65 -56
- data/lib/sequel/adapters/odbc/mssql.rb +17 -9
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +349 -53
- data/lib/sequel/adapters/postgres.rb +368 -138
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +343 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +401 -116
- data/lib/sequel/adapters/shared/mysql.rb +424 -89
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
- data/lib/sequel/adapters/shared/oracle.rb +257 -45
- data/lib/sequel/adapters/shared/postgres.rb +675 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +285 -96
- data/lib/sequel/adapters/sqlite.rb +101 -39
- data/lib/sequel/adapters/swift/mysql.rb +10 -12
- data/lib/sequel/adapters/swift/postgres.rb +13 -79
- data/lib/sequel/adapters/swift/sqlite.rb +9 -6
- data/lib/sequel/adapters/swift.rb +28 -19
- data/lib/sequel/adapters/tinytds.rb +174 -22
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
- data/lib/sequel/adapters/utils/pg_types.rb +81 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +194 -0
- data/lib/sequel/connection_pool/sharded_single.rb +11 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +33 -2
- data/lib/sequel/connection_pool/single.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +43 -14
- data/lib/sequel/connection_pool.rb +10 -2
- data/lib/sequel/core.rb +143 -11
- data/lib/sequel/database/connecting.rb +38 -28
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +63 -2
- data/lib/sequel/database/logging.rb +7 -2
- data/lib/sequel/database/misc.rb +190 -46
- data/lib/sequel/database/query.rb +272 -110
- data/lib/sequel/database/schema_generator.rb +103 -36
- data/lib/sequel/database/schema_methods.rb +300 -67
- data/lib/sequel/dataset/actions.rb +344 -90
- data/lib/sequel/dataset/features.rb +101 -8
- data/lib/sequel/dataset/graph.rb +42 -15
- data/lib/sequel/dataset/misc.rb +52 -25
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +305 -54
- data/lib/sequel/dataset/sql.rb +720 -292
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +83 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
- data/lib/sequel/extensions/blank.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +72 -0
- data/lib/sequel/extensions/constraint_validations.rb +451 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
- data/lib/sequel/extensions/eval_inspect.rb +173 -0
- data/lib/sequel/extensions/inflector.rb +4 -0
- data/lib/sequel/extensions/looser_typecasting.rb +5 -4
- data/lib/sequel/extensions/migration.rb +100 -11
- data/lib/sequel/extensions/named_timezones.rb +9 -0
- data/lib/sequel/extensions/null_dataset.rb +94 -0
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pg_array.rb +537 -0
- data/lib/sequel/extensions/pg_array_ops.rb +263 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
- data/lib/sequel/extensions/pg_hstore.rb +313 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
- data/lib/sequel/extensions/pg_inet.rb +113 -0
- data/lib/sequel/extensions/pg_interval.rb +191 -0
- data/lib/sequel/extensions/pg_json.rb +208 -0
- data/lib/sequel/extensions/pg_range.rb +512 -0
- data/lib/sequel/extensions/pg_range_ops.rb +150 -0
- data/lib/sequel/extensions/pg_row.rb +572 -0
- data/lib/sequel/extensions/pg_row_ops.rb +182 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
- data/lib/sequel/extensions/pretty_table.rb +17 -72
- data/lib/sequel/extensions/query.rb +8 -4
- data/lib/sequel/extensions/query_literals.rb +79 -0
- data/lib/sequel/extensions/schema_caching.rb +76 -0
- data/lib/sequel/extensions/schema_dumper.rb +282 -76
- data/lib/sequel/extensions/select_remove.rb +39 -0
- data/lib/sequel/extensions/server_block.rb +140 -0
- data/lib/sequel/extensions/split_array_nil.rb +65 -0
- data/lib/sequel/extensions/sql_expr.rb +8 -110
- data/lib/sequel/extensions/string_date_time.rb +4 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
- data/lib/sequel/extensions/to_dot.rb +99 -83
- data/lib/sequel/model/associations.rb +1263 -409
- data/lib/sequel/model/base.rb +624 -171
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +24 -2
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model.rb +30 -11
- data/lib/sequel/no_core_ext.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/caching.rb +25 -18
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +44 -12
- data/lib/sequel/plugins/constraint_validations.rb +198 -0
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +72 -0
- data/lib/sequel/plugins/dirty.rb +214 -0
- data/lib/sequel/plugins/eager_each.rb +59 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/identity_map.rb +134 -15
- data/lib/sequel/plugins/instance_filters.rb +10 -0
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +58 -6
- data/lib/sequel/plugins/list.rb +13 -2
- data/lib/sequel/plugins/many_through_many.rb +103 -51
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +150 -66
- data/lib/sequel/plugins/optimistic_locking.rb +8 -0
- data/lib/sequel/plugins/pg_row.rb +121 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
- data/lib/sequel/plugins/prepared_statements.rb +167 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +31 -17
- data/lib/sequel/plugins/schema.rb +8 -3
- data/lib/sequel/plugins/serialization.rb +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
- data/lib/sequel/plugins/static_cache.rb +99 -0
- data/lib/sequel/plugins/subclasses.rb +29 -3
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/plugins/validation_helpers.rb +55 -4
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +649 -122
- data/lib/sequel/timezones.rb +67 -40
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/firebird_spec.rb +1 -1
- data/spec/adapters/mssql_spec.rb +194 -66
- data/spec/adapters/mysql_spec.rb +475 -306
- data/spec/adapters/oracle_spec.rb +92 -117
- data/spec/adapters/postgres_spec.rb +1982 -325
- data/spec/adapters/spec_helper.rb +9 -6
- data/spec/adapters/sqlite_spec.rb +203 -75
- data/spec/core/connection_pool_spec.rb +218 -93
- data/spec/core/database_spec.rb +956 -522
- data/spec/core/dataset_spec.rb +1631 -1242
- data/spec/core/expression_filters_spec.rb +690 -334
- data/spec/core/mock_adapter_spec.rb +453 -0
- data/spec/core/object_graph_spec.rb +88 -129
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +556 -53
- data/spec/core/spec_helper.rb +7 -48
- data/spec/core_extensions_spec.rb +626 -0
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/arbitrary_servers_spec.rb +110 -0
- data/spec/extensions/association_autoreloading_spec.rb +18 -10
- data/spec/extensions/association_dependencies_spec.rb +15 -25
- data/spec/extensions/association_pks_spec.rb +66 -32
- data/spec/extensions/association_proxies_spec.rb +4 -4
- data/spec/extensions/boolean_readers_spec.rb +25 -25
- data/spec/extensions/caching_spec.rb +47 -51
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
- data/spec/extensions/constraint_validations_spec.rb +316 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +88 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/eval_inspect_spec.rb +67 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +97 -128
- data/spec/extensions/identity_map_spec.rb +142 -24
- data/spec/extensions/inflector_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +72 -0
- data/spec/extensions/json_serializer_spec.rb +49 -12
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +49 -40
- data/spec/extensions/looser_typecasting_spec.rb +7 -7
- data/spec/extensions/many_through_many_spec.rb +368 -254
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
- data/spec/extensions/migration_spec.rb +140 -35
- data/spec/extensions/named_timezones_spec.rb +29 -11
- data/spec/extensions/nested_attributes_spec.rb +268 -89
- data/spec/extensions/null_dataset_spec.rb +85 -0
- data/spec/extensions/optimistic_locking_spec.rb +24 -21
- data/spec/extensions/pg_array_ops_spec.rb +112 -0
- data/spec/extensions/pg_array_spec.rb +320 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
- data/spec/extensions/pg_hstore_spec.rb +194 -0
- data/spec/extensions/pg_inet_spec.rb +47 -0
- data/spec/extensions/pg_interval_spec.rb +72 -0
- data/spec/extensions/pg_json_spec.rb +99 -0
- data/spec/extensions/pg_range_ops_spec.rb +56 -0
- data/spec/extensions/pg_range_spec.rb +395 -0
- data/spec/extensions/pg_row_ops_spec.rb +58 -0
- data/spec/extensions/pg_row_plugin_spec.rb +49 -0
- data/spec/extensions/pg_row_spec.rb +323 -0
- data/spec/extensions/pg_statement_cache_spec.rb +208 -0
- data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +87 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +7 -6
- data/spec/extensions/query_literals_spec.rb +167 -0
- data/spec/extensions/query_spec.rb +9 -3
- data/spec/extensions/rcte_tree_spec.rb +50 -43
- data/spec/extensions/schema_caching_spec.rb +41 -0
- data/spec/extensions/schema_dumper_spec.rb +434 -49
- data/spec/extensions/schema_spec.rb +30 -49
- data/spec/extensions/select_remove_spec.rb +38 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +86 -48
- data/spec/extensions/server_block_spec.rb +90 -0
- data/spec/extensions/sharding_spec.rb +69 -143
- data/spec/extensions/single_table_inheritance_spec.rb +23 -29
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +34 -67
- data/spec/extensions/split_array_nil_spec.rb +24 -0
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -0
- data/spec/extensions/subclasses_spec.rb +14 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +8 -11
- data/spec/extensions/touch_spec.rb +13 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +9 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +58 -67
- data/spec/extensions/validation_helpers_spec.rb +31 -37
- data/spec/extensions/xml_serializer_spec.rb +29 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
- data/spec/integration/associations_test.rb +659 -21
- data/spec/integration/database_test.rb +11 -5
- data/spec/integration/dataset_test.rb +717 -129
- data/spec/integration/eager_loader_test.rb +38 -54
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +604 -147
- data/spec/integration/prepared_statement_test.rb +272 -128
- data/spec/integration/schema_test.rb +367 -57
- data/spec/integration/spec_helper.rb +42 -32
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +31 -8
- data/spec/model/association_reflection_spec.rb +207 -8
- data/spec/model/associations_spec.rb +1206 -693
- data/spec/model/base_spec.rb +334 -100
- data/spec/model/dataset_methods_spec.rb +45 -27
- data/spec/model/eager_loading_spec.rb +828 -692
- data/spec/model/hooks_spec.rb +355 -67
- data/spec/model/model_spec.rb +251 -179
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +506 -232
- data/spec/model/spec_helper.rb +16 -77
- data/spec/model/validations_spec.rb +38 -2
- data/spec/rcov.opts +2 -0
- metadata +209 -80
- data/spec/core/core_sql_spec.rb +0 -451
data/MIT-LICENSE
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Copyright (c) 2007-2008 Sharon Rosner
|
|
2
|
-
Copyright (c) 2008-
|
|
2
|
+
Copyright (c) 2008-2012 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
|
@@ -12,15 +12,15 @@ toolkit for Ruby.
|
|
|
12
12
|
two-phase commit, transaction isolation, master/slave
|
|
13
13
|
configurations, and database sharding.
|
|
14
14
|
* Sequel currently has adapters for ADO, Amalgalite, DataObjects,
|
|
15
|
-
DB2, DBI, Firebird, Informix, JDBC, MySQL, Mysql2, ODBC,
|
|
16
|
-
Oracle, PostgreSQL, SQLite3, Swift, and TinyTDS.
|
|
15
|
+
DB2, DBI, Firebird, IBM_DB, Informix, JDBC, MySQL, Mysql2, ODBC,
|
|
16
|
+
OpenBase, Oracle, PostgreSQL, SQLite3, Swift, and TinyTDS.
|
|
17
17
|
|
|
18
18
|
== Resources
|
|
19
19
|
|
|
20
20
|
* {Website}[http://sequel.rubyforge.org]
|
|
21
21
|
* {Blog}[http://sequel.heroku.com]
|
|
22
22
|
* {Source code}[http://github.com/jeremyevans/sequel]
|
|
23
|
-
* {Bug tracking}[http://
|
|
23
|
+
* {Bug tracking}[http://github.com/jeremyevans/sequel/issues]
|
|
24
24
|
* {Google group}[http://groups.google.com/group/sequel-talk]
|
|
25
25
|
* {RDoc}[http://sequel.rubyforge.org/rdoc]
|
|
26
26
|
|
|
@@ -64,12 +64,14 @@ If you have any comments or suggestions please post to the Google group.
|
|
|
64
64
|
|
|
65
65
|
== The Sequel Console
|
|
66
66
|
|
|
67
|
-
Sequel includes an IRB console for quick access to databases. You can use it like this:
|
|
67
|
+
Sequel includes an IRB console for quick access to databases (usually referred to as <tt>bin/sequel</tt>). You can use it like this:
|
|
68
68
|
|
|
69
69
|
sequel sqlite://test.db # test.db in current directory
|
|
70
70
|
|
|
71
71
|
You get an IRB session with the database object stored in DB.
|
|
72
72
|
|
|
73
|
+
In addition to providing an IRB shell (the default behavior), bin/sequel also has support for migrating databases (-m and -M), dumping schema migrations (-d and -D), and copying databases (-C).
|
|
74
|
+
|
|
73
75
|
== An Introduction
|
|
74
76
|
|
|
75
77
|
Sequel is designed to take the hassle away from connecting to databases and manipulating them. Sequel deals with all the boring stuff like maintaining connections, formatting SQL correctly and fetching records so you can concentrate on your application.
|
|
@@ -91,11 +93,11 @@ Since datasets retrieve records only when needed, they can be stored and later r
|
|
|
91
93
|
|
|
92
94
|
Sequel also offers convenience methods for extracting data from Datasets, such as an extended +map+ method:
|
|
93
95
|
|
|
94
|
-
middle_east.map(:name) #=> ['Egypt', '
|
|
96
|
+
middle_east.map(:name) #=> ['Egypt', 'Turkey', 'Israel', ...]
|
|
95
97
|
|
|
96
98
|
Or getting results as a hash via +to_hash+, with one column as key and another as value:
|
|
97
99
|
|
|
98
|
-
middle_east.to_hash(:name, :area) #=> {'Israel' => 20000, '
|
|
100
|
+
middle_east.to_hash(:name, :area) #=> {'Israel' => 20000, 'Turkey' => 120000, ...}
|
|
99
101
|
|
|
100
102
|
== Getting Started
|
|
101
103
|
|
|
@@ -169,7 +171,7 @@ You can also iterate through records one at a time using +each+:
|
|
|
169
171
|
|
|
170
172
|
Or perform more advanced stuff:
|
|
171
173
|
|
|
172
|
-
names_and_dates = posts.map
|
|
174
|
+
names_and_dates = posts.map([:name, :date])
|
|
173
175
|
old_posts, recent_posts = posts.partition{|r| r[:date] < Date.today - 7}
|
|
174
176
|
|
|
175
177
|
You can also retrieve the first record in a dataset:
|
|
@@ -189,29 +191,29 @@ If the dataset is ordered, you can also ask for the last record:
|
|
|
189
191
|
|
|
190
192
|
=== Filtering Records
|
|
191
193
|
|
|
192
|
-
An easy way to filter records is to provide a hash of values to match to +
|
|
194
|
+
An easy way to filter records is to provide a hash of values to match to +where+:
|
|
193
195
|
|
|
194
|
-
my_posts = posts.
|
|
196
|
+
my_posts = posts.where(:category => 'ruby', :author => 'david')
|
|
195
197
|
# WHERE category = 'ruby' AND author = 'david'
|
|
196
198
|
|
|
197
199
|
You can also specify ranges:
|
|
198
200
|
|
|
199
|
-
my_posts = posts.
|
|
201
|
+
my_posts = posts.where(:stamp => (Date.today - 14)..(Date.today - 7))
|
|
200
202
|
# WHERE stamp >= '2010-06-30' AND stamp <= '2010-07-07'
|
|
201
203
|
|
|
202
204
|
Or arrays of values:
|
|
203
205
|
|
|
204
|
-
my_posts = posts.
|
|
206
|
+
my_posts = posts.where(:category => ['ruby', 'postgres', 'linux'])
|
|
205
207
|
# WHERE category IN ('ruby', 'postgres', 'linux')
|
|
206
208
|
|
|
207
209
|
Sequel also accepts expressions:
|
|
208
210
|
|
|
209
|
-
my_posts = posts.
|
|
211
|
+
my_posts = posts.where{stamp > Date.today << 1}
|
|
210
212
|
# WHERE stamp > '2010-06-14'
|
|
211
213
|
|
|
212
214
|
Some adapters will also let you specify Regexps:
|
|
213
215
|
|
|
214
|
-
my_posts = posts.
|
|
216
|
+
my_posts = posts.where(:category => /ruby/i)
|
|
215
217
|
# WHERE category ~* 'ruby'
|
|
216
218
|
|
|
217
219
|
You can also use an inverse filter via +exclude+:
|
|
@@ -221,22 +223,21 @@ You can also use an inverse filter via +exclude+:
|
|
|
221
223
|
|
|
222
224
|
You can also specify a custom WHERE clause using a string:
|
|
223
225
|
|
|
224
|
-
posts.
|
|
226
|
+
posts.where('stamp IS NOT NULL')
|
|
225
227
|
# WHERE stamp IS NOT NULL
|
|
226
228
|
|
|
227
229
|
You can use parameters in your string, as well:
|
|
228
230
|
|
|
229
231
|
author_name = 'JKR'
|
|
230
|
-
posts.
|
|
232
|
+
posts.where('(stamp < ?) AND (author != ?)', Date.today - 3, author_name)
|
|
231
233
|
# WHERE (stamp < '2010-07-11') AND (author != 'JKR')
|
|
232
|
-
posts.filter{(stamp < Date.today - 3) & ~{:author => author_name}} # same as above
|
|
233
234
|
|
|
234
235
|
Datasets can also be used as subqueries:
|
|
235
236
|
|
|
236
|
-
DB[:items].
|
|
237
|
+
DB[:items].where('price > ?', DB[:items].select{avg(price) + 100})
|
|
237
238
|
# WHERE price > (SELECT avg(price) + 100 FROM items)
|
|
238
239
|
|
|
239
|
-
After filtering you can retrieve the matching records by using any of the retrieval methods:
|
|
240
|
+
After filtering, you can retrieve the matching records by using any of the retrieval methods:
|
|
240
241
|
|
|
241
242
|
my_posts.each{|row| p row}
|
|
242
243
|
|
|
@@ -246,7 +247,7 @@ See the doc/dataset_filtering.rdoc file for more details.
|
|
|
246
247
|
|
|
247
248
|
Counting records is easy using +count+:
|
|
248
249
|
|
|
249
|
-
posts.
|
|
250
|
+
posts.where(:category.like('%ruby%')).count
|
|
250
251
|
# SELECT COUNT(*) FROM posts WHERE category LIKE '%ruby%'
|
|
251
252
|
|
|
252
253
|
And you can also query maximum/minimum values via +max+ and +min+:
|
|
@@ -273,7 +274,7 @@ Ordering datasets is simple using +order+:
|
|
|
273
274
|
posts.order(:stamp, :name)
|
|
274
275
|
# ORDER BY stamp, name
|
|
275
276
|
|
|
276
|
-
Chaining +order+ doesn't work the same as +
|
|
277
|
+
Chaining +order+ doesn't work the same as +where+:
|
|
277
278
|
|
|
278
279
|
posts.order(:stamp).order(:name)
|
|
279
280
|
# ORDER BY name
|
|
@@ -283,10 +284,27 @@ The +order_append+ method chains this way, though:
|
|
|
283
284
|
posts.order(:stamp).order_append(:name)
|
|
284
285
|
# ORDER BY stamp, name
|
|
285
286
|
|
|
287
|
+
The +order_prepend+ method can be used as well:
|
|
288
|
+
|
|
289
|
+
posts.order(:stamp).order_prepend(:name)
|
|
290
|
+
# ORDER BY name, stamp
|
|
291
|
+
|
|
286
292
|
You can also specify descending order:
|
|
287
293
|
|
|
288
|
-
posts.
|
|
294
|
+
posts.reverse_order(:stamp)
|
|
289
295
|
# ORDER BY stamp DESC
|
|
296
|
+
posts.order(Sequel.desc(:stamp))
|
|
297
|
+
# ORDER BY stamp DESC
|
|
298
|
+
|
|
299
|
+
=== Core Extensions
|
|
300
|
+
|
|
301
|
+
Note the use of <tt>Sequel.desc(:stamp)</tt> in the above example. Much of Sequel's DSL uses this style, calling methods on the Sequel module that return SQL expression objects. Sequel also ships with a {core_extensions extension}[link:files/doc/core_extensions_rdoc.html]) that integrates Sequel's DSL better into the ruby language, allowing you to write:
|
|
302
|
+
|
|
303
|
+
:stamp.desc
|
|
304
|
+
|
|
305
|
+
instead of:
|
|
306
|
+
|
|
307
|
+
Sequel.desc(:stamp)
|
|
290
308
|
|
|
291
309
|
=== Selecting Columns
|
|
292
310
|
|
|
@@ -297,7 +315,7 @@ Selecting specific columns to be returned is also simple using +select+:
|
|
|
297
315
|
posts.select(:stamp, :name)
|
|
298
316
|
# SELECT stamp, name FROM posts
|
|
299
317
|
|
|
300
|
-
Chaining +select+ works like +order+, not +
|
|
318
|
+
Chaining +select+ works like +order+, not +where+:
|
|
301
319
|
|
|
302
320
|
posts.select(:stamp).select(:name)
|
|
303
321
|
# SELECT name FROM posts
|
|
@@ -311,16 +329,16 @@ As you might expect, there is an +order_append+ equivalent for +select+ called +
|
|
|
311
329
|
|
|
312
330
|
Deleting records from the table is done with +delete+:
|
|
313
331
|
|
|
314
|
-
posts.
|
|
332
|
+
posts.where('stamp < ?', Date.today - 3).delete
|
|
315
333
|
# DELETE FROM posts WHERE stamp < '2010-07-11'
|
|
316
334
|
|
|
317
335
|
Be very careful when deleting, as +delete+ affects all rows in the dataset.
|
|
318
|
-
+
|
|
336
|
+
Call +where+ first and +delete+ second:
|
|
319
337
|
|
|
320
338
|
# DO THIS:
|
|
321
|
-
posts.
|
|
339
|
+
posts.where('stamp < ?', Date.today - 7).delete
|
|
322
340
|
# NOT THIS:
|
|
323
|
-
posts.delete.
|
|
341
|
+
posts.delete.where('stamp < ?', Date.today - 7)
|
|
324
342
|
|
|
325
343
|
=== Inserting Records
|
|
326
344
|
|
|
@@ -333,21 +351,21 @@ Inserting records into the table is done with +insert+:
|
|
|
333
351
|
|
|
334
352
|
Updating records in the table is done with +update+:
|
|
335
353
|
|
|
336
|
-
posts.
|
|
354
|
+
posts.where('stamp < ?', Date.today - 7).update(:state => 'archived')
|
|
337
355
|
# UPDATE posts SET state = 'archived' WHERE stamp < '2010-07-07'
|
|
338
356
|
|
|
339
357
|
You can reference table columns when choosing what values to set:
|
|
340
358
|
|
|
341
|
-
posts.
|
|
359
|
+
posts.where{|o| o.stamp < Date.today - 7}.update(:backup_number => :backup_number + 1)
|
|
342
360
|
# UPDATE posts SET backup_number = backup_number + 1 WHERE stamp < '2010-07-07'
|
|
343
361
|
|
|
344
|
-
As with +delete+, +update+ affects all rows in the dataset, so +
|
|
345
|
-
+update+ second
|
|
362
|
+
As with +delete+, +update+ affects all rows in the dataset, so +where+ first,
|
|
363
|
+
+update+ second:
|
|
346
364
|
|
|
347
365
|
# DO THIS:
|
|
348
|
-
posts.
|
|
366
|
+
posts.where('stamp < ?', Date.today - 7).update(:state => 'archived')
|
|
349
367
|
# NOT THIS:
|
|
350
|
-
posts.update(:state => 'archived').
|
|
368
|
+
posts.update(:state => 'archived').where('stamp < ?', Date.today - 7)
|
|
351
369
|
|
|
352
370
|
=== Transactions
|
|
353
371
|
|
|
@@ -355,7 +373,7 @@ You can wrap some code in a database transaction using the <tt>Database#transact
|
|
|
355
373
|
|
|
356
374
|
DB.transaction do
|
|
357
375
|
posts.insert(:category => 'ruby', :author => 'david')
|
|
358
|
-
posts.
|
|
376
|
+
posts.where('stamp < ?', Date.today - 7).update(:state => 'archived')
|
|
359
377
|
end
|
|
360
378
|
|
|
361
379
|
If the block does not raise an exception, the transaction will be committed.
|
|
@@ -376,11 +394,15 @@ and not raise an exception outside the block, you can raise the
|
|
|
376
394
|
Sequel makes it easy to join tables:
|
|
377
395
|
|
|
378
396
|
order_items = DB[:items].join(:order_items, :item_id => :id).
|
|
379
|
-
|
|
397
|
+
where(:order_items__order_id => 1234)
|
|
380
398
|
# SELECT * FROM items INNER JOIN order_items
|
|
381
399
|
# ON order_items.item_id = items.id
|
|
382
400
|
# WHERE order_items.order_id = 1234
|
|
383
401
|
|
|
402
|
+
The important thing to note here is that item_id is automatically qualified with
|
|
403
|
+
the table being joined, and id is automatically qualified with the last table
|
|
404
|
+
joined.
|
|
405
|
+
|
|
384
406
|
You can then do anything you like with the dataset:
|
|
385
407
|
|
|
386
408
|
order_total = order_items.sum(:price)
|
|
@@ -404,14 +426,14 @@ Using +graph+, you can split the result hashes into subhashes, one per join:
|
|
|
404
426
|
|
|
405
427
|
Sequel expects column names to be specified using symbols. In addition, returned hashes always use symbols as their keys. This allows you to freely mix literal values and column references in many cases. For example, the two following lines produce equivalent SQL:
|
|
406
428
|
|
|
407
|
-
items.
|
|
429
|
+
items.where(:x => 1)
|
|
408
430
|
# SELECT * FROM items WHERE (x = 1)
|
|
409
|
-
items.
|
|
431
|
+
items.where(1 => :x)
|
|
410
432
|
# SELECT * FROM items WHERE (1 = x)"
|
|
411
433
|
|
|
412
434
|
Ruby strings are generally treated as SQL strings:
|
|
413
435
|
|
|
414
|
-
items.
|
|
436
|
+
items.where(:x => 'x')
|
|
415
437
|
# SELECT * FROM items WHERE (x = 'x')
|
|
416
438
|
|
|
417
439
|
=== Qualifying column names
|
|
@@ -421,9 +443,9 @@ Column references can be qualified by using the double underscore special notati
|
|
|
421
443
|
items.literal(:items__price)
|
|
422
444
|
# items.price
|
|
423
445
|
|
|
424
|
-
Another way to qualify columns is to use the
|
|
446
|
+
Another way to qualify columns is to use the <tt>Sequel.qualify</tt> method:
|
|
425
447
|
|
|
426
|
-
items.literal(
|
|
448
|
+
items.literal(Sequel.qualify(:items, :price))
|
|
427
449
|
# items.price
|
|
428
450
|
|
|
429
451
|
=== Column aliases
|
|
@@ -435,9 +457,9 @@ You can also alias columns by using the triple undersecore special notation <tt>
|
|
|
435
457
|
items.literal(:items__price___p)
|
|
436
458
|
# items.price AS p
|
|
437
459
|
|
|
438
|
-
Another way to alias columns is to use the
|
|
460
|
+
Another way to alias columns is to use the <tt>Sequel.as</tt> method:
|
|
439
461
|
|
|
440
|
-
items.literal(
|
|
462
|
+
items.literal(Sequel.as(:price, :p))
|
|
441
463
|
# price AS p
|
|
442
464
|
|
|
443
465
|
== Sequel Models
|
|
@@ -463,7 +485,7 @@ You can explicitly set the table name or even the dataset used:
|
|
|
463
485
|
|
|
464
486
|
If you call +set_dataset+ with a symbol, it assumes you are referring to the table with the same name. You can also call it with a dataset, which will set the defaults for all retrievals for that model:
|
|
465
487
|
|
|
466
|
-
Post.set_dataset DB[:my_posts].
|
|
488
|
+
Post.set_dataset DB[:my_posts].where(:category => 'ruby')
|
|
467
489
|
Post.set_dataset DB[:my_posts].select(:id, :name).order(:date)
|
|
468
490
|
|
|
469
491
|
=== Model instances
|
|
@@ -498,12 +520,12 @@ A single model instance can also be fetched by specifying a condition:
|
|
|
498
520
|
|
|
499
521
|
A model class lets you iterate over subsets of records by proxying many methods to the underlying dataset. This means that you can use most of the +Dataset+ API to create customized queries that return model instances, e.g.:
|
|
500
522
|
|
|
501
|
-
Post.
|
|
523
|
+
Post.where(:category => 'ruby').each{|post| p post}
|
|
502
524
|
|
|
503
525
|
You can also manipulate the records in the dataset:
|
|
504
526
|
|
|
505
|
-
Post.
|
|
506
|
-
Post.
|
|
527
|
+
Post.where{num_comments < 7}.delete
|
|
528
|
+
Post.where(Sequel.like(:title, /ruby/)).update(:category => 'ruby')
|
|
507
529
|
|
|
508
530
|
=== Accessing record values
|
|
509
531
|
|
|
@@ -521,10 +543,12 @@ If the record's attributes names are not valid columns in the model's dataset (m
|
|
|
521
543
|
post[:id] #=> 123
|
|
522
544
|
post[:title] #=> 'hello world'
|
|
523
545
|
|
|
524
|
-
You can also modify record values using attribute setters or the +set+ method:
|
|
546
|
+
You can also modify record values using attribute setters, the <tt>[]=</tt> method, or the +set+ method:
|
|
525
547
|
|
|
526
548
|
post.title = 'hey there'
|
|
527
549
|
# or
|
|
550
|
+
post[:title] = 'hey there'
|
|
551
|
+
# or
|
|
528
552
|
post.set(:title=>'hey there')
|
|
529
553
|
|
|
530
554
|
That will just change the value for the object, it will not update the row in the database. To update the database row, call the +save+ method:
|
|
@@ -573,7 +597,7 @@ You can execute custom code when creating, updating, or deleting records by defi
|
|
|
573
597
|
|
|
574
598
|
Note the use of +super+ if you define your own hook methods. Almost all <tt>Sequel::Model</tt> class and instance methods (not just hook methods) can be overridden safely, but you have to make sure to call +super+ when doing so, otherwise you risk breaking things.
|
|
575
599
|
|
|
576
|
-
For the example above, you should probably use a database trigger if you can. Hooks can be used for data integrity, but they will only enforce that integrity when you are modifying the database through model instances
|
|
600
|
+
For the example above, you should probably use a database trigger if you can. Hooks can be used for data integrity, but they will only enforce that integrity when you are modifying the database through model instances, and even then they are often subject to race conditions. It's best to use database triggers and constraints to enforce data integrity.
|
|
577
601
|
|
|
578
602
|
=== Deleting records
|
|
579
603
|
|
|
@@ -584,8 +608,8 @@ You can delete individual records by calling +delete+ or +destroy+. The only dif
|
|
|
584
608
|
|
|
585
609
|
Records can also be deleted en-masse by calling <tt>Model.delete</tt> and <tt>Model.destroy</tt>. As stated above, you can specify filters for the deleted records:
|
|
586
610
|
|
|
587
|
-
Post.
|
|
588
|
-
Post.
|
|
611
|
+
Post.where(:category => 32).delete # => bypasses hooks
|
|
612
|
+
Post.where(:category => 32).destroy # => runs hooks
|
|
589
613
|
|
|
590
614
|
Please note that if <tt>Model.destroy</tt> is called, each record is deleted
|
|
591
615
|
separately, but <tt>Model.delete</tt> deletes all matching records with a single
|
|
@@ -630,7 +654,7 @@ All associations add a dataset method that can be used to further filter or reor
|
|
|
630
654
|
post.comments_dataset.destroy
|
|
631
655
|
|
|
632
656
|
# Return all tags related to this post with no subscribers, ordered by the tag's name
|
|
633
|
-
post.tags_dataset.
|
|
657
|
+
post.tags_dataset.where(:subscribers=>0).order(:name).all
|
|
634
658
|
|
|
635
659
|
=== Eager Loading
|
|
636
660
|
|
|
@@ -661,7 +685,7 @@ Associations can be eagerly loaded via +eager+ and the <tt>:eager</tt> associati
|
|
|
661
685
|
Post.eager(:person).all
|
|
662
686
|
|
|
663
687
|
# eager is a dataset method, so it works with filters/orders/limits/etc.
|
|
664
|
-
Post.
|
|
688
|
+
Post.where{topic > 'M'}.order(:date).limit(5).eager(:person).all
|
|
665
689
|
|
|
666
690
|
person = Person.first
|
|
667
691
|
# Eager loading via :eager (will eagerly load the tags for this person's posts)
|
|
@@ -681,9 +705,23 @@ Associations can be eagerly loaded via +eager+ and the <tt>:eager</tt> associati
|
|
|
681
705
|
# Loads all people, their posts, their posts' tags, replies to those posts,
|
|
682
706
|
# the person for each reply, the tag for each reply, and all posts and
|
|
683
707
|
# replies that have that tag. Uses a total of 8 queries.
|
|
684
|
-
Person.eager(:posts=>{:replies=>[:person, {:tags=>
|
|
708
|
+
Person.eager(:posts=>{:replies=>[:person, {:tags=>[:posts, :replies]}]}).all
|
|
709
|
+
|
|
710
|
+
In addition to using +eager+, you can also use +eager_graph+, which will use a single query to get the object and all associated objects. This may be necessary if you want to filter or order the result set based on columns in associated tables. It works with cascading as well, the API is very similar. Note that using +eager_graph+ to eagerly load multiple <tt>*_to_many</tt> associations will cause the result set to be a cartesian product, so you should be very careful with your filters when using it in that case.
|
|
711
|
+
|
|
712
|
+
You can dynamically customize the eagerly loaded dataset by using using a proc. This proc is passed the dataset used for eager loading, and should return a modified copy of that dataset:
|
|
713
|
+
|
|
714
|
+
# Eagerly load only replies containing 'foo'
|
|
715
|
+
Post.eager(:replies=>proc{|ds| ds.where(Sequel.like(text, '%foo%'))}).all
|
|
716
|
+
|
|
717
|
+
This also works when using +eager_graph+, in which case the proc is called with dataset to graph into the current dataset:
|
|
685
718
|
|
|
686
|
-
|
|
719
|
+
Post.eager_graph(:replies=>proc{|ds| ds.where(Sequel.like(text, '%foo%'))}).all
|
|
720
|
+
|
|
721
|
+
You can dynamically customize eager loads for both +eager+ and +eager_graph+ while also cascading, by making the value a single entry hash with the proc as a key, and the cascaded associations as the value:
|
|
722
|
+
|
|
723
|
+
# Eagerly load only replies containing 'foo', and the person and tags for those replies
|
|
724
|
+
Post.eager(:replies=>{proc{|ds| ds.where(Sequel.like(text, '%foo%'))}=>[:person, :tags]}).all
|
|
687
725
|
|
|
688
726
|
=== Extending the underlying dataset
|
|
689
727
|
|
|
@@ -691,7 +729,7 @@ The obvious way to add table-wide logic is to define class methods to the model
|
|
|
691
729
|
|
|
692
730
|
class Post < Sequel::Model
|
|
693
731
|
def self.posts_with_few_comments
|
|
694
|
-
|
|
732
|
+
where{num_comments < 30}
|
|
695
733
|
end
|
|
696
734
|
|
|
697
735
|
def self.clean_posts_with_few_comments
|
|
@@ -699,27 +737,29 @@ The obvious way to add table-wide logic is to define class methods to the model
|
|
|
699
737
|
end
|
|
700
738
|
end
|
|
701
739
|
|
|
702
|
-
You can also implement table-wide logic by defining methods on the dataset using +
|
|
740
|
+
You can also implement table-wide logic by defining methods on the dataset using +dataset_module+:
|
|
703
741
|
|
|
704
742
|
class Post < Sequel::Model
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
743
|
+
dataset_module do
|
|
744
|
+
def posts_with_few_comments
|
|
745
|
+
where{num_comments < 30}
|
|
746
|
+
end
|
|
747
|
+
|
|
748
|
+
def clean_posts_with_few_comments
|
|
749
|
+
posts_with_few_comments.delete
|
|
750
|
+
end
|
|
711
751
|
end
|
|
712
752
|
end
|
|
713
753
|
|
|
714
754
|
This is the recommended way of implementing table-wide operations, and allows you to have access to your model API from filtered datasets as well:
|
|
715
755
|
|
|
716
|
-
Post.
|
|
756
|
+
Post.where(:category => 'ruby').clean_posts_with_few_comments
|
|
717
757
|
|
|
718
758
|
Sequel models also provide a +subset+ class method that creates a dataset method with a simple filter:
|
|
719
759
|
|
|
720
760
|
class Post < Sequel::Model
|
|
721
761
|
subset(:posts_with_few_comments){num_comments < 30}
|
|
722
|
-
subset :invisible,
|
|
762
|
+
subset :invisible, Sequel.~(:visible)
|
|
723
763
|
end
|
|
724
764
|
|
|
725
765
|
=== Model Validations
|
data/Rakefile
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
require "rake"
|
|
2
2
|
require "rake/clean"
|
|
3
|
-
require "rake/gempackagetask"
|
|
4
|
-
begin
|
|
5
|
-
require "hanna/rdoctask"
|
|
6
|
-
rescue LoadError
|
|
7
|
-
require "rake/rdoctask"
|
|
8
|
-
end
|
|
9
3
|
|
|
10
4
|
NAME = 'sequel'
|
|
11
5
|
VERS = lambda do
|
|
@@ -13,34 +7,47 @@ VERS = lambda do
|
|
|
13
7
|
Sequel.version
|
|
14
8
|
end
|
|
15
9
|
CLEAN.include ["**/.*.sw?", "sequel-*.gem", ".config", "rdoc", "coverage", "www/public/*.html", "www/public/rdoc*", '**/*.rbc']
|
|
16
|
-
|
|
17
|
-
RDOC_OPTS = RDOC_DEFAULT_OPTS + ['--main', 'README.rdoc']
|
|
10
|
+
SUDO = ENV['SUDO'] || 'sudo'
|
|
18
11
|
|
|
19
12
|
# Gem Packaging and Release
|
|
20
13
|
|
|
21
14
|
desc "Packages sequel"
|
|
22
15
|
task :package=>[:clean] do |p|
|
|
23
|
-
|
|
16
|
+
load './sequel.gemspec'
|
|
17
|
+
Gem::Builder.new(SEQUEL_GEMSPEC).build
|
|
24
18
|
end
|
|
25
19
|
|
|
26
20
|
desc "Install sequel gem"
|
|
27
21
|
task :install=>[:package] do
|
|
28
|
-
sh %{
|
|
22
|
+
sh %{#{SUDO} gem install ./#{NAME}-#{VERS.call} --local}
|
|
29
23
|
end
|
|
30
24
|
|
|
31
25
|
desc "Uninstall sequel gem"
|
|
32
26
|
task :uninstall=>[:clean] do
|
|
33
|
-
sh %{
|
|
27
|
+
sh %{#{SUDO} gem uninstall #{NAME}}
|
|
34
28
|
end
|
|
35
29
|
|
|
36
30
|
desc "Upload sequel gem to gemcutter"
|
|
37
31
|
task :release=>[:package] do
|
|
38
|
-
sh %{gem push ./#{NAME}-#{VERS.call}.gem}
|
|
32
|
+
sh %{gem push ./#{NAME}-#{VERS.call}.gem}
|
|
39
33
|
end
|
|
40
34
|
|
|
41
35
|
### RDoc
|
|
42
36
|
|
|
43
|
-
|
|
37
|
+
RDOC_DEFAULT_OPTS = ["--quiet", "--line-numbers", "--inline-source", '--title', 'Sequel: The Database Toolkit for Ruby']
|
|
38
|
+
|
|
39
|
+
rdoc_task_class = begin
|
|
40
|
+
require "rdoc/task"
|
|
41
|
+
RDOC_DEFAULT_OPTS.concat(['-f', 'hanna'])
|
|
42
|
+
RDoc::Task
|
|
43
|
+
rescue LoadError
|
|
44
|
+
require "rake/rdoctask"
|
|
45
|
+
Rake::RDocTask
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
RDOC_OPTS = RDOC_DEFAULT_OPTS + ['--main', 'README.rdoc']
|
|
49
|
+
|
|
50
|
+
rdoc_task_class.new do |rdoc|
|
|
44
51
|
rdoc.rdoc_dir = "rdoc"
|
|
45
52
|
rdoc.options += RDOC_OPTS
|
|
46
53
|
rdoc.rdoc_files.add %w"README.rdoc CHANGELOG MIT-LICENSE lib/**/*.rb doc/*.rdoc doc/release_notes/*.txt"
|
|
@@ -50,25 +57,25 @@ end
|
|
|
50
57
|
|
|
51
58
|
desc "Make local version of website"
|
|
52
59
|
task :website do
|
|
53
|
-
sh %{www/make_www.rb}
|
|
60
|
+
sh %{#{FileUtils::RUBY} www/make_www.rb}
|
|
54
61
|
end
|
|
55
62
|
|
|
56
63
|
desc "Make rdoc for website"
|
|
57
64
|
task :website_rdoc=>[:website_rdoc_main, :website_rdoc_adapters, :website_rdoc_plugins]
|
|
58
65
|
|
|
59
|
-
|
|
66
|
+
rdoc_task_class.new(:website_rdoc_main) do |rdoc|
|
|
60
67
|
rdoc.rdoc_dir = "www/public/rdoc"
|
|
61
68
|
rdoc.options += RDOC_OPTS
|
|
62
69
|
rdoc.rdoc_files.add %w"README.rdoc CHANGELOG MIT-LICENSE lib/*.rb lib/sequel/*.rb lib/sequel/{connection_pool,dataset,database,model}/*.rb doc/*.rdoc doc/release_notes/*.txt lib/sequel/extensions/migration.rb"
|
|
63
70
|
end
|
|
64
71
|
|
|
65
|
-
|
|
72
|
+
rdoc_task_class.new(:website_rdoc_adapters) do |rdoc|
|
|
66
73
|
rdoc.rdoc_dir = "www/public/rdoc-adapters"
|
|
67
74
|
rdoc.options += RDOC_DEFAULT_OPTS + %w'--main Sequel'
|
|
68
75
|
rdoc.rdoc_files.add %w"lib/sequel/adapters/**/*.rb"
|
|
69
76
|
end
|
|
70
77
|
|
|
71
|
-
|
|
78
|
+
rdoc_task_class.new(:website_rdoc_plugins) do |rdoc|
|
|
72
79
|
rdoc.rdoc_dir = "www/public/rdoc-plugins"
|
|
73
80
|
rdoc.options += RDOC_DEFAULT_OPTS + %w'--main Sequel'
|
|
74
81
|
rdoc.rdoc_files.add %w"lib/sequel/{extensions,plugins}/**/*.rb"
|
|
@@ -92,11 +99,13 @@ begin
|
|
|
92
99
|
require "spec/rake/spectask"
|
|
93
100
|
spec_class = Spec::Rake::SpecTask
|
|
94
101
|
spec_files_meth = :spec_files=
|
|
102
|
+
spec_opts_meth = :spec_opts=
|
|
95
103
|
rescue LoadError
|
|
96
104
|
# RSpec 2
|
|
97
105
|
require "rspec/core/rake_task"
|
|
98
106
|
spec_class = RSpec::Core::RakeTask
|
|
99
107
|
spec_files_meth = :pattern=
|
|
108
|
+
spec_opts_meth = :rspec_opts=
|
|
100
109
|
end
|
|
101
110
|
|
|
102
111
|
spec = lambda do |name, files, d|
|
|
@@ -105,26 +114,49 @@ begin
|
|
|
105
114
|
desc d
|
|
106
115
|
spec_class.new(name) do |t|
|
|
107
116
|
t.send spec_files_meth, files
|
|
108
|
-
t.
|
|
117
|
+
t.send spec_opts_meth, ENV['SEQUEL_SPEC_OPTS'].split if ENV['SEQUEL_SPEC_OPTS']
|
|
109
118
|
end
|
|
110
119
|
end
|
|
111
120
|
|
|
112
|
-
spec_with_cov = lambda do |name, files, d|
|
|
121
|
+
spec_with_cov = lambda do |name, files, d, &b|
|
|
113
122
|
spec.call(name, files, d)
|
|
114
123
|
t = spec.call("#{name}_cov", files, "#{d} with coverage")
|
|
115
124
|
t.rcov = true
|
|
116
125
|
t.rcov_opts = File.read("spec/rcov.opts").split("\n")
|
|
126
|
+
b.call(t) if b
|
|
127
|
+
t
|
|
117
128
|
end
|
|
118
|
-
|
|
129
|
+
|
|
119
130
|
task :default => [:spec]
|
|
120
|
-
spec_with_cov.call("spec", Dir["spec/{core,model}/*_spec.rb"], "Run core and model specs")
|
|
131
|
+
spec_with_cov.call("spec", Dir["spec/{core,model}/*_spec.rb"], "Run core and model specs"){|t| t.rcov_opts.concat(%w'--exclude "lib/sequel/(adapters/([a-ln-z]|m[a-np-z])|extensions/core_extensions)"')}
|
|
121
132
|
spec.call("spec_core", Dir["spec/core/*_spec.rb"], "Run core specs")
|
|
122
133
|
spec.call("spec_model", Dir["spec/model/*_spec.rb"], "Run model specs")
|
|
123
|
-
|
|
134
|
+
spec.call("_spec_model_no_assoc", Dir["spec/model/*_spec.rb"].delete_if{|f| f =~ /association|eager_loading/}, '')
|
|
135
|
+
spec_with_cov.call("spec_core_ext", ["spec/core_extensions_spec.rb"], "Run core extensions specs"){|t| t.rcov_opts.concat(%w'--exclude "lib/sequel/([a-z_]+\.rb|adapters|connection_pool|database|dataset|model)"')}
|
|
136
|
+
spec_with_cov.call("spec_plugin", Dir["spec/extensions/*_spec.rb"], "Run extension/plugin specs"){|t| t.rcov_opts.concat(%w'--exclude "lib/sequel/([a-z_]+\.rb|adapters|connection_pool|database|dataset|model)"')}
|
|
124
137
|
spec_with_cov.call("spec_integration", Dir["spec/integration/*_test.rb"], "Run integration tests")
|
|
125
|
-
|
|
126
|
-
%w'postgres sqlite mysql informix oracle firebird mssql'.each do |adapter|
|
|
127
|
-
spec_with_cov.call("spec_#{adapter}", ["spec/adapters/#{adapter}_spec.rb"] + Dir["spec/integration/*_test.rb"], "Run #{adapter} specs")
|
|
138
|
+
|
|
139
|
+
%w'postgres sqlite mysql informix oracle firebird mssql db2'.each do |adapter|
|
|
140
|
+
spec_with_cov.call("spec_#{adapter}", ["spec/adapters/#{adapter}_spec.rb"] + Dir["spec/integration/*_test.rb"], "Run #{adapter} specs"){|t| t.rcov_opts.concat(%w'--exclude "lib/sequel/([a-z_]+\.rb|connection_pool|database|dataset|model|extensions|plugins)"')}
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
task :spec_travis=>[:spec, :spec_plugin, :spec_core_ext, :spec_sqlite] do
|
|
144
|
+
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
|
145
|
+
ENV['SEQUEL_PG_SPEC_DB'] = "jdbc:postgresql://localhost/sequel_test?user=postgres"
|
|
146
|
+
ENV['SEQUEL_MY_SPEC_DB'] = "jdbc:mysql://localhost/sequel_test?user=root"
|
|
147
|
+
else
|
|
148
|
+
ENV['SEQUEL_PG_SPEC_DB'] = "postgres://localhost/sequel_test?user=postgres"
|
|
149
|
+
ENV['SEQUEL_MY_SPEC_DB'] = "mysql2://localhost/sequel_test?user=root"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
Rake::Task['spec_postgres'].invoke
|
|
153
|
+
Rake::Task['spec_mysql'].invoke
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
desc "Run model specs without the associations code"
|
|
157
|
+
task :spec_model_no_assoc do
|
|
158
|
+
ENV['SEQUEL_NO_ASSOCIATIONS'] = '1'
|
|
159
|
+
Rake::Task['_spec_model_no_assoc'].invoke
|
|
128
160
|
end
|
|
129
161
|
rescue LoadError
|
|
130
162
|
task :default do
|
|
@@ -142,7 +174,7 @@ end
|
|
|
142
174
|
desc "Report code statistics (KLOCs, etc) from the application"
|
|
143
175
|
task :stats do
|
|
144
176
|
STATS_DIRECTORIES = [%w(Code lib/), %w(Spec spec)].map{|name, dir| [ name, "./#{dir}" ] }.select { |name, dir| File.directory?(dir)}
|
|
145
|
-
require "extra/stats"
|
|
177
|
+
require "./extra/stats"
|
|
146
178
|
verbose = true
|
|
147
179
|
CodeStatistics.new(*STATS_DIRECTORIES).to_s
|
|
148
180
|
end
|
|
@@ -154,5 +186,5 @@ end
|
|
|
154
186
|
|
|
155
187
|
desc "Check syntax of all .rb files"
|
|
156
188
|
task :check_syntax do
|
|
157
|
-
Dir['**/*.rb'].each{|file| print `#{
|
|
189
|
+
Dir['**/*.rb'].each{|file| print `#{FileUtils::RUBY} -c #{file} | fgrep -v "Syntax OK"`}
|
|
158
190
|
end
|