merb_sequel 1.0.0 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ == 1.0.9 "Get official" 2009-11-10
2
+
3
+ * Moved to gihub.com/merb and to merb_sequel
4
+ * Added Merb::Sequel::VERSION constant
5
+ * Moved to jeweler to match with Merb
6
+
7
+ == 1.0.8
8
+
9
+ * Dropped support for Sequel versions < 2.7.0
10
+
11
+ == 1.0.7
12
+
13
+ * Add support for ActiveModel via active_model plugin for Sequel > 3.5.0 or
14
+ Merb::Orms::Sequel::Model::ActiveModelCompatibility module. Added
15
+ :load_activemodel_compatibility configuration option to handle ActiveModel
16
+ compatibility loading. See README for
17
+ more information.
18
+ * Removed Merb::Orms::Sequel::ModelExtensions in favour to Merb::Orms::Sequel::Model::ActiveModelCompatibility
19
+ * Added spec.opts
20
+ * Fixing session storage
@@ -0,0 +1,139 @@
1
+ = merb_sequel
2
+
3
+ A plug-in for the Merb framework that provides support for Sequel models.
4
+
5
+ This is fork of the code in the official merb-plugins
6
+ (http://github.com/wycats/merb-plugins) repository. I did separate repository
7
+ and Gem to allow faster and more independent release cycle to keep up with the
8
+ Sequel monthly releases.
9
+
10
+ Plug-in is compatible with Merb 0.9.9 and higher and Sequel 1.4.0 and
11
+ higher including 2.x.x and <b>3.x.x</b>.
12
+
13
+ <b>Any issues please report to http://github.com/pk/merb_sequel/issues</b>.
14
+
15
+
16
+ == Install
17
+ Since version 1.0.6 I've moved gem hosting to Gemcutter. So now you need
18
+ to install gem with:
19
+
20
+ gem install pk-merb_sequel --source http://gemcutter.org
21
+
22
+ For versions <= 1.0.5 I used GitHub:
23
+
24
+ gem install pk-merb_sequel --source http://gems.github.com
25
+
26
+
27
+ === Merb < 1.1
28
+ Add pk-merb_sequel as a dependency to your <b>config/dependencies.rb</b>:
29
+
30
+ dependency 'pk-merb_sequel', :require_as => 'merb_sequel'
31
+
32
+ <b>Because of Merb < 1.1 ORM plugin loading mechanism you neeed to change init.rb</b>:
33
+
34
+ use_orm :sequel
35
+
36
+ to
37
+
38
+ Merb.orm = :sequel
39
+
40
+ If you don't do this Merb will complain that there is no merb_sequel gem also
41
+ if you have merb_sequel installed it will load your system wide gem instead of
42
+ the pk-merb_sequel gem.
43
+
44
+
45
+ === Merb >= 1.1, add it as a dependency to your <b>Gemfile</b>:
46
+
47
+ gem 'pk-merb_sequel', :require_as => 'merb_sequel'
48
+
49
+ Add Sequel as you ORM of choice to init.rb:
50
+
51
+ use_orm :sequel
52
+
53
+
54
+ == Compatibility
55
+
56
+ === Ruby 1.8.7:
57
+ Sequel 2.11.0:: All pass
58
+ Sequel 2.12.0:: All pass
59
+ Sequel 3.0.0:: All pass
60
+ Sequel 3.5.0:: All pass
61
+
62
+ === Ruby 1.9.1:
63
+ Sequel 2.11.0:: All pass except session spec failing due to Marshall issues.
64
+ Sequel 2.12.0:: All pass except session spec failing due to Marshall issues.
65
+ Sequel 3.0.0:: All pass except session spec failing due to Marshall issues.
66
+ Sequel 3.5.0:: All pass except session spec failing due to Marshall issues.
67
+
68
+ === ActiveModel compatibility
69
+ In Merb > 1.0.13 we use ActiveModel interface for the ORM plugins. merb_sequel
70
+ now supports this for all versions of Sequel by including compatibilit layers
71
+ by default or loading active model plugin when using Sequel > 3.5.0
72
+
73
+ You can use configuration to not load compatibility layer:
74
+ Merb::Plugins.config[:merb_sequel][:load_activemodel_compatibility] = false
75
+
76
+ == RSpec transactional examples
77
+
78
+ If you want to cut significantly runtime of your test suite which is using
79
+ Sequel you can enable transactional examples. Just add following line to
80
+ your spec_helper.rb or any spec you want to be transactional:
81
+
82
+ require 'merb_sequel/rspec/sequel'
83
+
84
+ Now <b>each example is wrapped in a Sequel transaction and when example finishes
85
+ Sequel::Error::Rollback is raised which cause transaction to rollback</b>.
86
+
87
+ == Connection options & Settings
88
+
89
+ Settings:
90
+
91
+ * :load_activemodel_compatibility. By default is set to true. If set to false, ActiveModelCompatibility is not loaded.
92
+
93
+ Merb Sequel plug-in uses config/database.yml for connection configuration.
94
+
95
+ Options are:
96
+
97
+ * adapter. :sqlite is assumed by default.
98
+ * database, default is "hey_dude_configure_your_database". In case of SQLite this
99
+ should be either :memory: or file path for SQLite.
100
+ * db_type: default is nil. Use "mssql" to connect to MSSQL using ODBC.
101
+ * encoding or charset, default is utf8.
102
+ * host. localhost is assumed by default.
103
+ * logger default is Merb.logger
104
+ * password. <b>WARNING: default password is an empty string</b>.
105
+ * socket Use socket to connect to DB.
106
+ * username or user, default is an empty string
107
+
108
+
109
+ == Generators
110
+
111
+ After you install the plug-in, merb-gen can generate Sequel models for you:
112
+
113
+ merb-gen model --orm=sequel Article
114
+
115
+ same with the resources
116
+
117
+ merb-gen resource --orm=sequel Article
118
+
119
+
120
+ <b>Note that if you have specified that you use Sequel in init.rb or environment
121
+ specific init file (for instance, environments/development.rb)
122
+ via use_orm :sequel, you don't need to specify --orm option explicitly when
123
+ using merb-gen</b>.
124
+
125
+
126
+ == Contributors
127
+
128
+ Originally written by Duane Johnson (canadaduane at gmail.com).
129
+
130
+ Contributions by:
131
+ * Wayne E. Seguin
132
+ * Lance Carlson
133
+ * Jacob Dunphy
134
+ * Lori Holden
135
+ * Pavel Kunc
136
+ * e-mac
137
+ * Piotr Usewicz
138
+
139
+ Maintained by Pavel Kunc (pavel.kunc at gmail.com)
data/Rakefile CHANGED
@@ -1,77 +1,48 @@
1
- require 'rubygems'
2
- require 'rake/gempackagetask'
3
- require "rake/rdoctask"
4
- require "extlib"
5
- require 'merb-core/tasks/merb_rake_helper'
6
- require "spec/rake/spectask"
7
-
8
- ##############################################################################
9
- # Package && release
10
- ##############################################################################
11
- RUBY_FORGE_PROJECT = "merb"
12
- PROJECT_URL = "http://merbivore.com"
13
- PROJECT_SUMMARY = "Merb plugin that provides support for Sequel and Sequel::Model"
14
- PROJECT_DESCRIPTION = PROJECT_SUMMARY
15
-
16
- GEM_AUTHOR = "Wayne E. Seguin, Lance Carlson, Lori Holden"
17
- GEM_EMAIL = "wayneeseguin@gmail.com, lancecarlson@gmail.com, email@loriholden.com"
18
-
19
- GEM_NAME = "merb_sequel"
20
- PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
21
- GEM_VERSION = (Merb::MORE_VERSION rescue "1.0.0") + PKG_BUILD
22
-
23
- RELEASE_NAME = "REL #{GEM_VERSION}"
24
-
25
- require "extlib/tasks/release"
26
-
27
- spec = Gem::Specification.new do |s|
28
- s.rubyforge_project = RUBY_FORGE_PROJECT
29
- s.name = GEM_NAME
30
- s.version = GEM_VERSION
31
- s.platform = Gem::Platform::RUBY
32
- s.has_rdoc = true
33
- s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
34
- s.summary = PROJECT_SUMMARY
35
- s.description = PROJECT_DESCRIPTION
36
- s.author = GEM_AUTHOR
37
- s.email = GEM_EMAIL
38
- s.homepage = PROJECT_URL
39
- s.add_dependency("merb-core", ">= 0.9.9")
40
- s.add_dependency("sequel", ">= 1.4.0")
41
- s.files = %w(LICENSE README Rakefile TODO Generators) + Dir.glob("{lib}/**/*")
42
- end
43
-
44
- Rake::GemPackageTask.new(spec) do |pkg|
45
- pkg.gem_spec = spec
46
- end
1
+ require "rubygems"
2
+ require "rake"
3
+
4
+ # Assume a typical dev checkout to fetch the current merb-core version
5
+ require File.expand_path('../../merb/merb-core/lib/merb-core/version', __FILE__)
6
+
7
+ # Load this library's version information
8
+ require File.expand_path('../lib/merb_sequel/version', __FILE__)
9
+
10
+ begin
11
+ require 'jeweler'
12
+
13
+ Jeweler::Tasks.new do |gemspec|
14
+ gemspec.version = Merb::Sequel::VERSION
15
+ gemspec.name = "merb_sequel"
16
+ gemspec.description = "Merb plugin that provides support for Sequel"
17
+ gemspec.summary = "Merb plugin that provides support for Sequel"
18
+ gemspec.authors = [ "Wayne E. Seguin", "Lance Carlson", "Lori Holden", "Pavel Kunc" ]
19
+ gemspec.email = "wayneeseguin@gmail.com, lancecarlson@gmail.com, email@loriholden.com, pavel.kunc@gmail.com"
20
+ gemspec.homepage = "http://github.com/merb/merb_sequel"
21
+ gemspec.files = %w(CHANGELOG LICENSE Rakefile README.rdoc TODO Generators) + Dir['{lib,spec}/**/*']
22
+ # Runtime dependencies
23
+ gemspec.add_dependency "merb-core", ">= 0.9.9"
24
+ gemspec.add_dependency "sequel", ">= 2.7.0"
25
+ # Development dependencies
26
+ gemspec.add_development_dependency "rspec", ">= 1.2.9"
27
+ end
47
28
 
48
- desc "Install the gem"
49
- task :install do
50
- Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
51
- end
29
+ Jeweler::GemcutterTasks.new
52
30
 
53
- desc "Uninstall the gem"
54
- task :uninstall do
55
- Merb::RakeHelper.uninstall(GEM_NAME, :version => GEM_VERSION)
31
+ rescue LoadError
32
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
56
33
  end
57
34
 
58
- desc "Create a gemspec file"
59
- task :gemspec do
60
- File.open("#{GEM_NAME}.gemspec", "w") do |file|
61
- file.puts spec.to_ruby
62
- end
35
+ require 'spec/rake/spectask'
36
+ Spec::Rake::SpecTask.new(:spec) do |spec|
37
+ spec.spec_opts << '--options' << 'spec/spec.opts' if File.exists?('spec/spec.opts')
38
+ spec.libs << 'lib' << 'spec'
39
+ spec.spec_files = FileList['spec/**/*_spec.rb']
63
40
  end
64
41
 
65
- desc "Run all examples (or a specific spec with TASK=xxxx)"
66
- Spec::Rake::SpecTask.new('spec') do |t|
67
- t.spec_opts = ["-cfs"]
68
- t.spec_files = begin
69
- if ENV["TASK"]
70
- ENV["TASK"].split(',').map { |task| "spec/**/#{task}_spec.rb" }
71
- else
72
- FileList['spec/**/*_spec.rb']
73
- end
74
- end
42
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
43
+ spec.libs << 'lib' << 'spec'
44
+ spec.pattern = 'spec/**/*_spec.rb'
45
+ spec.rcov = true
75
46
  end
76
47
 
77
48
  desc 'Default: run spec examples'
@@ -1,6 +1,6 @@
1
- # For details on Sequel migrations see
2
- # http://sequel.rubyforge.org/
3
- # http://sequel.rubyforge.org/rdoc/classes/Sequel/Database.html#M000607
1
+ # For details on Sequel migrations see:
2
+ # * http://sequel.rubyforge.org/
3
+ # * http://sequel.rubyforge.org/rdoc-plugins/classes/Sequel/Migration.html
4
4
 
5
5
  class <%= class_name %> < Sequel::Migration
6
6
 
@@ -25,9 +25,10 @@ class <%= class_name %> < Application
25
25
  # POST /<%= resource_path %>
26
26
  def create
27
27
  @<%= singular_model %> = <%= model_class_name %>.new(params[:<%= singular_model %>])
28
- if @<%= singular_model %>.save
28
+ begin
29
+ @<%= singular_model %>.save
29
30
  redirect url(:<%= (modules.collect{|m| m.downcase} << singular_model).join("_") %>, @<%= singular_model %>)
30
- else
31
+ rescue Sequel::ValidationFailed
31
32
  render :new
32
33
  end
33
34
  end
@@ -44,10 +45,11 @@ class <%= class_name %> < Application
44
45
  def update
45
46
  @<%= singular_model %> = <%= model_class_name %>[params[:id]]
46
47
  raise NotFound unless @<%= singular_model %>
47
- if @<%= singular_model %>.update(params[:<%= singular_model %>])
48
+ begin
49
+ @<%= singular_model %>.update(params[:<%= singular_model %>])
48
50
  redirect url(:<%= (modules.collect{|m| m.downcase} << singular_model).join("_") %>, @<%= singular_model %>)
49
- else
50
- raise BadRequest
51
+ rescue Sequel::ValidationFailed
52
+ render :edit
51
53
  end
52
54
  end
53
55
 
@@ -55,12 +57,13 @@ class <%= class_name %> < Application
55
57
  def destroy
56
58
  @<%= singular_model %> = <%= model_class_name %>[params[:id]]
57
59
  raise NotFound unless @<%= singular_model %>
58
- if @<%= singular_model %>.destroy
60
+ begin
61
+ @<%= singular_model %>.destroy
59
62
  redirect url(:<%= (modules.collect{|m| m.downcase} << singular_model).join("_") %>s)
60
- else
63
+ rescue Sequel::Error
61
64
  raise BadRequest
62
65
  end
63
66
  end
64
67
 
65
68
  end
66
- <% end -%>
69
+ <% end -%>
@@ -10,6 +10,14 @@ module Merb
10
10
  def config_file() Merb.dir_for(:config) / "database.yml" end
11
11
  def sample_dest() Merb.dir_for(:config) / "database.yml.sample" end
12
12
  def sample_source() File.dirname(__FILE__) / "database.yml.sample" end
13
+
14
+ # Determine if we use Sequel 3 or not
15
+ #
16
+ # ==== Returns
17
+ # Bool:: True if using Sequel >= 2.12.0 or False
18
+ def new_sequel?
19
+ !!(/^(2.12|3)/ =~ ::Sequel.version)
20
+ end
13
21
 
14
22
  def copy_sample_config
15
23
  FileUtils.cp sample_source, sample_dest unless File.exists?(sample_dest)
@@ -19,7 +27,7 @@ module Merb
19
27
  @config ||= begin
20
28
  # Convert string keys to symbols
21
29
  full_config = Erubis.load_yaml_file(config_file)
22
- config = (Merb::Plugins.config[:merb_sequel] = {})
30
+ config = Merb::Plugins.config[:merb_sequel]
23
31
  (full_config[Merb.environment.to_sym] || full_config[Merb.environment] || full_config[:development]).each do |key, value|
24
32
  config[key.to_sym] = value
25
33
  end
@@ -66,6 +74,7 @@ module Merb
66
74
  options[:database] = config[:database] || "hey_dude_configure_your_database"
67
75
  # MSSQL support
68
76
  options[:db_type] = config[:db_type] if config[:db_type]
77
+ options[:socket] = config[:socket] if config[:socket]
69
78
  options[:logger] = Merb.logger
70
79
  options
71
80
  end
@@ -0,0 +1,38 @@
1
+ module Merb
2
+ module Orms
3
+ module Sequel
4
+ module Model
5
+
6
+ # This code has been taken from Sequel 3.5.0
7
+ # Sequel::Plugins::ActiveModel
8
+ # http://sequel.rubyforge.org/rdoc-plugins/classes/Sequel/Plugins/ActiveModel.html
9
+ module ActiveModelCompatibility
10
+ # Record that an object was destroyed, for later use by
11
+ # destroyed?
12
+ def after_destroy
13
+ super
14
+ @destroyed = true
15
+ end
16
+
17
+ # Whether the object was destroyed by destroy. Not true
18
+ # for objects that were deleted.
19
+ def destroyed?
20
+ @destroyed == true
21
+ end
22
+
23
+ # An alias for new?
24
+ def new_record?
25
+ new?
26
+ end
27
+
28
+ # With the ActiveModel plugin, Sequel model objects are already
29
+ # compliant, so this returns self.
30
+ def to_model
31
+ self
32
+ end
33
+ end
34
+
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,10 +1,10 @@
1
1
  require 'sequel'
2
+ require 'sequel/extensions/migration' if Merb::Orms::Sequel.new_sequel?
2
3
  require 'merb-core/dispatch/session'
3
- require 'base64'
4
4
 
5
5
  module Merb
6
6
 
7
- Merb::Plugins.config[:merb_sequel][:session_table_name] ||= "sessions"
7
+ Merb::Plugins.config[:merb_sequel][:session_table_name] ||= 'sessions'
8
8
 
9
9
  # Default session migration run if a sessions table does not yet exist.
10
10
  #
@@ -48,18 +48,26 @@ module Merb
48
48
  # ContainerSession:: The session corresponding to the ID.
49
49
  def retrieve_session(session_id)
50
50
  if item = find(:session_id => session_id)
51
- item.data
51
+ Marshal.load(item.data.unpack('m').first)
52
52
  end
53
53
  end
54
54
 
55
55
  # ==== Parameters
56
56
  # session_id<String>:: ID of the session to set.
57
57
  # data<ContainerSession>:: The session to set.
58
- def store_session(session_id, data)
59
- if item = find(:session_id => session_id)
60
- item.update(:data => data)
61
- else
62
- create(:session_id => session_id, :data => data, :created_at => Time.now)
58
+ def store_session(session_id, session_data)
59
+ session_data = session_data.empty? ? nil : [Marshal.dump(session_data)].pack('m')
60
+ begin
61
+ if item = self.find(:session_id => session_id)
62
+ item.update(:data => session_data)
63
+ else
64
+ item = self.new(:session_id => session_id,
65
+ :data => session_data,
66
+ :created_at => Time.now)
67
+ item.save
68
+ end
69
+ rescue => e
70
+ Merb.logger.error("#{e.message} when trying to save #{session_data}")
63
71
  end
64
72
  end
65
73
 
@@ -70,49 +78,20 @@ module Merb
70
78
  item.delete
71
79
  end
72
80
  end
73
-
74
- # ==== Returns
75
- # Integer:: The maximum length of the 'data' column.
76
- def data_column_size_limit
77
- 512 # TODO - figure out how much space we actually have
78
- end
79
-
80
- alias :create_table! :create_table
81
- alias :drop_table! :drop_table
82
- end
83
-
84
- # Lazy-unserialize session state.
85
- def data
86
- @data ||= (@values[:data] ? Marshal.load(@values[:data]) : {})
87
- end
88
-
89
- # Virtual attribute writer - override.
90
- def data=(hsh)
91
- @data = hsh if hsh.is_a?(Hash)
92
- end
93
-
94
- # Has the session been loaded yet?
95
- def loaded?
96
- !!@data
97
- end
98
81
 
99
- before_save do
100
- @values[:data] = Marshal.dump(self.data)
101
- if @values[:data].size > self.class.data_column_size_limit
102
- raise Merb::SessionMixin::SessionOverflow
103
- end
82
+ unless Merb::Orms::Sequel.new_sequel?
83
+ alias :create_table! :create_table
84
+ alias :drop_table! :drop_table
85
+ end
104
86
  end
105
-
106
87
  end
107
88
 
108
89
  class SequelSession < SessionStoreContainer
109
-
110
90
  # The session store type
111
91
  self.session_store_type = :sequel
112
92
 
113
93
  # The store object is the model class itself
114
94
  self.store = SequelSessionStore
115
-
116
95
  end
117
96
 
118
97
  end