nulogy-sequel-rails 0.3.8

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.
Files changed (36) hide show
  1. data/.document +5 -0
  2. data/.gitignore +29 -0
  3. data/Gemfile +3 -0
  4. data/History.md +77 -0
  5. data/LICENSE +20 -0
  6. data/README.rdoc +102 -0
  7. data/Rakefile +9 -0
  8. data/lib/rails/generators/sequel/active_model.rb +39 -0
  9. data/lib/rails/generators/sequel/base.rb +26 -0
  10. data/lib/rails/generators/sequel/generated_attribute_ext.rb +9 -0
  11. data/lib/rails/generators/sequel/migration/migration_generator.rb +43 -0
  12. data/lib/rails/generators/sequel/migration/templates/migration.rb +48 -0
  13. data/lib/rails/generators/sequel/model/model_generator.rb +28 -0
  14. data/lib/rails/generators/sequel/model/templates/migration.rb +14 -0
  15. data/lib/rails/generators/sequel/model/templates/model.rb +6 -0
  16. data/lib/rails/generators/sequel/observer/observer_generator.rb +16 -0
  17. data/lib/rails/generators/sequel/observer/templates/observer.rb +4 -0
  18. data/lib/rails/generators/sequel.rb +9 -0
  19. data/lib/sequel/plugins/rails_extensions.rb +25 -0
  20. data/lib/sequel/rails/configuration.rb +56 -0
  21. data/lib/sequel/rails/core.rb +50 -0
  22. data/lib/sequel/rails/ext.rb +25 -0
  23. data/lib/sequel/rails/log_subscriber.rb +71 -0
  24. data/lib/sequel/rails/migrations.rb +22 -0
  25. data/lib/sequel/rails/railtie.rb +76 -0
  26. data/lib/sequel/rails/railties/controller_runtime.rb +48 -0
  27. data/lib/sequel/rails/railties/database.rake +185 -0
  28. data/lib/sequel/rails/railties/i18n_support.rb +9 -0
  29. data/lib/sequel/rails/session_store.rb +69 -0
  30. data/lib/sequel/rails/setup.rb +14 -0
  31. data/lib/sequel/rails/storage.rb +225 -0
  32. data/lib/sequel/rails/version.rb +6 -0
  33. data/lib/sequel/rails.rb +26 -0
  34. data/lib/sequel-rails.rb +2 -0
  35. data/nulogy-sequel-rails.gemspec +19 -0
  36. metadata +101 -0
