sequel 5.83.1 → 5.85.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/sequel/adapters/shared/sqlite.rb +3 -1
- data/lib/sequel/connection_pool.rb +2 -2
- data/lib/sequel/database/schema_methods.rb +2 -0
- data/lib/sequel/dataset/actions.rb +9 -1
- data/lib/sequel/extensions/dataset_run.rb +41 -0
- data/lib/sequel/extensions/pg_json_ops.rb +642 -9
- data/lib/sequel/sql.rb +8 -5
- data/lib/sequel/version.rb +2 -2
- metadata +4 -237
- data/CHANGELOG +0 -1397
- data/README.rdoc +0 -936
- data/doc/advanced_associations.rdoc +0 -884
- data/doc/association_basics.rdoc +0 -1859
- data/doc/bin_sequel.rdoc +0 -146
- data/doc/cheat_sheet.rdoc +0 -255
- data/doc/code_order.rdoc +0 -104
- data/doc/core_extensions.rdoc +0 -405
- data/doc/dataset_basics.rdoc +0 -96
- data/doc/dataset_filtering.rdoc +0 -222
- data/doc/extensions.rdoc +0 -77
- data/doc/fork_safety.rdoc +0 -84
- data/doc/mass_assignment.rdoc +0 -98
- data/doc/migration.rdoc +0 -660
- data/doc/model_dataset_method_design.rdoc +0 -129
- data/doc/model_hooks.rdoc +0 -254
- data/doc/model_plugins.rdoc +0 -270
- data/doc/mssql_stored_procedures.rdoc +0 -43
- data/doc/object_model.rdoc +0 -563
- data/doc/opening_databases.rdoc +0 -439
- data/doc/postgresql.rdoc +0 -611
- data/doc/prepared_statements.rdoc +0 -144
- data/doc/querying.rdoc +0 -1070
- data/doc/reflection.rdoc +0 -120
- data/doc/release_notes/5.0.0.txt +0 -159
- data/doc/release_notes/5.1.0.txt +0 -31
- data/doc/release_notes/5.10.0.txt +0 -84
- data/doc/release_notes/5.11.0.txt +0 -83
- data/doc/release_notes/5.12.0.txt +0 -141
- data/doc/release_notes/5.13.0.txt +0 -27
- data/doc/release_notes/5.14.0.txt +0 -63
- data/doc/release_notes/5.15.0.txt +0 -39
- data/doc/release_notes/5.16.0.txt +0 -110
- data/doc/release_notes/5.17.0.txt +0 -31
- data/doc/release_notes/5.18.0.txt +0 -69
- data/doc/release_notes/5.19.0.txt +0 -28
- data/doc/release_notes/5.2.0.txt +0 -33
- data/doc/release_notes/5.20.0.txt +0 -89
- data/doc/release_notes/5.21.0.txt +0 -87
- data/doc/release_notes/5.22.0.txt +0 -48
- data/doc/release_notes/5.23.0.txt +0 -56
- data/doc/release_notes/5.24.0.txt +0 -56
- data/doc/release_notes/5.25.0.txt +0 -32
- data/doc/release_notes/5.26.0.txt +0 -35
- data/doc/release_notes/5.27.0.txt +0 -21
- data/doc/release_notes/5.28.0.txt +0 -16
- data/doc/release_notes/5.29.0.txt +0 -22
- data/doc/release_notes/5.3.0.txt +0 -121
- data/doc/release_notes/5.30.0.txt +0 -20
- data/doc/release_notes/5.31.0.txt +0 -148
- data/doc/release_notes/5.32.0.txt +0 -46
- data/doc/release_notes/5.33.0.txt +0 -24
- data/doc/release_notes/5.34.0.txt +0 -40
- data/doc/release_notes/5.35.0.txt +0 -56
- data/doc/release_notes/5.36.0.txt +0 -60
- data/doc/release_notes/5.37.0.txt +0 -30
- data/doc/release_notes/5.38.0.txt +0 -28
- data/doc/release_notes/5.39.0.txt +0 -19
- data/doc/release_notes/5.4.0.txt +0 -80
- data/doc/release_notes/5.40.0.txt +0 -40
- data/doc/release_notes/5.41.0.txt +0 -25
- data/doc/release_notes/5.42.0.txt +0 -136
- data/doc/release_notes/5.43.0.txt +0 -98
- data/doc/release_notes/5.44.0.txt +0 -32
- data/doc/release_notes/5.45.0.txt +0 -34
- data/doc/release_notes/5.46.0.txt +0 -87
- data/doc/release_notes/5.47.0.txt +0 -59
- data/doc/release_notes/5.48.0.txt +0 -14
- data/doc/release_notes/5.49.0.txt +0 -59
- data/doc/release_notes/5.5.0.txt +0 -61
- data/doc/release_notes/5.50.0.txt +0 -78
- data/doc/release_notes/5.51.0.txt +0 -47
- data/doc/release_notes/5.52.0.txt +0 -87
- data/doc/release_notes/5.53.0.txt +0 -23
- data/doc/release_notes/5.54.0.txt +0 -27
- data/doc/release_notes/5.55.0.txt +0 -21
- data/doc/release_notes/5.56.0.txt +0 -51
- data/doc/release_notes/5.57.0.txt +0 -23
- data/doc/release_notes/5.58.0.txt +0 -31
- data/doc/release_notes/5.59.0.txt +0 -73
- data/doc/release_notes/5.6.0.txt +0 -31
- data/doc/release_notes/5.60.0.txt +0 -22
- data/doc/release_notes/5.61.0.txt +0 -43
- data/doc/release_notes/5.62.0.txt +0 -132
- data/doc/release_notes/5.63.0.txt +0 -33
- data/doc/release_notes/5.64.0.txt +0 -50
- data/doc/release_notes/5.65.0.txt +0 -21
- data/doc/release_notes/5.66.0.txt +0 -24
- data/doc/release_notes/5.67.0.txt +0 -32
- data/doc/release_notes/5.68.0.txt +0 -61
- data/doc/release_notes/5.69.0.txt +0 -26
- data/doc/release_notes/5.7.0.txt +0 -108
- data/doc/release_notes/5.70.0.txt +0 -35
- data/doc/release_notes/5.71.0.txt +0 -21
- data/doc/release_notes/5.72.0.txt +0 -33
- data/doc/release_notes/5.73.0.txt +0 -66
- data/doc/release_notes/5.74.0.txt +0 -45
- data/doc/release_notes/5.75.0.txt +0 -35
- data/doc/release_notes/5.76.0.txt +0 -86
- data/doc/release_notes/5.77.0.txt +0 -63
- data/doc/release_notes/5.78.0.txt +0 -67
- data/doc/release_notes/5.79.0.txt +0 -28
- data/doc/release_notes/5.8.0.txt +0 -170
- data/doc/release_notes/5.80.0.txt +0 -40
- data/doc/release_notes/5.81.0.txt +0 -31
- data/doc/release_notes/5.82.0.txt +0 -61
- data/doc/release_notes/5.83.0.txt +0 -56
- data/doc/release_notes/5.9.0.txt +0 -99
- data/doc/schema_modification.rdoc +0 -679
- data/doc/security.rdoc +0 -443
- data/doc/sharding.rdoc +0 -286
- data/doc/sql.rdoc +0 -648
- data/doc/testing.rdoc +0 -204
- data/doc/thread_safety.rdoc +0 -15
- data/doc/transactions.rdoc +0 -250
- data/doc/validations.rdoc +0 -558
- data/doc/virtual_rows.rdoc +0 -265
data/doc/bin_sequel.rdoc
DELETED
@@ -1,146 +0,0 @@
|
|
1
|
-
= bin/sequel
|
2
|
-
|
3
|
-
bin/sequel is the name used to refer to the "sequel" command line tool that ships with the sequel gem. By default, bin/sequel provides an IRB shell with the +DB+ constant set to a Sequel::Database object created using the database connection string provided on the command line. For example, to connect to a new in-memory SQLite database using the sqlite adapter, you can use the following:
|
4
|
-
|
5
|
-
sequel sqlite:/
|
6
|
-
|
7
|
-
This is very useful for quick testing of ideas, and does not affect the environment, since the in-memory SQLite database is destroyed when the program exits.
|
8
|
-
|
9
|
-
== Running from a git checkout
|
10
|
-
|
11
|
-
If you've installed the sequel gem, then just running "sequel" should load the program, since rubygems should place the sequel binary in your load path. However, if you want to run bin/sequel from the root of a repository checkout, you should probably do:
|
12
|
-
|
13
|
-
ruby bin/sequel
|
14
|
-
|
15
|
-
== Choosing the Database to Connect to
|
16
|
-
|
17
|
-
=== Connection String
|
18
|
-
|
19
|
-
In general, you probably want to provide a connection string argument to bin/sequel, indicating the adapter and database connection information you want to use. For example:
|
20
|
-
|
21
|
-
sequel sqlite:/
|
22
|
-
sequel postgres://user:pass@host/database_name
|
23
|
-
sequel mysql2://user:pass@host/database_name
|
24
|
-
|
25
|
-
See the {Connecting to a database guide}[rdoc-ref:doc/opening_databases.rdoc] for more details about and examples of connection strings.
|
26
|
-
|
27
|
-
=== YAML Connection File
|
28
|
-
|
29
|
-
Instead of specifying the database connection using a connection string, you can provide the path to a YAML configuration file containing the connection information. This YAML file can contain a single options hash, or it can contain a nested hash, where the top-level hash uses environment keys with hash values for
|
30
|
-
each environment. Using the -e option with a yaml connection file, you can choose which environment to use if using a nested hash.
|
31
|
-
|
32
|
-
sequel -e production config/database.yml
|
33
|
-
|
34
|
-
Note that bin/sequel does not directly support ActiveRecord YAML configuration files, as they use different names for some options.
|
35
|
-
|
36
|
-
=== Mock Connection
|
37
|
-
|
38
|
-
If you don't provide a connection string or YAML connection file, Sequel will start with a mock database. The mock database allows you to play around with Sequel without any database at all, and can be useful if you just want to test things out and generate SQL without actually getting results from a database.
|
39
|
-
|
40
|
-
sequel
|
41
|
-
|
42
|
-
Sequel also has the ability to use the mock adapter with database-specific syntax, allowing you to pretend you are connecting to a specific type of database without actually connecting to one. To do that, you need to use a connection string:
|
43
|
-
|
44
|
-
sequel mock://postgres
|
45
|
-
|
46
|
-
== Not Just an IRB shell
|
47
|
-
|
48
|
-
bin/sequel is not just an IRB shell, it can also do far more.
|
49
|
-
|
50
|
-
=== Execute Code
|
51
|
-
|
52
|
-
bin/sequel can also be used to execute other ruby files with +DB+ preset to the database given on the command line:
|
53
|
-
|
54
|
-
sequel postgres://host/database_name path/to/some_file.rb
|
55
|
-
|
56
|
-
On modern versions of Linux, this means that you can use bin/sequel in a shebang line:
|
57
|
-
|
58
|
-
#!/path/to/bin/sequel postgres://host/database_name
|
59
|
-
|
60
|
-
If you want to quickly execute a small piece of ruby code, you can use the -c option:
|
61
|
-
|
62
|
-
sequel -c "p DB.tables" postgres://host/database_name
|
63
|
-
|
64
|
-
Similarly, if data is piped into bin/sequel, it will be executed:
|
65
|
-
|
66
|
-
echo "p DB.tables" | sequel postgres://host/database_name
|
67
|
-
|
68
|
-
=== Migrate Databases
|
69
|
-
|
70
|
-
With -m option, Sequel will migrate the database given using the migration directory provided by -m:
|
71
|
-
|
72
|
-
sequel -m /path/to/migrations/dir postgres://host/database
|
73
|
-
|
74
|
-
You can use the -M attribute to set the version to migrate to:
|
75
|
-
|
76
|
-
sequel -m /path/to/migrations/dir -M 3 postgres://host/database
|
77
|
-
|
78
|
-
See the {migration guide}[rdoc-ref:doc/migration.rdoc] for more details about migrations.
|
79
|
-
|
80
|
-
=== Dump Schemas
|
81
|
-
|
82
|
-
Using the -d or -D options, Sequel will dump the database's schema in Sequel migration format to the standard output:
|
83
|
-
|
84
|
-
sequel -d postgres://host/database
|
85
|
-
|
86
|
-
To save this information to a file, use a standard shell redirection:
|
87
|
-
|
88
|
-
sequel -d postgres://host/database > /path/to/migrations/dir/001_base_schema.rb
|
89
|
-
|
90
|
-
The -d option dumps the migration in database-independent format, the -D option dumps it in database-specific format.
|
91
|
-
|
92
|
-
Note that the support for dumping schema is fairly limited. It doesn't handle database views, functions, triggers, schemas, partial indexes, functional indexes, and many other things. You should probably use the database specific tools to handle those.
|
93
|
-
|
94
|
-
The -S option dumps the schema cache for all tables in the database, which can speed up the usage of Sequel with models when using the schema_caching extension. You should provide this option with the path to which to dump the schema:
|
95
|
-
|
96
|
-
sequel -S /path/to/schema_cache.db postgres://host/database
|
97
|
-
|
98
|
-
=== Copy Databases
|
99
|
-
|
100
|
-
Using the -C option, Sequel can copy the contents of one database to another, even between different database types. Using this option, you provide two connection strings on the command line:
|
101
|
-
|
102
|
-
sequel -C mysql://host1/database postgres://host2/database2
|
103
|
-
|
104
|
-
This copies the table structure, table data, indexes, and foreign keys from the MySQL database to the PostgreSQL database.
|
105
|
-
|
106
|
-
Note that the support for copying is fairly limited. It doesn't handle database views, functions, triggers, schemas, partial indexes, functional indexes, and many other things. Also, the data type conversion may not be exactly what you want. It is best designed for quick conversions and testing. For serious production use, use the database's tools to copy databases for the same database type, and for different database types, use the Sequel API.
|
107
|
-
|
108
|
-
== Other Options
|
109
|
-
|
110
|
-
Other options not mentioned above are explained briefly here.
|
111
|
-
|
112
|
-
=== -E
|
113
|
-
|
114
|
-
-E logs all SQL queries to the standard output, so you can see all SQL that Sequel is sending the database.
|
115
|
-
|
116
|
-
=== -I include_directory
|
117
|
-
|
118
|
-
-I is similar to ruby -I, and specifies an additional $LOAD_PATH directory.
|
119
|
-
|
120
|
-
=== -l log_file
|
121
|
-
|
122
|
-
-l is similar to -E, but logs all SQL queries to the given file.
|
123
|
-
|
124
|
-
=== -L load_directory
|
125
|
-
|
126
|
-
-L loads all *.rb files under the given directory. This is usually used to load Sequel::Model classes into bin/sequel.
|
127
|
-
|
128
|
-
=== -N
|
129
|
-
|
130
|
-
-N skips testing the connection when creating the Database object. This is rarely needed.
|
131
|
-
|
132
|
-
=== -r require_lib
|
133
|
-
|
134
|
-
-r is similar to ruby -r, requiring the given library.
|
135
|
-
|
136
|
-
=== -t
|
137
|
-
|
138
|
-
-t tells bin/sequel to output full backtraces in the case of an error, which can aid in debugging.
|
139
|
-
|
140
|
-
=== -h
|
141
|
-
|
142
|
-
-h prints the usage information for bin/sequel.
|
143
|
-
|
144
|
-
=== -v
|
145
|
-
|
146
|
-
-v prints the Sequel version in use.
|
data/doc/cheat_sheet.rdoc
DELETED
@@ -1,255 +0,0 @@
|
|
1
|
-
= Cheat Sheet
|
2
|
-
|
3
|
-
== Open a database
|
4
|
-
|
5
|
-
require 'sequel'
|
6
|
-
|
7
|
-
DB = Sequel.sqlite('my_blog.db')
|
8
|
-
DB = Sequel.connect('postgres://user:password@localhost/my_db')
|
9
|
-
DB = Sequel.postgres('my_db', user: 'user', password: 'password', host: 'localhost')
|
10
|
-
DB = Sequel.ado('mydb')
|
11
|
-
|
12
|
-
== Open an SQLite memory database
|
13
|
-
|
14
|
-
Without a filename argument, the sqlite adapter will setup a new sqlite database in memory.
|
15
|
-
|
16
|
-
DB = Sequel.sqlite
|
17
|
-
|
18
|
-
== Logging SQL statements
|
19
|
-
|
20
|
-
require 'logger'
|
21
|
-
DB = Sequel.sqlite(loggers: [Logger.new($stdout)])
|
22
|
-
# or
|
23
|
-
DB.loggers << Logger.new($stdout)
|
24
|
-
|
25
|
-
== Using raw SQL
|
26
|
-
|
27
|
-
DB.run "CREATE TABLE users (name VARCHAR(255) NOT NULL, age INT(3) NOT NULL)"
|
28
|
-
dataset = DB["SELECT age FROM users WHERE name = ?", name]
|
29
|
-
dataset.map(:age)
|
30
|
-
DB.fetch("SELECT name FROM users") do |row|
|
31
|
-
p row[:name]
|
32
|
-
end
|
33
|
-
|
34
|
-
== Create a dataset
|
35
|
-
|
36
|
-
dataset = DB[:items]
|
37
|
-
dataset = DB.from(:items)
|
38
|
-
|
39
|
-
== Most dataset methods are chainable
|
40
|
-
|
41
|
-
dataset = DB[:managers].where(salary: 5000..10000).order(:name, :department)
|
42
|
-
|
43
|
-
== Insert rows
|
44
|
-
|
45
|
-
dataset.insert(name: 'Sharon', grade: 50)
|
46
|
-
|
47
|
-
== Retrieve rows
|
48
|
-
|
49
|
-
dataset.each{|r| p r}
|
50
|
-
dataset.all # => [{...}, {...}, ...]
|
51
|
-
dataset.first # => {...}
|
52
|
-
dataset.last # => {...}
|
53
|
-
|
54
|
-
== Update/Delete rows
|
55
|
-
|
56
|
-
dataset.exclude(:active).delete
|
57
|
-
dataset.where{price < 100}.update(active: true)
|
58
|
-
dataset.where(:active).update(price: Sequel[:price] * 0.90)
|
59
|
-
|
60
|
-
= Merge rows
|
61
|
-
|
62
|
-
dataset.
|
63
|
-
merge_using(:table, col1: :col2).
|
64
|
-
merge_insert(col3: :col4).
|
65
|
-
merge_delete{col5 > 30}.
|
66
|
-
merge_update(col3: Sequel[:col3] + :col4)
|
67
|
-
|
68
|
-
== Datasets are Enumerable
|
69
|
-
|
70
|
-
dataset.map{|r| r[:name]}
|
71
|
-
dataset.map(:name) # same as above
|
72
|
-
|
73
|
-
dataset.inject(0){|sum, r| sum + r[:value]}
|
74
|
-
dataset.sum(:value) # better
|
75
|
-
|
76
|
-
== Filtering (see also {Dataset Filtering}[rdoc-ref:doc/dataset_filtering.rdoc])
|
77
|
-
|
78
|
-
=== Equality
|
79
|
-
|
80
|
-
dataset.where(name: 'abc')
|
81
|
-
|
82
|
-
=== Inequality
|
83
|
-
|
84
|
-
dataset.where{value > 100}
|
85
|
-
dataset.exclude{value <= 100}
|
86
|
-
|
87
|
-
=== Inclusion
|
88
|
-
|
89
|
-
dataset.where(value: 50..100)
|
90
|
-
dataset.where{(value >= 50) & (value <= 100)}
|
91
|
-
|
92
|
-
dataset.where(value: [50,75,100])
|
93
|
-
dataset.where(id: other_dataset.select(:other_id))
|
94
|
-
|
95
|
-
=== Subselects as scalar values
|
96
|
-
|
97
|
-
dataset.where{price > dataset.select(avg(price) + 100)}
|
98
|
-
|
99
|
-
=== LIKE/Regexp
|
100
|
-
|
101
|
-
DB[:items].where(Sequel.like(:name, 'AL%'))
|
102
|
-
DB[:items].where(name: /^AL/)
|
103
|
-
|
104
|
-
=== AND/OR/NOT
|
105
|
-
|
106
|
-
DB[:items].where{(x > 5) & (y > 10)}
|
107
|
-
# SELECT * FROM items WHERE ((x > 5) AND (y > 10))
|
108
|
-
|
109
|
-
DB[:items].where(Sequel.or(x: 1, y: 2) & Sequel.~(z: 3))
|
110
|
-
# SELECT * FROM items WHERE (((x = 1) OR (y = 2)) AND (z != 3))
|
111
|
-
|
112
|
-
=== Mathematical operators
|
113
|
-
|
114
|
-
DB[:items].where{x + y > z}
|
115
|
-
# SELECT * FROM items WHERE ((x + y) > z)
|
116
|
-
|
117
|
-
DB[:items].where{price - 100 < avg(price)}
|
118
|
-
# SELECT * FROM items WHERE ((price - 100) < avg(price))
|
119
|
-
|
120
|
-
=== Raw SQL Fragments
|
121
|
-
|
122
|
-
dataset.where(Sequel.lit('id= 1'))
|
123
|
-
dataset.where(Sequel.lit('name = ?', 'abc'))
|
124
|
-
dataset.where(Sequel.lit('value IN ?', [50,75,100]))
|
125
|
-
dataset.where(Sequel.lit('price > (SELECT avg(price) + 100 FROM table)'))
|
126
|
-
|
127
|
-
== Ordering
|
128
|
-
|
129
|
-
dataset.order(:kind) # kind
|
130
|
-
dataset.reverse(:kind) # kind DESC
|
131
|
-
dataset.order(Sequel.desc(:kind), :name) # kind DESC, name
|
132
|
-
|
133
|
-
== Limit/Offset
|
134
|
-
|
135
|
-
dataset.limit(30) # LIMIT 30
|
136
|
-
dataset.limit(30, 10) # LIMIT 30 OFFSET 10
|
137
|
-
dataset.limit(30).offset(10) # LIMIT 30 OFFSET 10
|
138
|
-
|
139
|
-
== Joins
|
140
|
-
|
141
|
-
DB[:items].left_outer_join(:categories, id: :category_id)
|
142
|
-
# SELECT * FROM items
|
143
|
-
# LEFT OUTER JOIN categories ON categories.id = items.category_id
|
144
|
-
|
145
|
-
DB[:items].join(:categories, id: :category_id).
|
146
|
-
join(:groups, id: Sequel[:items][:group_id])
|
147
|
-
# SELECT * FROM items
|
148
|
-
# INNER JOIN categories ON categories.id = items.category_id
|
149
|
-
# INNER JOIN groups ON groups.id = items.group_id
|
150
|
-
|
151
|
-
== Aggregate functions methods
|
152
|
-
|
153
|
-
dataset.count #=> record count
|
154
|
-
dataset.max(:price)
|
155
|
-
dataset.min(:price)
|
156
|
-
dataset.avg(:price)
|
157
|
-
dataset.sum(:stock)
|
158
|
-
|
159
|
-
dataset.group_and_count(:category).all
|
160
|
-
dataset.select_group(:category).select_append{avg(:price)}
|
161
|
-
|
162
|
-
== SQL Functions / Literals
|
163
|
-
|
164
|
-
dataset.update(updated_at: Sequel.function(:NOW))
|
165
|
-
dataset.update(updated_at: Sequel.lit('NOW()'))
|
166
|
-
|
167
|
-
dataset.update(updated_at: Sequel.lit("DateValue('1/1/2001')"))
|
168
|
-
dataset.update(updated_at: Sequel.function(:DateValue, '1/1/2001'))
|
169
|
-
|
170
|
-
== Schema Manipulation
|
171
|
-
|
172
|
-
DB.create_table :items do
|
173
|
-
primary_key :id
|
174
|
-
String :name, unique: true, null: false
|
175
|
-
TrueClass :active, default: true
|
176
|
-
foreign_key :category_id, :categories
|
177
|
-
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP, index: true
|
178
|
-
|
179
|
-
index [:category_id, :active]
|
180
|
-
end
|
181
|
-
|
182
|
-
DB.drop_table :items
|
183
|
-
|
184
|
-
== Aliasing
|
185
|
-
|
186
|
-
DB[:items].select(Sequel[:name].as(:item_name))
|
187
|
-
DB[:items].select(Sequel.as(:name, :item_name))
|
188
|
-
DB[:items].select{name.as(:item_name)}
|
189
|
-
# SELECT name AS item_name FROM items
|
190
|
-
|
191
|
-
DB[Sequel[:items].as(:items_table)].select{items_table[:name].as(:item_name)}
|
192
|
-
# SELECT items_table.name AS item_name FROM items AS items_table
|
193
|
-
|
194
|
-
== Transactions
|
195
|
-
|
196
|
-
DB.transaction do
|
197
|
-
# BEGIN
|
198
|
-
dataset.insert(first_name: 'Inigo', last_name: 'Montoya')
|
199
|
-
dataset.insert(first_name: 'Farm', last_name: 'Boy')
|
200
|
-
end
|
201
|
-
# COMMIT
|
202
|
-
|
203
|
-
|
204
|
-
Transactions are reentrant:
|
205
|
-
|
206
|
-
DB.transaction do
|
207
|
-
# BEGIN
|
208
|
-
DB.transaction do
|
209
|
-
dataset.insert(first_name: 'Inigo', last_name: 'Montoya')
|
210
|
-
end
|
211
|
-
end
|
212
|
-
# COMMIT
|
213
|
-
|
214
|
-
Transactions are aborted if an error is raised:
|
215
|
-
|
216
|
-
DB.transaction do
|
217
|
-
# BEGIN
|
218
|
-
raise "some error occurred"
|
219
|
-
end
|
220
|
-
# ROLLBACK issued and the error is re-raised
|
221
|
-
|
222
|
-
Transactions can also be aborted by raising Sequel::Rollback:
|
223
|
-
|
224
|
-
DB.transaction do
|
225
|
-
# BEGIN
|
226
|
-
raise(Sequel::Rollback)
|
227
|
-
end
|
228
|
-
# ROLLBACK issued and no error raised
|
229
|
-
|
230
|
-
Savepoints can be used if the database supports it:
|
231
|
-
|
232
|
-
DB.transaction do
|
233
|
-
dataset.insert(first_name: 'Farm', last_name: 'Boy') # Inserted
|
234
|
-
DB.transaction(savepoint: true) do # This savepoint is rolled back
|
235
|
-
dataset.insert(first_name: 'Inigo', last_name: 'Montoya') # Not inserted
|
236
|
-
raise(Sequel::Rollback)
|
237
|
-
end
|
238
|
-
dataset.insert(first_name: 'Prince', last_name: 'Humperdink') # Inserted
|
239
|
-
end
|
240
|
-
|
241
|
-
== Retrieving SQL
|
242
|
-
|
243
|
-
dataset.sql # "SELECT * FROM items"
|
244
|
-
dataset.insert_sql(a: 1) # "INSERT INTO items (a) VALUES (1)"
|
245
|
-
dataset.update_sql(a: 1) # "UPDATE items SET a = 1"
|
246
|
-
dataset.delete_sql # "DELETE FROM items"
|
247
|
-
|
248
|
-
== Basic introspection
|
249
|
-
|
250
|
-
dataset.columns # => [:id, :name, ...]
|
251
|
-
DB.tables # => [:items, ...]
|
252
|
-
DB.views # => [:new_items, ...]
|
253
|
-
DB.schema(:items) # => [[:id, {:type=>:integer, ...}], [:name, {:type=>:string, ...}], ...]
|
254
|
-
DB.indexes(:items) # => {:index_name => {:columns=>[:a], :unique=>false}, ...}
|
255
|
-
DB.foreign_key_list(:items) # => [{:name=>:items_a_fk, :columns=>[:a], :key=>[:id], :table=>:other_table}, ...]
|
data/doc/code_order.rdoc
DELETED
@@ -1,104 +0,0 @@
|
|
1
|
-
= Code Order
|
2
|
-
|
3
|
-
In Sequel, the order in which code is executed during initialization is important. This
|
4
|
-
guide provides the recommended way to order your Sequel code. Some
|
5
|
-
of these guidelines are not strictly necessary, but others are, and
|
6
|
-
this guide will be specific about which are strictly necessary.
|
7
|
-
|
8
|
-
== Require Sequel
|
9
|
-
|
10
|
-
This is sort of a no-brainer, but you need to require the library
|
11
|
-
first. This is a strict requirement, none of the other code can
|
12
|
-
be executed unless the library has been required first. Example:
|
13
|
-
|
14
|
-
require 'sequel'
|
15
|
-
|
16
|
-
== Add Global Extensions
|
17
|
-
|
18
|
-
Global extensions are loaded with Sequel.extension, and affect
|
19
|
-
other parts of Sequel or the general ruby environment. It's not
|
20
|
-
necessary to load them first, but it is a recommended practice.
|
21
|
-
Example:
|
22
|
-
|
23
|
-
Sequel.extension :blank
|
24
|
-
|
25
|
-
== Add Extensions Applied to All Databases/Datasets
|
26
|
-
|
27
|
-
If you want database or datasets extensions applied to all databases
|
28
|
-
and datasets, you must use Sequel::Database.extension to load the
|
29
|
-
extension before connecting to a database. If you connect to a
|
30
|
-
database before using Sequel::Database.extension, it will not have
|
31
|
-
that extension loaded. Example:
|
32
|
-
|
33
|
-
Sequel::Database.extension :columns_introspection
|
34
|
-
|
35
|
-
== Connect to Databases
|
36
|
-
|
37
|
-
Connecting to a database is required before running any queries against
|
38
|
-
that database, or creating any datasets or models. You cannot create
|
39
|
-
model classes without having a database object created first. The
|
40
|
-
convention for an application with a single Database instance is to
|
41
|
-
store that instance in a constant named DB. Example:
|
42
|
-
|
43
|
-
DB = Sequel.connect('postgres://user:pass@host/database')
|
44
|
-
|
45
|
-
== Add Extensions Specific to a Database or All Datasets in that Database
|
46
|
-
|
47
|
-
If you want specific databases to use specific extensions, or have all
|
48
|
-
datasets in that database use a specific extension, you need to load that
|
49
|
-
extension into the database after creating it using
|
50
|
-
Sequel::Database#extension. Example:
|
51
|
-
|
52
|
-
DB.extension :pg_array
|
53
|
-
|
54
|
-
== Configure Global Model Behavior
|
55
|
-
|
56
|
-
If you want to change the configuration for all model classes, you must do
|
57
|
-
so before loading your model classes, as configuration is copied into the
|
58
|
-
subclass when model subclasses are created. Example:
|
59
|
-
|
60
|
-
Sequel::Model.raise_on_save_failure = false
|
61
|
-
|
62
|
-
== Add Global Model Plugins
|
63
|
-
|
64
|
-
If you want to load a plugin into all models classes, you must do so
|
65
|
-
before loading your model classes, as plugin specific data may need to be
|
66
|
-
copied into the subclass when model subclasses are created. Example:
|
67
|
-
|
68
|
-
Sequel::Model.plugin :prepared_statements
|
69
|
-
|
70
|
-
== Load Model Classes
|
71
|
-
|
72
|
-
After you have established a database connection, and configured your
|
73
|
-
global model configuration and global plugins, you can load your model
|
74
|
-
classes. It's recommended to have a separate file for each model class,
|
75
|
-
unless the model classes are very simple. Example:
|
76
|
-
|
77
|
-
Dir['./models/*.rb'].each{|f| require f}
|
78
|
-
|
79
|
-
== Finalize Associations and Freeze Model Classes and Database
|
80
|
-
|
81
|
-
After all the models have been setup, you can finalize the associations.
|
82
|
-
This can speed up association reflection methods by doing a lookup in
|
83
|
-
advance to find the associated class, and cache related association
|
84
|
-
information in the association itself.
|
85
|
-
|
86
|
-
Additionally, in production and testing, you should freeze the
|
87
|
-
model classes and Database instance, so that you can detect
|
88
|
-
unsafe runtime modification of the configuration:
|
89
|
-
|
90
|
-
model_classes.each(&:finalize_associations)
|
91
|
-
model_classes.each(&:freeze)
|
92
|
-
DB.freeze
|
93
|
-
|
94
|
-
`model_classes` is not a Sequel method, it indicates an array of model
|
95
|
-
classes you defined. Instead of listing them manually, the `subclasses`
|
96
|
-
plugin can be used to keep track of all model classes that have been
|
97
|
-
setup in your application. Finalizing their associations and freezing
|
98
|
-
them can easily be achieved through the plugin:
|
99
|
-
|
100
|
-
# Register the plugin before setting up the models
|
101
|
-
Sequel::Model.plugin :subclasses
|
102
|
-
# ... setup models
|
103
|
-
# Now finalize associations & freeze models by calling the plugin:
|
104
|
-
Sequel::Model.freeze_descendents
|