nulogy-sequel-rails 0.3.8

Sign up to get free protection for your applications and to get access to all the features.
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