sequel-rails 0.6.1 → 0.7.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f72c17bd6336f3beaf4c924f50df1c3c5f465e26
4
- data.tar.gz: 68c754a39afbf03af0beada56cd545c38167d59f
3
+ metadata.gz: 1f76a96adfae8ea0e88a9309033960f3257abc59
4
+ data.tar.gz: ee00b69625771c517e4b0c9d595420fac941b62b
5
5
  SHA512:
6
- metadata.gz: ba99ffdebabe0e37b4d17c4de59a00bc0fba5475505d7ddd5998570fb45652f1e2f93c4597b356a798c94e1b3a174d50ac6cf7181ae506ae6d56a699b49a1449
7
- data.tar.gz: 46740f777f70160dd7d8ffa6158557280c0677dabe0b2eae00dc7631b33b3780da148d759c9f554b0b2d9bfa90fbe56f5f07d2796f6c74a4e946f6f1bef84346
6
+ metadata.gz: 1d988bf8488b10141f59786d78902694cb3f3bc44eaeffcdb09afc885f343b731b7d1faf36f070daa38d0628900e21687726c5f4b477aaf023a21d1ae9b85ec9
7
+ data.tar.gz: 96fc1e85b462e0d74ba7389f33c7aafe1ed94bd0d9fbbf4eeeb997ce6bb26ec22b25c94c6e99f6f50d19bd36dd77d8ac2bfeb28b680e943ece1ff8d76fdd4b7c
data/Gemfile CHANGED
@@ -3,6 +3,7 @@ source "http://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  gem "fakefs", :require => "fakefs/safe"
6
+ gem "pry"
6
7
 
7
8
  # MRI/Rubinius Adapter Dependencies
8
9
  platform :ruby do
