sequel-rails 0.1.8 → 0.4.0.pre
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/.gitignore +1 -0
- data/.rspec +3 -0
- data/.travis.yml +12 -0
- data/Gemfile +13 -16
- data/History.md +142 -0
- data/README.md +124 -0
- data/Rakefile +6 -30
- data/config.ru +7 -0
- data/lib/generators/sequel.rb +11 -8
- data/lib/generators/sequel/migration/migration_generator.rb +36 -11
- data/lib/generators/sequel/migration/templates/migration.rb.erb +48 -0
- data/lib/generators/sequel/model/model_generator.rb +8 -2
- data/lib/generators/sequel/model/templates/migration.rb.erb +16 -0
- data/lib/generators/sequel/model/templates/{model.rb → model.rb.erb} +4 -1
- data/lib/generators/sequel/observer/observer_generator.rb +2 -2
- data/lib/generators/sequel/observer/templates/{observer.rb → observer.rb.erb} +0 -0
- data/lib/sequel-rails.rb +1 -1
- data/lib/sequel_rails.rb +2 -0
- data/lib/sequel_rails/configuration.rb +64 -0
- data/lib/sequel_rails/migrations.rb +22 -0
- data/lib/sequel_rails/railtie.rb +94 -0
- data/lib/sequel_rails/railties/controller_runtime.rb +40 -0
- data/lib/sequel_rails/railties/database.rake +175 -0
- data/lib/sequel_rails/railties/i18n_support.rb +10 -0
- data/lib/sequel_rails/railties/log_subscriber.rb +56 -0
- data/lib/sequel_rails/sequel/database/active_support_notification.rb +28 -0
- data/lib/sequel_rails/sequel/plugins/rails_extensions.rb +35 -0
- data/lib/sequel_rails/session_store.rb +80 -0
- data/lib/sequel_rails/storage.rb +58 -0
- data/lib/sequel_rails/storage/abstract.rb +52 -0
- data/lib/sequel_rails/storage/jdbc.rb +45 -0
- data/lib/sequel_rails/storage/mysql.rb +31 -0
- data/lib/sequel_rails/storage/mysql2.rb +6 -0
- data/lib/sequel_rails/storage/postgres.rb +22 -0
- data/lib/sequel_rails/storage/sqlite.rb +26 -0
- data/lib/sequel_rails/version.rb +3 -0
- data/sequel-rails.gemspec +22 -86
- data/spec/internal/app/models/user.rb +2 -0
- data/spec/internal/config/database.yml +7 -0
- data/spec/internal/config/routes.rb +3 -0
- data/spec/internal/db/schema.rb +8 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/lib/generators/sequel/migration_spec.rb +256 -0
- data/spec/lib/sequel_rails/railtie_spec.rb +85 -0
- data/spec/lib/sequel_rails/railties/log_subscriber_spec.rb +29 -0
- data/spec/lib/sequel_rails/storage_spec.rb +108 -0
- data/spec/spec_helper.rb +30 -16
- data/tasks/spec.rake +63 -29
- metadata +194 -142
- data/CHANGELOG +0 -15
- data/README.rdoc +0 -86
- data/VERSION +0 -1
- data/autotest/discover.rb +0 -1
- data/lib/generators/sequel/migration/templates/migration.rb +0 -16
- data/lib/sequel-rails/configuration.rb +0 -61
- data/lib/sequel-rails/migrations.rb +0 -30
- data/lib/sequel-rails/railtie.rb +0 -90
- data/lib/sequel-rails/railties/benchmarking_mixin.rb +0 -23
- data/lib/sequel-rails/railties/controller_runtime.rb +0 -43
- data/lib/sequel-rails/railties/database.rake +0 -148
- data/lib/sequel-rails/railties/i18n_support.rb +0 -12
- data/lib/sequel-rails/railties/log_subscriber.rb +0 -31
- data/lib/sequel-rails/runtime.rb +0 -14
- data/lib/sequel-rails/session_store.rb +0 -82
- data/lib/sequel-rails/setup.rb +0 -19
- data/lib/sequel-rails/storage.rb +0 -210
- data/spec/rcov.opts +0 -6
- data/spec/setup_spec.rb +0 -7
- data/spec/spec.opts +0 -4
- data/tasks/ci.rake +0 -1
- data/tasks/clean.rake +0 -6
- data/tasks/metrics.rake +0 -37
- data/tasks/yard.rake +0 -9
- data/tasks/yardstick.rake +0 -20
@@ -0,0 +1,56 @@
|
|
1
|
+
module SequelRails
|
2
|
+
module Railties
|
3
|
+
|
4
|
+
class LogSubscriber < ActiveSupport::LogSubscriber
|
5
|
+
|
6
|
+
def self.runtime=(value)
|
7
|
+
Thread.current["sequel_sql_runtime"] = value
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.runtime
|
11
|
+
Thread.current["sequel_sql_runtime"] ||= 0
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.reset_runtime
|
15
|
+
rt, self.runtime = runtime, 0
|
16
|
+
rt
|
17
|
+
end
|
18
|
+
|
19
|
+
def sql(event)
|
20
|
+
self.class.runtime += event.duration
|
21
|
+
return unless logger.debug?
|
22
|
+
|
23
|
+
payload = event.payload
|
24
|
+
|
25
|
+
name = '%s (%.1fms)' % [payload[:name], event.duration]
|
26
|
+
sql = payload[:sql].squeeze(' ')
|
27
|
+
binds = nil
|
28
|
+
|
29
|
+
unless (payload[:binds] || []).empty?
|
30
|
+
binds = " " + payload[:binds].map { |col,v|
|
31
|
+
[col.name, v]
|
32
|
+
}.inspect
|
33
|
+
end
|
34
|
+
|
35
|
+
if odd?
|
36
|
+
name = color(name, :cyan, true)
|
37
|
+
sql = color(sql, nil, true)
|
38
|
+
else
|
39
|
+
name = color(name, :magenta, true)
|
40
|
+
end
|
41
|
+
|
42
|
+
debug " #{name} #{sql}#{binds}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def odd?
|
46
|
+
@odd_or_even = !@odd_or_even
|
47
|
+
end
|
48
|
+
|
49
|
+
def logger
|
50
|
+
::SequelRails.configuration.logger
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "sequel/database/logging"
|
2
|
+
require "active_support/notifications"
|
3
|
+
|
4
|
+
module Sequel
|
5
|
+
class Database
|
6
|
+
|
7
|
+
def log_yield(sql, args=nil)
|
8
|
+
sql_for_log = args ? "#{sql}; #{args.inspect}" : sql
|
9
|
+
start = Time.now
|
10
|
+
begin
|
11
|
+
::ActiveSupport::Notifications.instrument(
|
12
|
+
"sql.sequel",
|
13
|
+
sql: sql,
|
14
|
+
name: self.class,
|
15
|
+
binds: args,
|
16
|
+
) do
|
17
|
+
yield
|
18
|
+
end
|
19
|
+
rescue => e
|
20
|
+
log_exception(e, sql_for_log) unless @loggers.empty?
|
21
|
+
raise
|
22
|
+
ensure
|
23
|
+
log_duration(Time.now - start, sql_for_log) unless e || @loggers.empty?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "sequel"
|
2
|
+
|
3
|
+
module Sequel
|
4
|
+
module Plugins
|
5
|
+
# The RailsExtensions plugin adds a single class method to Sequel::Model in
|
6
|
+
# order to make its use in controllers a little more like ActiveRecord's.
|
7
|
+
# The +find!+ method is added which will raise an exception if no object is
|
8
|
+
# found. By adding the following code to a Railtie:
|
9
|
+
#
|
10
|
+
# config.action_dispatch.rescue_responses.merge!(
|
11
|
+
# 'Sequel::Plugins::RailsExtensions::ModelNotFound' => :not_found
|
12
|
+
# )
|
13
|
+
#
|
14
|
+
# Usage:
|
15
|
+
#
|
16
|
+
# # Apply plugin to all models:
|
17
|
+
# Sequel::Model.plugin :rails_extensions
|
18
|
+
#
|
19
|
+
# # Apply plugin to a single model:
|
20
|
+
# Album.plugin :rails_extensions
|
21
|
+
module RailsExtensions
|
22
|
+
class ModelNotFound < Sequel::Error
|
23
|
+
end
|
24
|
+
|
25
|
+
module ClassMethods
|
26
|
+
def find!(args)
|
27
|
+
m = self[args]
|
28
|
+
raise ModelNotFound, "Couldn't find #{self} matching #{args}." unless m
|
29
|
+
m
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require "sequel"
|
2
|
+
|
3
|
+
# Implements Sequel-specific session store.
|
4
|
+
|
5
|
+
module SequelRails
|
6
|
+
|
7
|
+
class SessionStore < ActionDispatch::Session::AbstractStore
|
8
|
+
|
9
|
+
class Session < ::Sequel::Model
|
10
|
+
|
11
|
+
# property :id, Serial
|
12
|
+
# property :session_id, String, :required => true, :unique => true, :unique_index => true
|
13
|
+
# property :data, Object, :required => true, :default => ActiveSupport::Base64.encode64(Marshal.dump({}))
|
14
|
+
# property :updated_at, DateTime, :required => false, :index => true
|
15
|
+
|
16
|
+
class << self
|
17
|
+
|
18
|
+
def auto_migrate!
|
19
|
+
self.db.create_table :sessions do
|
20
|
+
primary_key :id
|
21
|
+
column :session_id, String,
|
22
|
+
:null => false,
|
23
|
+
:unique => true,
|
24
|
+
:index => true
|
25
|
+
|
26
|
+
column :data, :text,
|
27
|
+
:null => false
|
28
|
+
|
29
|
+
column :updated_at, DateTime,
|
30
|
+
:null => true,
|
31
|
+
:index => true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.name
|
38
|
+
'session'
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
SESSION_RECORD_KEY = 'rack.session.record'.freeze
|
44
|
+
|
45
|
+
cattr_accessor :session_class
|
46
|
+
self.session_class = Session
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def get_session(env, sid)
|
51
|
+
sid ||= generate_sid
|
52
|
+
session = find_session(sid)
|
53
|
+
env[SESSION_RECORD_KEY] = session
|
54
|
+
[ sid, session.data ]
|
55
|
+
end
|
56
|
+
|
57
|
+
def set_session(env, sid, session_data)
|
58
|
+
session = get_session_resource(env, sid)
|
59
|
+
session.data = session_data
|
60
|
+
session.updated_at = Time.now if session.dirty?
|
61
|
+
session.save
|
62
|
+
end
|
63
|
+
|
64
|
+
def get_session_resource(env, sid)
|
65
|
+
if env[ENV_SESSION_OPTIONS_KEY][:id].nil?
|
66
|
+
env[SESSION_RECORD_KEY] = find_session(sid)
|
67
|
+
else
|
68
|
+
env[SESSION_RECORD_KEY] ||= find_session(sid)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def find_session(sid)
|
73
|
+
klass = self.class.session_class
|
74
|
+
|
75
|
+
klass.where(:session_id => sid).first || klass.new(:session_id => sid)
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "sequel_rails/storage/abstract"
|
2
|
+
require "sequel_rails/storage/sqlite"
|
3
|
+
require "sequel_rails/storage/mysql"
|
4
|
+
require "sequel_rails/storage/mysql2"
|
5
|
+
require "sequel_rails/storage/postgres"
|
6
|
+
require "sequel_rails/storage/jdbc"
|
7
|
+
|
8
|
+
module SequelRails
|
9
|
+
module Storage
|
10
|
+
def self.create_all
|
11
|
+
with_local_repositories { |config| create_environment(config) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.drop_all
|
15
|
+
with_local_repositories { |config| drop_environment(config) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.create_environment(config)
|
19
|
+
adapter_for(config).create
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.drop_environment(config)
|
23
|
+
adapter_for(config).drop
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.adapter_for(config_or_env)
|
27
|
+
config = if config_or_env.kind_of? Hash
|
28
|
+
config_or_env
|
29
|
+
else
|
30
|
+
::SequelRails.configuration.environments[config_or_env.to_s]
|
31
|
+
end
|
32
|
+
lookup_class(config['adapter']).new config
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def self.with_local_repositories
|
38
|
+
::SequelRails.configuration.environments.each_value do |config|
|
39
|
+
next if config['database'].blank?
|
40
|
+
if config['host'].blank? || %w[ 127.0.0.1 localhost ].include?(config['host'])
|
41
|
+
yield config
|
42
|
+
else
|
43
|
+
puts "This task only modifies local databases. #{config['database']} is on a remote host."
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.lookup_class(adapter)
|
49
|
+
klass_name = adapter.camelize.to_sym
|
50
|
+
|
51
|
+
unless self.const_defined?(klass_name)
|
52
|
+
raise "Adapter #{adapter} not supported (#{klass_name.inspect})"
|
53
|
+
end
|
54
|
+
|
55
|
+
const_get klass_name
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module SequelRails
|
2
|
+
module Storage
|
3
|
+
class Abstract
|
4
|
+
|
5
|
+
attr_reader :config
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
@config = config
|
9
|
+
end
|
10
|
+
|
11
|
+
def create
|
12
|
+
_create
|
13
|
+
puts "[sequel] Created database '#{database}'"
|
14
|
+
end
|
15
|
+
|
16
|
+
def drop
|
17
|
+
::Sequel::Model.db.disconnect
|
18
|
+
_drop
|
19
|
+
puts "[sequel] Dropped database '#{database}'"
|
20
|
+
end
|
21
|
+
|
22
|
+
def database
|
23
|
+
@database ||= config['database'] || config['path']
|
24
|
+
end
|
25
|
+
|
26
|
+
def username
|
27
|
+
@username ||= config['username'] || config['user'] || ''
|
28
|
+
end
|
29
|
+
|
30
|
+
def password
|
31
|
+
@password ||= config['password'] || ''
|
32
|
+
end
|
33
|
+
|
34
|
+
def host
|
35
|
+
@host ||= config['host'] || ''
|
36
|
+
end
|
37
|
+
|
38
|
+
def port
|
39
|
+
@port ||= config['port'] || ''
|
40
|
+
end
|
41
|
+
|
42
|
+
def owner
|
43
|
+
@owner ||= config['owner'] || ''
|
44
|
+
end
|
45
|
+
|
46
|
+
def charset
|
47
|
+
@charset ||= config['charset'] || ENV['CHARSET'] || 'utf8'
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module SequelRails
|
2
|
+
module Storage
|
3
|
+
class Jdbc < Abstract
|
4
|
+
|
5
|
+
def _is_mysql?
|
6
|
+
database.match(/^jdbc:mysql/)
|
7
|
+
end
|
8
|
+
|
9
|
+
def _root_url
|
10
|
+
database.scan(/^jdbc:mysql:\/\/\w*:?\d*/)
|
11
|
+
end
|
12
|
+
|
13
|
+
def db_name
|
14
|
+
database.scan(/^jdbc:mysql:\/\/\w+:?\d*\/(\w+)/).flatten.first
|
15
|
+
end
|
16
|
+
|
17
|
+
def _params
|
18
|
+
database.scan(/\?.*$/)
|
19
|
+
end
|
20
|
+
|
21
|
+
def _create
|
22
|
+
if _is_mysql?
|
23
|
+
::Sequel.connect("#{_root_url}#{_params}") do |db|
|
24
|
+
db.execute("CREATE DATABASE IF NOT EXISTS `#{db_name}` DEFAULT CHARACTER SET #{charset} DEFAULT COLLATE #{collation}")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def _drop
|
30
|
+
if _is_mysql?
|
31
|
+
::Sequel.connect("#{_root_url}#{_params}") do |db|
|
32
|
+
db.execute("DROP DATABASE IF EXISTS `#{db_name}`")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def collation
|
40
|
+
@collation ||= config['collation'] || ENV['COLLATION'] || 'utf8_unicode_ci'
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
|
3
|
+
module SequelRails
|
4
|
+
module Storage
|
5
|
+
class Mysql < Abstract
|
6
|
+
def _create
|
7
|
+
execute("CREATE DATABASE IF NOT EXISTS `#{database}` DEFAULT CHARACTER SET #{charset} DEFAULT COLLATE #{collation}")
|
8
|
+
end
|
9
|
+
|
10
|
+
def _drop
|
11
|
+
execute("DROP DATABASE IF EXISTS `#{database}`")
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def execute(statement)
|
17
|
+
commands = ["mysql"]
|
18
|
+
commands << "--user=#{Shellwords.escape(username)}" unless username.blank?
|
19
|
+
commands << "--password=#{Shellwords.escape(password)}" unless password.blank?
|
20
|
+
commands << "--host=#{host}" unless host.blank?
|
21
|
+
commands << "-e" << statement
|
22
|
+
system(*commands)
|
23
|
+
end
|
24
|
+
|
25
|
+
def collation
|
26
|
+
@collation ||= config['collation'] || ENV['COLLATION'] || 'utf8_unicode_ci'
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module SequelRails
|
2
|
+
module Storage
|
3
|
+
class Postgres < Abstract
|
4
|
+
def _create
|
5
|
+
ENV["PGPASSWORD"] = password unless password.blank?
|
6
|
+
commands = ["createdb", "--encoding", charset]
|
7
|
+
commands << "--username" << username unless username.blank?
|
8
|
+
commands << "--owner" << owner unless owner.blank?
|
9
|
+
commands << "--port" << port unless port.blank?
|
10
|
+
commands << "--host" << host unless host.blank?
|
11
|
+
commands << database
|
12
|
+
res = system(*commands)
|
13
|
+
ENV["PGPASSWORD"] = nil
|
14
|
+
res
|
15
|
+
end
|
16
|
+
|
17
|
+
def _drop
|
18
|
+
system("dropdb", "-U", username, database)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module SequelRails
|
2
|
+
module Storage
|
3
|
+
class Sqlite < Abstract
|
4
|
+
def _create
|
5
|
+
return if in_memory?
|
6
|
+
::Sequel.connect(config.merge('database' => path))
|
7
|
+
end
|
8
|
+
|
9
|
+
def _drop
|
10
|
+
return if in_memory?
|
11
|
+
path.unlink if path.file?
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def in_memory?
|
17
|
+
database == ':memory:'
|
18
|
+
end
|
19
|
+
|
20
|
+
def path
|
21
|
+
@path ||= Pathname(File.expand_path(database, Rails.root))
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|