@@ -0,0 +1,71 @@
1
+
2
+ module Sequel::Rails
3
+ # This is copied straight from ActiveRecord::LogSubscriber
4
+ class LogSubscriber < ActiveSupport::LogSubscriber
5
+ def self.runtime=(value)
6
+ Thread.current["sequel_sql_runtime"] = value
7
+ end
8
+
9
+ def self.runtime
10
+ Thread.current["sequel_sql_runtime"] ||= 0
11
+ end
12
+
13
+ def self.reset_runtime
14
+ rt, self.runtime = runtime, 0
15
+ rt
16
+ end
17
+
18
+ def initialize
19
+ super
20
+ @odd_or_even = false
21
+ end
22
+
23
+ def sql(event)
24
+ self.class.runtime += event.duration
25
+ return unless logger.debug?
26
+
27
+ payload = event.payload
28
+
29
+ return if 'SCHEMA' == payload[:name]
30
+
31
+ name = '%s (%.1fms)' % [payload[:name], event.duration]
32
+ sql = payload[:sql].squeeze(' ')
33
+ binds = nil
34
+
35
+ unless (payload[:binds] || []).empty?
36
+ binds = " " + payload[:binds].map { |col,v|
37
+ [col.name, v]
38
+ }.inspect
39
+ end
40
+
41
+ if odd?
42
+ name = color(name, CYAN, true)
43
+ sql = color(sql, nil, true)
44
+ else
45
+ name = color(name, MAGENTA, true)
46
+ end
47
+
48
+ debug " #{name} #{sql}#{binds}"
49
+ end
50
+
51
+ def identity(event)
52
+ return unless logger.debug?
53
+
54
+ name = color(event.payload[:name], odd? ? CYAN : MAGENTA, true)
55
+ line = odd? ? color(event.payload[:line], nil, true) : event.payload[:line]
56
+
57
+ debug " #{name} #{line}"
58
+ end
59
+
60
+ def odd?
61
+ @odd_or_even = !@odd_or_even
62
+ end
63
+
64
+ def logger
65
+ Sequel::Rails.configuration.logger
66
+ end
67
+ end
68
+ end
69
+
70
+ Sequel::Rails::LogSubscriber.attach_to :sequel
71
+
@@ -0,0 +1,22 @@
1
+
2
+ require 'sequel/extensions/migration'
3
+
4
+ module Sequel
5
+ module Rails
6
+ class Migrations
7
+ class << self
8
+ def migrate_up!(version=nil)
9
+ opts = {}
10
+ opts[:target] = version.to_i if version
11
+ Sequel::Migrator.run(Sequel::Model.db, "db/migrate", opts)
12
+ end
13
+
14
+ def migrate_down!(version=nil)
15
+ opts = {}
16
+ opts[:target] = version.to_i if version
17
+ Sequel::Migrator.run(Sequel::Model.db, "db/migrate", opts)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,76 @@
1
+
2
+ require File.expand_path('../../rails', __FILE__)
3
+
4
+ if not defined?(Rails)
5
+ raise "Rails must be loaded before Sequel::Rails::Railtie is loaded"
6
+ end
7
+ if Rails.version.to_i < 3
8
+ raise "sequel-rails requires Rails >= 3"
9
+ end
10
+
11
+ module Sequel
12
+ module Rails
13
+ require libpath('sequel/rails/railties/i18n_support')
14
+ require libpath('sequel/rails/railties/controller_runtime')
15
+
16
+ class Railtie < ::Rails::Railtie
17
+ config.sequel = Sequel::Rails.configuration
18
+
19
+ Sequel::Rails::LogSubscriber.attach_to :sequel
20
+
21
+ config.app_generators.orm :sequel, :migration => true
22
+
23
+ config.action_dispatch.rescue_responses.merge!(
24
+ # If a record cannot be found within an action (resulting from a call
25
+ # to #find!, which is a method we patch into Sequel::Model), then rescue
26
+ # it as a 404
27
+ 'Sequel::Plugins::RailsExtensions::ModelNotFound' => :not_found,
28
+ # If a record fails validation within an action, rescue it as a 500
29
+ 'Sequel::ValidationFailed' => :unprocessable_entity,
30
+ # If something bad happens, rescue it as a 500
31
+ 'Sequel::NoExistingObject' => :unprocessable_entity
32
+ )
33
+
34
+ rake_tasks do
35
+ load Sequel::Rails.libpath('sequel/rails/railties/database.rake')
36
+ end
37
+
38
+ initializer 'sequel.logger' do |app|
39
+ app.config.sequel.logger ||=
40
+ if defined?(Logging)
41
+ Logging.logger['Sequel']
42
+ else
43
+ ::Rails.logger
44
+ end
45
+ end
46
+
47
+ initializer 'sequel.i18n_support' do |app|
48
+ Sequel::Model.class_eval { include Sequel::Rails::Railties::I18nSupport }
49
+ end
50
+
51
+ # Expose database runtime to controller for logging.
52
+ initializer 'sequel.log_runtime' do |app|
53
+ ActiveSupport.on_load(:action_controller) do
54
+ include Sequel::Rails::Railties::ControllerRuntime
55
+ end
56
+ end
57
+
58
+ initializer 'sequel.connect' do |app|
59
+ Sequel::Rails.configuration.init_database(app.config.database_configuration)
60
+ Sequel::Rails.connect(::Rails.env)
61
+ end
62
+
63
+ # Run setup code after_initialize to make sure all config/initializers
64
+ # are in effect once we setup the connection. This is especially necessary
65
+ # for the cascaded adapter wrappers that need to be declared before setup.
66
+ config.after_initialize do |app|
67
+ Sequel::Model.raise_on_save_failure = false
68
+ Sequel::Model.plugin :active_model
69
+ Sequel::Model.plugin :validation_helpers
70
+ # This is our own plugin
71
+ Sequel::Model.plugin :rails_extensions
72
+ end
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,48 @@
1
+
2
+ require 'active_support/core_ext/module/attr_internal'
3
+
4
+ module Sequel::Rails::Railties
5
+ # This is copied straight from ActiveRecord::Railties::ControllerRuntime
6
+ module ControllerRuntime
7
+ extend ActiveSupport::Concern
8
+
9
+ protected
10
+ attr_internal :db_runtime
11
+
12
+ def process_action(action, *args)
13
+ # We also need to reset the runtime before each action
14
+ # because of queries in middleware or in cases we are streaming
15
+ # and it won't be cleaned up by the method below.
16
+ Sequel::Rails::LogSubscriber.reset_runtime
17
+ super
18
+ end
19
+
20
+ def cleanup_view_runtime
21
+ if Sequel::Rails.connected?
22
+ db_rt_before_render = Sequel::Rails::LogSubscriber.reset_runtime
23
+ runtime = super
24
+ db_rt_after_render = Sequel::Rails::LogSubscriber.reset_runtime
25
+ self.db_runtime = db_rt_before_render + db_rt_after_render
26
+ runtime - db_rt_after_render
27
+ else
28
+ super
29
+ end
30
+ end
31
+
32
+ def append_info_to_payload(payload)
33
+ super
34
+ if Sequel::Rails.connected?
35
+ payload[:db_runtime] = (db_runtime || 0) + Sequel::Rails::LogSubscriber.reset_runtime
36
+ end
37
+ end
38
+
39
+ module ClassMethods
40
+ def log_process_action(payload)
41
+ messages, db_runtime = super, payload[:db_runtime]
42
+ messages << ("Sequel: %.1fms" % db_runtime.to_f) if db_runtime
43
+ messages
44
+ end
45
+ end
46
+ end
47
+ end
48
+
@@ -0,0 +1,185 @@
1
+
2
+ # TODO: DRY these up
3
+ # TODO: Add task to create sessions table
4
+
5
+ ######################################################
6
+ # BEWARE: Regular Expressions of DOOOOOOOOOOOOOOOOOM #
7
+ ######################################################
8
+ namespace :db do
9
+ namespace :schema do
10
+ desc "Create a db/schema.rb file that can be portably used against any DB supported by Sequel"
11
+ task :dump => :environment do
12
+ Sequel.extension :schema_dumper
13
+ db = Sequel::Rails.db
14
+ File.open(ENV['SCHEMA'] || "#{Rails.root}/db/schema.rb", "w") do |file|
15
+ database = db.dump_schema_migration(same_db: true)
16
+ # 0. Add schema_migrations info (mucho importante!)
17
+ filenames = db[:schema_migrations].map{|x| x[:filename]}
18
+ statements = filenames.sort.map do |f|
19
+ "self[:schema_migrations].insert(:filename => \"#{f}\")"
20
+ end
21
+
22
+ inserts = statements.map do |s|
23
+ " #{s}"
24
+ end.join("\n")
25
+
26
+ database.gsub!(/(create_table\(:schema_migrations\) do.+?end)/m, '\1'+"\n\n#{inserts}\n")
27
+
28
+ # 1. Fuck arbitrary whitespaces.
29
+ database.gsub!(/\s+$/,"\n")
30
+
31
+ # 2. Add new line at end of file
32
+ database += "\n"
33
+ file.write database
34
+ end
35
+ Rake::Task["db:schema:dump"].reenable
36
+ end
37
+
38
+ desc "Load a schema.rb file into the database"
39
+ task :load => :environment do
40
+ file = ENV['SCHEMA'] || "#{Rails.root}/db/schema.rb"
41
+ if File.exists?(file)
42
+ require 'sequel/extensions/migration'
43
+ load(file)
44
+ Sequel::Migration.descendants.first.apply(::Sequel::Model.db, :up)
45
+ else
46
+ 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}
47
+ end
48
+ end
49
+ end
50
+
51
+ namespace :create do
52
+ desc 'Create all the local databases defined in config/database.yml'
53
+ task :all => :environment do
54
+ require 'sequel/rails/storage'
55
+ Sequel::Rails::Storage.create_all
56
+ end
57
+ end
58
+
59
+ desc "Create the database defined in config/database.yml for the current Rails.env"
60
+ task :create, [:env] => :environment do |t, args|
61
+ args.with_defaults(:env => Rails.env)
62
+
63
+ require 'sequel/rails/storage'
64
+ Sequel::Rails::Storage.new(args.env).create
65
+ end
66
+
67
+ namespace :drop do
68
+ desc 'Drops all the local databases defined in config/database.yml'
69
+ task :all => :environment do
70
+ require 'sequel/rails/storage'
71
+ Sequel::Rails::Storage.drop_all
72
+ end
73
+ end
74
+
75
+ desc "Create the database defined in config/database.yml for the current Rails.env"
76
+ task :drop, [:env] => :environment do |t, args|
77
+ args.with_defaults(:env => Rails.env)
78
+
79
+ require 'sequel/rails/storage'
80
+ Sequel::Rails::Storage.new(args.env).drop
81
+ end
82
+
83
+ namespace :migrate do
84
+ task :load => :environment do
85
+ require 'sequel/rails/migrations'
86
+ end
87
+
88
+ desc 'Rollbacks the database one migration and re migrate up. If you want to rollback more than one step, define STEP=x. Target specific version with VERSION=x.'
89
+ task :redo => :load do
90
+ if ENV["VERSION"]
91
+ Rake::Task["db:migrate:down"].invoke
92
+ Rake::Task["db:migrate:up"].invoke
93
+ else
94
+ Rake::Task["db:rollback"].invoke
95
+ Rake::Task["db:migrate"].invoke
96
+ end
97
+ end
98
+
99
+
100
+ desc 'Resets your database using your migrations for the current environment'
101
+ task :reset => ["db:drop", "db:create", "db:migrate"]
102
+
103
+ desc 'Runs the "up" for a given migration VERSION.'
104
+ task :up => :load do
105
+ version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
106
+ raise "VERSION is required" unless version
107
+ Sequel::Rails::Migrations.migrate_up!(version)
108
+ Rake::Task["db:schema:dump"].invoke if Rails.env != 'test'
109
+ end
110
+
111
+ desc 'Runs the "down" for a given migration VERSION.'
112
+ task :down => :load do
113
+ version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
114
+ raise "VERSION is required" unless version
115
+ Sequel::Rails::Migrations.migrate_down!(version)
116
+ Rake::Task["db:schema:dump"].invoke if Rails.env != 'test'
117
+ end
118
+ end
119
+
120
+ desc 'Migrate the database to the latest version'
121
+ task :migrate => :'migrate:load' do
122
+ Sequel::Rails::Migrations.migrate_up!(ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
123
+ Rake::Task["db:schema:dump"].invoke if Rails.env != 'test'
124
+ end
125
+
126
+ desc 'Rolls the schema back to the previous version. Specify the number of steps with STEP=n'
127
+ task :rollback => :'migrate:load' do
128
+ step = ENV['STEP'] ? ENV['STEP'].to_i : 1
129
+ Sequel::Migrator.rollback('db/migrate/', step)
130
+ Rake::Task["db:schema:dump"].invoke if Rails.env != 'test'
131
+ end
132
+
133
+ desc 'Pushes the schema to the next version. Specify the number of steps with STEP=n'
134
+ task :forward => :'migrate:load' do
135
+ step = ENV['STEP'] ? ENV['STEP'].to_i : 1
136
+ Sequel::Migrator.forward('db/migrate/', step)
137
+ Rake::Task["db:schema:dump"].invoke if Rails.env != 'test'
138
+ end
139
+
140
+ desc 'Load the seed data from db/seeds.rb'
141
+ task :seed => :environment do
142
+ seed_file = File.join(Rails.root, 'db', 'seeds.rb')
143
+ load(seed_file) if File.exist?(seed_file)
144
+ end
145
+
146
+ desc 'Create the database, load the schema, and initialize with the seed data'
147
+ task :setup => [ 'db:create', 'db:schema:load', 'db:seed' ]
148
+
149
+ desc 'Drops and recreates the database from db/schema.rb for the current environment and loads the seeds.'
150
+ task :reset => [ 'db:drop', 'db:setup' ]
151
+
152
+ desc 'Forcibly close any open connections to the test database'
153
+ task :force_close_open_connections => :environment do
154
+ if Rails.env.test?
155
+ db_config = Rails.configuration.database_configuration[Rails.env].symbolize_keys
156
+ begin
157
+ #Will only work on Postgres > 8.4
158
+ Sequel::Model.db.execute <<-SQL.gsub(/^\s{9}/,'')
159
+ SELECT COUNT(pg_terminate_backend(procpid))
160
+ FROM pg_stat_activity
161
+ WHERE datname = '#{db_config[:database]}';
162
+ SQL
163
+ rescue => e
164
+ #Will raise an error as it kills existing process running this command
165
+ #Seems to be only way to ensure *all* test connections are closed
166
+ end
167
+ end
168
+ end
169
+
170
+ namespace :test do
171
+ task :prepare do
172
+ Rails.env = 'test'
173
+ Rake::Task['db:force_close_open_connections'].invoke()
174
+ Rake::Task['db:drop'].invoke()
175
+ Rake::Task['db:create'].invoke()
176
+ Rake::Task['db:schema:load'].invoke()
177
+ Sequel::DATABASES.each do |db|
178
+ db.disconnect
179
+ end
180
+ end
181
+ end
182
+ end
183
+
184
+ task 'test:prepare' => 'db:test:prepare'
185
+
@@ -0,0 +1,9 @@
1
+
2
+ module Sequel::Rails::Railties
3
+ module I18nSupport
4
+ # Set the i18n scope to overwrite ActiveModel.
5
+ def i18n_scope
6
+ :sequel
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,69 @@
1
+
2
+ module Sequel::Rails
3
+ # Database-backed session store, with a Sequel model as the interface to the
4
+ # session table.
5
+ #
6
+ # Note that Rails will not use this by default (since the default store is
7
+ # CookieStore). To use it, you'll need to add this to config/application.rb:
8
+ #
9
+ # config.session_store(Sequel::Rails::SessionStore)
10
+ #
11
+ class SessionStore < ActionDispatch::Session::AbstractStore
12
+ class Session < Sequel::Model
13
+ def self.auto_migrate!
14
+ db.create_table :sessions do
15
+ primary_key :id
16
+ column :session_id, String,
17
+ :null => false,
18
+ :unique => true,
19
+ :index => true
20
+
21
+ column :data, :text,
22
+ :null => false
23
+
24
+ column :updated_at, DateTime,
25
+ :null => true,
26
+ :index => true
27
+ end
28
+ end
29
+
30
+ def self.name
31
+ 'session'
32
+ end
33
+ end
34
+
35
+ SESSION_RECORD_KEY = 'rack.session.record'.freeze
36
+
37
+ cattr_accessor :session_class
38
+ self.session_class = Session
39
+
40
+ private
41
+ def get_session(env, sid)
42
+ sid ||= generate_sid
43
+ session = find_session(sid)
44
+ env[SESSION_RECORD_KEY] = session
45
+ [ sid, session.data ]
46
+ end
47
+
48
+ def set_session(env, sid, session_data)
49
+ session = get_session_resource(env, sid)
50
+ session.data = session_data
51
+ session.updated_at = Time.now if session.dirty?
52
+ session.save
53
+ end
54
+
55
+ def get_session_resource(env, sid)
56
+ if env[ENV_SESSION_OPTIONS_KEY][:id].nil?
57
+ env[SESSION_RECORD_KEY] = find_session(sid)
58
+ else
59
+ env[SESSION_RECORD_KEY] ||= find_session(sid)
60
+ end
61
+ end
62
+
63
+ def find_session(sid)
64
+ klass = self.class.session_class
65
+
66
+ klass.where(:session_id => sid).first || klass.new(:session_id => sid)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,14 @@
1
+ require 'active_support/core_ext/hash/except'
2
+
3
+ require 'sequel/extensions/migration'
4
+
5
+ require 'sequel/rails/configuration'
6
+ require 'sequel/rails/runtime'
7
+ require 'sequel/rails/railties/benchmarking_mixin'
8
+
9
+ module Sequel
10
+ module Rails
11
+
12
+
13
+ end
14
+ end