data/History.md CHANGED
@@ -1,3 +1,17 @@
1
+ 0.7.0 (2013-10-11)
2
+ ==================
3
+
4
+ * Add more information in the README, related to features of SequelRails [#54](https://github.com/TalentBox/sequel-rails/issues/54)
5
+ * Refactor storage shell command construction/execution/escaping [#55](https://github.com/TalentBox/sequel-rails/issues/55)
6
+ * Handle more options from database.yml for PostgreSQL when creating/dropping/loading/dumping database [#55](https://github.com/TalentBox/sequel-rails/issues/55)
7
+ * Allow dumping the schema even if there aren't any migrations to run. (Kevin Menard) [#53](https://github.com/TalentBox/sequel-rails/pull/53)
8
+ * Fix Postgres rake tasks under JRuby (Kevin Menard, Chris Heisterkamp) [#52](https://github.com/TalentBox/sequel-rails/pull/52) [#38](https://github.com/TalentBox/sequel-rails/pull/38)
9
+ * Fix SQL schema dumps using timestamp migration (Joshua Hansen) [#50](https://github.com/TalentBox/sequel-rails/pull/50)
10
+ * Apply all migrations in the schema.rb file when loading it (Robert Payne) [#49](https://github.com/TalentBox/sequel-rails/pull/49)
11
+ * Make dump_schema_information compatible with integer based migration (Robert Payne) [#48](https://github.com/TalentBox/sequel-rails/pull/48) [#47](https://github.com/TalentBox/sequel-rails/issues/47)
12
+ * Add an `after_connect` hook (Jan Berdajs) [#46](https://github.com/TalentBox/sequel-rails/pull/46)
13
+ * Update license dates and add license to gemspec [#45](https://github.com/TalentBox/sequel-rails/issues/45)
14
+
1
15
  0.6.1 (2013-09-16)
2
16
  ==================
3
17
 
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009-2010 The sequel-rails team
1
+ Copyright (c) 2009-2013 The sequel-rails team
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -4,18 +4,27 @@ sequel-rails
4
4
  [![Build Status](https://travis-ci.org/TalentBox/sequel-rails.png?branch=master)](https://travis-ci.org/TalentBox/sequel-rails)
5
5
  [![Code Climate](https://codeclimate.com/github/TalentBox/sequel-rails.png)](https://codeclimate.com/github/TalentBox/sequel-rails)
6
6
 
7
- This gem provides the railtie that allows [sequel](http://github.com/jeremyevans/sequel) to hook into [rails3](http://github.com/rails/rails) and thus behave like a rails framework component. Just like activerecord does in rails, [sequel-rails](http://github.com/talentbox/sequel-rails) uses the railtie API to hook into rails. The two are actually hooked into rails almost identically.
7
+ This gem provides the railtie that allows
8
+ [sequel](http://github.com/jeremyevans/sequel) to hook into
9
+ [Rails (3.x and 4.x)](http://github.com/rails/rails) and thus behave like a
10
+ rails framework component. Just like activerecord does in rails,
11
+ [sequel-rails](http://github.com/talentbox/sequel-rails) uses the railtie API to
12
+ hook into rails. The two are actually hooked into rails almost identically.
8
13
 
9
- The code for this gem was initially taken from the excellent [dm-rails](http://github.com/datamapper/dm-rails) project.
14
+ The code for this gem was initially taken from the excellent
15
+ [dm-rails](http://github.com/datamapper/dm-rails) project.
10
16
 
11
- This was originally a fork of [brasten](https://github.com/brasten)'s [sequel-rails](https://github.com/brasten/sequel-rails) that has been updated to support newer versions of rails.
17
+ This was originally a fork of [brasten](https://github.com/brasten)'s
18
+ [sequel-rails](https://github.com/brasten/sequel-rails) that has been updated to
19
+ support newer versions of rails.
12
20
 
13
- Since January 2013, we've became the official maintainers of the gem after [brasten](https://github.com/brasten) proposed us.
21
+ Since January 2013, we've became the official maintainers of the gem after
22
+ [brasten](https://github.com/brasten) proposed us.
14
23
 
15
24
  Using sequel-rails
16
25
  ==================
17
26
 
18
- Using sequel with rails3 requires a couple minor changes.
27
+ Using sequel with Rails (3.x or 4.x) requires a couple minor changes.
19
28
 
20
29
  First, add the following to your Gemfile (after the `Rails` lines):
21
30
 
@@ -30,7 +39,9 @@ gem "sequel-rails"
30
39
 
31
40
  ... be sure to run "bundle install" if needed!
32
41
 
33
- Secondly, you'll need to require the different Rails components separately in your `config/application.rb` file, and not require `ActiveRecord`. The top of your `config/application.rb` will probably look something like:
42
+ Secondly, you'll need to require the different Rails components separately in
43
+ your `config/application.rb` file, and not require `ActiveRecord`.
44
+ The top of your `config/application.rb` will probably look something like:
34
45
 
35
46
  ```ruby
36
47
  # require 'rails/all'
@@ -44,7 +55,8 @@ require "sprockets/railtie"
44
55
 
45
56
  Starting with sequel-rails 0.4.0.pre3 we don't change default Sequel behaviour
46
57
  nor include any plugin by default, if you want to get back the previous
47
- behaviour, you can create a new initializer (eg: `config/initializers/sequel.rb`) with content:
58
+ behaviour, you can create a new initializer (eg: `config/initializers/sequel.rb`)
59
+ with content:
48
60
 
49
61
  ```ruby
50
62
  require "sequel_rails/railties/legacy_model_config"
@@ -52,8 +64,62 @@ require "sequel_rails/railties/legacy_model_config"
52
64
 
53
65
  After those changes, you should be good to go!
54
66
 
67
+ Features provided by `sequel-rails`
68
+ ===================================
69
+
70
+ 1. Connection management:
71
+
72
+ `sequel-rails` will initiate the `Sequel` connection mechanism based on your
73
+ configuration in `database.yml`.
74
+
75
+ 2. Generators:
76
+
77
+ You can use them just like `ActiveRecord`'s ones:
78
+
79
+ Migration:
80
+
81
+ ```ruby
82
+ rails generate migration create_admin_users
83
+ # Or
84
+ rails generate migration CreateAdminUsers
85
+ ```
86
+
87
+ Model:
88
+
89
+ ```ruby
90
+ rails generate model User email:string
91
+ ```
92
+
93
+ Observer:
94
+
95
+ ```ruby
96
+ rails generate observer User
97
+ ```
98
+
99
+ 3. Rake tasks similar to `ActiveRecord`, see
100
+ [Available sequel specific rake tasks](#available-sequel-specific-rake-tasks)
101
+
102
+ 4. Add some `Sequel` and `sequel-rails` specific exceptions to `ActionDispatch`'s `rescue_responses`
103
+
104
+ `Sequel::Plugins::RailsExtensions::ModelNotFound` is mapped to `:not_found`
105
+
106
+ `Sequel::NoMatchingRow` is mapped to `:not_found`
107
+
108
+ `Sequel::ValidationFailed` is mapped to `:unprocessable_entity`
109
+
110
+ `Sequel::NoExistingObject` is mapped to `:unprocessable_entity`
111
+
112
+ 5. Add a `i18n_scope` method to `Sequel::Model` which respond with `"sequel"`.
113
+ This is used by `ActiveModel`.
114
+
115
+ 6. Adding `Sequel` to `ActiveSupport::LogSubscriber`. This is what allows you to
116
+ see SQL queries in the log and also allows us to implement the next item.
117
+
118
+ 7. Add a hook in `ActionController::Base` so that the sum of SQL queries time
119
+ for the current action is reported as `DB` for the controller's line in logs.
120
+
55
121
  Configuration
56
- ====================================
122
+ =============
57
123
  You can configure some options with the usual rails mechanism, in
58
124
  `config/application.rb` and/or in `config/environments/*.rb`.
59
125
 
@@ -74,6 +140,78 @@ You can configure some options with the usual rails mechanism, in
74
140
  config.sequel.load_database_tasks = false
75
141
  ```
76
142
 
143
+ The connection settings are read from the file `config/database.yml` and is
144
+ expected to be similar to `ActiveRecord`'s format.
145
+
146
+ Here's some examples:
147
+
148
+ 1. For PostgreSQL:
149
+
150
+ ```yaml
151
+ development:
152
+ adapter: postgresql
153
+ database: a_database_name
154
+ user: user_name # Also accept 'username' as key, if both are present 'username' is used
155
+ password: password
156
+ host: 10.0.0.2 # Optional
157
+ port: 5432 # Optional
158
+ owner: owner_name # Optional
159
+ encoding: utf8 # Optional, also accept 'charset' as key, if both are present 'encoding' is used (defaults to 'utf8')
160
+ maintenance_db: template2 # Optional
161
+ locale: en_US.UTF-8 # Optional, equivalent to setting 'collation' and 'ctype' to the same value
162
+ collation: en_US.UTF-8 # Optional
163
+ ctype: en_US.UTF-8 # Optional
164
+ template: template1 # Optional
165
+ tablespace: non_default_tablespace_name # Optional
166
+ ```
167
+
168
+ 2. For MySQL:
169
+
170
+ ```yaml
171
+ development:
172
+ adapter: mysql # Also accept mysql2
173
+ database: a_database_name
174
+ user: user_name # Also accept 'username' as key, if both are present 'username' is used
175
+ password: password
176
+ host: 10.0.0.2 # Optional
177
+ port: 5432 # Optional
178
+ charset: latin1 # Optional (defaults to 'utf8')
179
+ collation: latin1_general_ci # Optional (defaults to 'utf8_unicode_ci')
180
+ ```
181
+
182
+ 2. For SQLite:
183
+
184
+ ```yaml
185
+ development:
186
+ adapter: sqlite # Also accept sqlite3
187
+ database: db/mydatabase.sqlite # Path to db relative to Rails root
188
+ ```
189
+
190
+ For in memory testing:
191
+
192
+ ```yaml
193
+ development:
194
+ adapter: sqlite # Also accept sqlite3
195
+ database: ":memory:"
196
+ ```
197
+
198
+ Enabling plugins
199
+ ================
200
+
201
+ If you want to enable plugins for all your models, you should use the
202
+ after_connect configuration option in `config/application.rb` (0.6.2+):
203
+
204
+ ```ruby
205
+ config.sequel.after_connect = proc do
206
+ Sequel::Model.plugin :timestamps, update_on_create: true
207
+ end
208
+ ```
209
+
210
+ This will ensure that these plugins are loaded before any Sequel models are
211
+ loaded. Loading plugins into `Sequel::Model` after subclasses are already
212
+ created is not supported by Sequel. You can also load extensions in
213
+ `after_connect` or perform any custom actions that you need.
214
+
77
215
  Available sequel specific rake tasks
78
216
  ====================================
79
217
 
@@ -153,6 +291,10 @@ Improvements has been made by those awesome contributors:
153
291
  * Saulius Grigaliunas (sauliusg)
154
292
  * Jacques Crocker (railsjedi)
155
293
  * Eric Strathmeyer (strathmeyer)
294
+ * Jan Berdajs (mrbrdo)
295
+ * Robert Payne (robertjpayne)
296
+ * Kevin Menard (nirvdrum)
297
+ * Chris Heisterkamp (cheister)
156
298
 
157
299
  Credits
158
300
  =======
@@ -5,12 +5,7 @@ module SequelRails
5
5
  mattr_accessor :configuration
6
6
 
7
7
  def self.setup(environment)
8
- config = configuration.environment_for(environment.to_s)
9
- if config['url']
10
- ::Sequel.connect config['url'], config
11
- else
12
- ::Sequel.connect config
13
- end
8
+ configuration.connect environment
14
9
  end
15
10
 
16
11
  class Configuration < ActiveSupport::OrderedOptions
@@ -32,6 +27,7 @@ module SequelRails
32
27
  self.migration_dir = nil
33
28
  self.schema_dump = default_schema_dump
34
29
  self.load_database_tasks = true
30
+ self.after_connect = nil
35
31
  end
36
32
 
37
33
  def environment_for(name)
@@ -46,6 +42,17 @@ module SequelRails
46
42
  end
47
43
  end
48
44
 
45
+ def connect(environment)
46
+ normalized_config = environment_for environment
47
+ db = if normalized_config['url']
48
+ ::Sequel.connect normalized_config['url'], normalized_config
49
+ else
50
+ ::Sequel.connect normalized_config
51
+ end
52
+ after_connect.call if after_connect.respond_to?(:call)
53
+ db
54
+ end
55
+
49
56
  private
50
57
 
51
58
  def default_schema_dump
@@ -6,34 +6,46 @@ module SequelRails
6
6
  def migrate(version=nil)
7
7
  opts = {}
8
8
  opts[:target] = version.to_i if version
9
- ::Sequel::Migrator.run(::Sequel::Model.db, Rails.root.join("db/migrate"), opts)
9
+ ::Sequel::Migrator.run(::Sequel::Model.db, migrations_dir, opts)
10
10
  end
11
11
  alias_method :migrate_up!, :migrate
12
12
  alias_method :migrate_down!, :migrate
13
13
 
14
14
  def pending_migrations?
15
- return false unless File.exists?(Rails.root.join("db/migrate"))
16
- !::Sequel::Migrator.is_current?(::Sequel::Model.db, Rails.root.join("db/migrate"))
15
+ return false unless available_migrations?
16
+ !::Sequel::Migrator.is_current?(::Sequel::Model.db, migrations_dir)
17
17
  end
18
18
 
19
19
  def dump_schema_information(opts={})
20
20
  sql = opts.fetch :sql
21
21
  db = ::Sequel::Model.db
22
- migrator = ::Sequel::TimestampMigrator.new db, "db/migrate"
22
+ res = ""
23
23
 
24
- inserts = migrator.applied_migrations.map do |migration_name|
25
- insert = migrator.ds.insert_sql(migrator.column => migration_name)
26
- sql ? insert : " self << #{insert.inspect}"
27
- end
24
+ if available_migrations?
25
+ migrator_class = ::Sequel::Migrator.send(:migrator_class, migrations_dir)
26
+ migrator = migrator_class.new db, migrations_dir
28
27
 
29
- res = ""
30
- if inserts.any?
31
- res << "Sequel.migration do\n change do\n" unless sql
32
- res << inserts.join("\n")
33
- res << "\n end\nend\n" unless sql
28
+ inserts = migrator.ds.map do |hash|
29
+ insert = migrator.ds.insert_sql(hash)
30
+ sql ? "#{insert};" : " self << #{insert.inspect}"
31
+ end
32
+
33
+ if inserts.any?
34
+ res << "Sequel.migration do\n change do\n" unless sql
35
+ res << inserts.join("\n")
36
+ res << "\n end\nend\n" unless sql
37
+ end
34
38
  end
35
39
  res
36
40
  end
41
+
42
+ def migrations_dir
43
+ Rails.root.join("db/migrate")
44
+ end
45
+
46
+ def available_migrations?
47
+ File.exists?(migrations_dir) && Dir[File.join(migrations_dir, '*')].any?
48
+ end
37
49
  end
38
50
  end
39
51
  end
@@ -33,7 +33,7 @@ namespace :db do
33
33
  if File.exists?(file)
34
34
  require 'sequel/extensions/migration'
35
35
  load(file)
36
- ::Sequel::Migration.descendants.first.apply(db_for_current_env, :up)
36
+ ::Sequel::Migration.descendants.each{|m| m.apply(db_for_current_env, :up)}
37
37
  else
38
38
  abort %{#{file} doesn't exist yet. Run "rake db:migrate" to create it then try again. If you do not intend to use a database, you should instead alter #{Rails.root}/config/boot.rb to limit the frameworks that will be loaded}
39
39
  end
@@ -0,0 +1,33 @@
1
+ module SequelRails
2
+ begin
3
+ require "shellwords"
4
+ Shellwords = ::Shellwords
5
+ rescue LoadError
6
+ # Taken from shellwords.rb (Ruby 2.0.0p247)
7
+ class Shellwords
8
+ def self.shellescape(str)
9
+ str = str.to_s
10
+
11
+ # An empty argument will be skipped, so return empty quotes.
12
+ return "''" if str.empty?
13
+
14
+ str = str.dup
15
+
16
+ # Treat multibyte characters as is. It is caller's responsibility
17
+ # to encode the string in the right encoding for the shell
18
+ # environment.
19
+ str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/, "\\\\\\1")
20
+
21
+ # A LF cannot be escaped with a backslash because a backslash + LF
22
+ # combo is regarded as line continuation and simply ignored.
23
+ str.gsub!(/\n/, "'\n'")
24
+
25
+ return str
26
+ end
27
+
28
+ def self.shelljoin(array)
29
+ array.map { |arg| shellescape(arg) }.join(' ')
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,3 +1,4 @@
1
+ require "sequel_rails/shellwords"
1
2
  require "sequel_rails/storage/abstract"
2
3
  require "sequel_rails/storage/sqlite"
3
4
  require "sequel_rails/storage/mysql"
@@ -39,31 +39,59 @@ module SequelRails
39
39
  end
40
40
 
41
41
  def database
42
- @database ||= config['database'] || config['path']
42
+ @database ||= config["database"] || config["path"]
43
43
  end
44
44
 
45
45
  def username
46
- @username ||= config['username'] || config['user'] || ''
46
+ @username ||= config["username"] || config["user"] || ""
47
47
  end
48
48
 
49
49
  def password
50
- @password ||= config['password'] || ''
50
+ @password ||= config["password"] || ""
51
51
  end
52
52
 
53
53
  def host
54
- @host ||= config['host'] || ''
54
+ @host ||= config["host"] || ""
55
55
  end
56
56
 
57
57
  def port
58
- @port ||= config['port'] || ''
58
+ @port ||= config["port"] || ""
59
59
  end
60
60
 
61
61
  def owner
62
- @owner ||= config['owner'] || ''
62
+ @owner ||= config["owner"] || ""
63
63
  end
64
64
 
65
65
  def charset
66
- @charset ||= config['charset'] || ENV['CHARSET'] || 'utf8'
66
+ @charset ||= config["charset"] || ENV["CHARSET"] || "utf8"
67
+ end
68
+
69
+ def collation
70
+ @collation ||= config["collation"] || ENV["COLLATION"]
71
+ end
72
+
73
+ private
74
+
75
+ def add_option(commands, name, value)
76
+ if value.present?
77
+ separator = name[0,2]=="--" ? "=" : " "
78
+ commands << "#{name}#{separator}#{value}"
79
+ end
80
+ end
81
+
82
+ def add_flag(commands, flag)
83
+ commands << flag
84
+ end
85
+
86
+ def exec(escaped_command)
87
+ `#{escaped_command}`
88
+
89
+ # Evaluate command status as a boolean like `system` does.
90
+ $?.exitstatus == 0
91
+ end
92
+
93
+ def safe_exec(args)
94
+ exec SequelRails::Shellwords.join(Array(args))
67
95
  end
68
96
 
69
97
  end