Skip to content

Instantly share code, notes, and snippets.

@dariocravero
Created January 14, 2013 12:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dariocravero/9fd84405895a803b7cb1 to your computer and use it in GitHub Desktop.
Save dariocravero/9fd84405895a803b7cb1 to your computer and use it in GitHub Desktop.
diff --git a/padrino-admin/lib/padrino-admin/generators/actions.rb b/padrino-admin/lib/padrino-admin/generators/actions.rb
index 9ca2892..8a6d582 100644
--- a/padrino-admin/lib/padrino-admin/generators/actions.rb
+++ b/padrino-admin/lib/padrino-admin/generators/actions.rb
@@ -27,7 +27,7 @@ module Padrino
# Tell us for now wich orm we support
#
def supported_orm
- [:mini_record, :datamapper, :activerecord, :mongomapper, :mongoid, :couchrest, :sequel, :ohm]
+ [:mini_record, :datamapper, :activerecord, :mongomapper, :mongoid, :couchrest, :sequel, :ohm, :couchpotato]
end
##
diff --git a/padrino-admin/lib/padrino-admin/generators/admin_app.rb b/padrino-admin/lib/padrino-admin/generators/admin_app.rb
index 6553f11..c508f61 100644
--- a/padrino-admin/lib/padrino-admin/generators/admin_app.rb
+++ b/padrino-admin/lib/padrino-admin/generators/admin_app.rb
@@ -52,6 +52,7 @@ module Padrino
empty_directory destination_root("admin")
# Setup Admin Model
+ @orm = orm
@model_name = options[:admin_model].classify
@model_singular = @model_name.underscore
@model_plural = @model_singular.pluralize
diff --git a/padrino-admin/lib/padrino-admin/generators/orm.rb b/padrino-admin/lib/padrino-admin/generators/orm.rb
index bc05b6a..142237a 100644
--- a/padrino-admin/lib/padrino-admin/generators/orm.rb
+++ b/padrino-admin/lib/padrino-admin/generators/orm.rb
@@ -56,6 +56,7 @@ module Padrino
when :mongomapper then @klass.keys.values.reject { |key| key.name == "_id" } # On MongoMapper keys are an hash
when :sequel then @klass.db_schema.map { |k,v| v[:type] = :text if v[:db_type] =~ /^text/i; Column.new(k, v[:type]) }
when :ohm then @klass.attributes.map { |a| Column.new(a.to_s, :string) } # ohm has strings
+ when :couchpotato then @klass.properties
else raise OrmError, "Adapter #{orm} is not yet supported!"
end
end
@@ -94,7 +95,7 @@ module Padrino
def find(params=nil)
case orm
- when :activerecord, :mini_record, :mongomapper, :mongoid then "#{klass_name}.find(#{params})"
+ when :activerecord, :mini_record, :mongomapper, :mongoid, :couchpotato then "#{klass_name}.find(#{params})"
when :datamapper, :couchrest then "#{klass_name}.get(#{params})"
when :sequel, :ohm then "#{klass_name}[#{params}]"
else raise OrmError, "Adapter #{orm} is not yet supported!"
@@ -118,7 +119,7 @@ module Padrino
def update_attributes(params=nil)
case orm
- when :activerecord, :mini_record, :mongomapper, :mongoid, :couchrest then "@#{name_singular}.update_attributes(#{params})"
+ when :activerecord, :mini_record, :mongomapper, :mongoid, :couchrest, :couchpotato then "@#{name_singular}.update_attributes(#{params})"
when :datamapper, :ohm then "@#{name_singular}.update(#{params})"
when :sequel then "@#{name_singular}.modified! && @#{name_singular}.update(#{params})"
else raise OrmError, "Adapter #{orm} is not yet supported!"
diff --git a/padrino-admin/lib/padrino-admin/generators/templates/account/couchpotato.rb.tt b/padrino-admin/lib/padrino-admin/generators/templates/account/couchpotato.rb.tt
new file mode 100644
index 0000000..eb8a5bd
--- /dev/null
+++ b/padrino-admin/lib/padrino-admin/generators/templates/account/couchpotato.rb.tt
@@ -0,0 +1,68 @@
+class <%= @model_name %>
+ include CouchPotato::Persistence
+
+ attr_accessor :password, :password_confirmation
+
+ # Properties
+ property :name
+ property :surname
+ property :email
+ property :crypted_password
+ property :role
+
+ view :by_email, :key => :email
+ view :all, :key => :created_at
+
+ # Validations
+ validates :email, :role, :presence => true
+ validates :password, :password_confirmation, :presence => true, :if => :password_required
+ validates :password, :length => {:within => 4..40}, :if => :password_required
+ validates :password, :confirmation => true, :if => :password_required
+ validates :email, :length => {:within => 3..100}
+ validates :email, :format => {:with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i}
+ validates :role, :format => {:with => /[A-Za-z]/}
+ validate :unique_email
+
+ # Callbacks
+ before_save :encrypt_password, :if => :password_required
+
+ ##
+ # This method is for authentication purpose
+ #
+ def self.authenticate(email, password)
+ account = CouchPotato.database.view(Account.by_email(email))
+ account if account && account.has_password?(password)
+ end
+
+ def has_password?(password)
+ ::BCrypt::Password.new(crypted_password) == password
+ end
+
+ ##
+ # This method is used by AuthenticationHelper
+ #
+ def self.find_by_id(id)
+ CouchPotato.database.load(id)
+ end
+
+ private
+ def encrypt_password
+ self.crypted_password = ::BCrypt::Password.create(password)
+ end
+
+ def password_required
+ crypted_password.blank? || password.present?
+ end
+
+ def unique_email
+ # TODO case_sensitive => false
+ account = CouchPotato.database.view(Account.by_email(email)).first
+
+ # didn't find email in the database
+ return if account.nil?
+
+ # account with same email in database is this account
+ return if has_key?('_id') && self['_id'] == account['_id']
+ errors.add(:email, "is not unique")
+ end
+end
diff --git a/padrino-admin/lib/padrino-admin/generators/templates/account/seeds.rb.tt b/padrino-admin/lib/padrino-admin/generators/templates/account/seeds.rb.tt
index 0218078..28de7d5 100644
--- a/padrino-admin/lib/padrino-admin/generators/templates/account/seeds.rb.tt
+++ b/padrino-admin/lib/padrino-admin/generators/templates/account/seeds.rb.tt
@@ -10,9 +10,16 @@ password = shell.ask "Tell me the password to use:"
shell.say ""
+<% if @orm == :couchpotato %>
+account = <%= @model_name %>.new(:email => email, :name => "Foo", :surname => "Bar", :password => password, :password_confirmation => password, :role => "admin")
+
+if account.valid?
+ CouchPotato.database.save_document account
+<% else %>
account = <%= @model_name %>.create(:email => email, :name => "Foo", :surname => "Bar", :password => password, :password_confirmation => password, :role => "admin")
if account.valid?
+<% end %>
shell.say "================================================================="
shell.say "<%= @model_name %> has been successfully created, now you can login with:"
shell.say "================================================================="
diff --git a/padrino-core/lib/padrino-core/application/routing.rb b/padrino-core/lib/padrino-core/application/routing.rb
index 18095c1..9886b97 100644
--- a/padrino-core/lib/padrino-core/application/routing.rb
+++ b/padrino-core/lib/padrino-core/application/routing.rb
@@ -908,14 +908,10 @@ module Padrino
static! if settings.static? && (request.get? || request.head?)
route!
rescue ::Exception => boom
- filter! :before if boom.kind_of? ::Sinatra::NotFound
- @boom_handled = handle_exception!(boom)
+ filter! :before
+ handle_exception!(boom)
ensure
- @boom_handled or begin
- filter! :after unless env['sinatra.static_file']
- rescue ::Exception => boom
- handle_exception!(boom)
- end
+ filter! :after unless env['sinatra.static_file']
end
ROUTE_NOT_FOUND_STATUS = 9404
diff --git a/padrino-core/test/test_filters.rb b/padrino-core/test/test_filters.rb
index a7b615d..b1ebe47 100644
--- a/padrino-core/test/test_filters.rb
+++ b/padrino-core/test/test_filters.rb
@@ -275,74 +275,4 @@ describe "Filters" do
get '/foo'
assert_equal 'before', test
end
-
- should "call before filters only once" do
- once = ''
- mock_app do
- error 500 do
- 'error 500'
- end
- before do
- once += 'before'
- end
- get :index do
- raise Exception, 'Oops'
- end
- end
-
- get '/'
- assert_equal 'before', once
- end
-
- should 'catch exceptions in before filters' do
- doodle = nil
- mock_app do
- after do
- doodle = 'Been after'
- end
- before do
- raise StandardError, "before"
- end
- get :index do
- doodle = 'Been now'
- end
- error 500 do
- "We broke #{env['sinatra.error'].message}"
- end
- end
-
- get '/'
- assert_equal 'We broke before', body
- assert_equal nil, doodle
- end
-
- should 'catch exceptions in after filters if no exceptions caught before' do
- doodle = ''
- mock_app do
- after do
- doodle += ' and after'
- raise StandardError, "after"
- end
- get :foo do
- doodle = 'Been now'
- raise StandardError, "now"
- end
- get :index do
- doodle = 'Been now'
- end
- error 500 do
- "We broke #{env['sinatra.error'].message}"
- end
- end
-
- get '/foo'
- assert_equal 'We broke now', body
- assert_equal 'Been now', doodle
-
- doodle = ''
- get '/'
- assert_equal 'We broke after', body
- assert_equal 'Been now and after', doodle
- end
-
end
diff --git a/padrino-gen/README.rdoc b/padrino-gen/README.rdoc
index cbb3bef..086e17f 100644
--- a/padrino-gen/README.rdoc
+++ b/padrino-gen/README.rdoc
@@ -43,7 +43,7 @@ renderer:: haml (default), erb, erubis, liquid, slim
stylesheet:: sass (default), less, compass
mock:: none (default), mocha, rr
script:: none (default), jquery, prototype, mootools, rightjs, extcore, dojo
-orm:: none (default), datamapper, mongomapper, mongoid, activerecord, sequel, couchrest, ohm, mongomatic, ripple
+orm:: none (default), datamapper, mongomapper, mongoid, activerecord, sequel, couchrest, ohm, mongomatic, ripple, couchpotato
In addition, you can generate projects based on existing templates:
diff --git a/padrino-gen/lib/padrino-gen/generators/components/orms/activerecord.rb b/padrino-gen/lib/padrino-gen/generators/components/orms/activerecord.rb
index 40eec15..8b094ad 100644
--- a/padrino-gen/lib/padrino-gen/generators/components/orms/activerecord.rb
+++ b/padrino-gen/lib/padrino-gen/generators/components/orms/activerecord.rb
@@ -100,7 +100,7 @@ def setup_orm
ar.gsub! /!DB_DEVELOPMENT!/, MYSQL.gsub(/!DB_NAME!/,"'#{db}_development'")
ar.gsub! /!DB_PRODUCTION!/, MYSQL.gsub(/!DB_NAME!/,"'#{db}_production'")
ar.gsub! /!DB_TEST!/, MYSQL.gsub(/!DB_NAME!/,"'#{db}_test'")
- require_dependencies 'mysql', :version => "~> 2.8"
+ require_dependencies 'mysql'
when 'mysql2'
ar.gsub! /!DB_DEVELOPMENT!/, MYSQL2.gsub(/!DB_NAME!/,"'#{db}_development'")
ar.gsub! /!DB_PRODUCTION!/, MYSQL2.gsub(/!DB_NAME!/,"'#{db}_production'")
diff --git a/padrino-gen/lib/padrino-gen/generators/components/orms/couchpotato.rb b/padrino-gen/lib/padrino-gen/generators/components/orms/couchpotato.rb
new file mode 100644
index 0000000..0917247
--- /dev/null
+++ b/padrino-gen/lib/padrino-gen/generators/components/orms/couchpotato.rb
@@ -0,0 +1,54 @@
+COUCHPOTATO = (<<-COUCHPOTATO) unless defined?(COUCHPOTATO)
+case Padrino.env
+ when :development then db_name = '!NAME!_development'
+ when :production then db_name = '!NAME!_production'
+ when :test then db_name = '!NAME!_test'
+end
+
+CouchPotato::Config.database_name = db_name
+# or CouchPotato::Config.database_name = http://<host>:<port>/db_name
+# or CouchPotato::Config.database_name = http://<username>:<password>@<host>:<port>/db_name
+
+# language for design documents - defaulting to :javascript
+# CouchPotato::Config.default_language = :erlang
+
+# views in own design documents - defaulting to false
+# CouchPotato::Config.split_design_documents_per_view = true
+COUCHPOTATO
+
+def setup_orm
+ require_dependencies 'couch_potato'
+ create_file("config/database.rb", COUCHPOTATO.gsub(/!NAME!/, @app_name.underscore))
+end
+
+POTATO_MODEL = (<<-MODEL) unless defined?(POTATO_MODEL)
+class !NAME!
+ include CouchPotato::Persistence
+ # property <name>, :type => String, :default => 'Fredrik' # type and default optional
+ !FIELDS!
+end
+MODEL
+
+# options => { :fields => ["title:string", "body:string"], :app => 'app' }
+def create_model_file(name, options={})
+ model_path = destination_root(options[:app], 'models', "#{name.to_s.underscore}.rb")
+ field_tuples = options[:fields].map { |value| value.split(":") }
+ column_declarations = field_tuples.map { |field, kind|
+ if kind
+ "property :#{field}, :type => #{kind.capitalize}"
+ else
+ "property :#{field}"
+ end
+ }.join("\n ")
+ model_contents = POTATO_MODEL.gsub(/!NAME!/, name.to_s.underscore.camelize)
+ model_contents.gsub!(/!FIELDS!/, column_declarations)
+ create_file(model_path, model_contents)
+end
+
+def create_model_migration(filename, name, fields)
+ # NO MIGRATION NEEDED
+end
+
+def create_migration_file(migration_name, name, columns)
+ # NO MIGRATION NEEDED
+end
diff --git a/padrino-gen/lib/padrino-gen/generators/project.rb b/padrino-gen/lib/padrino-gen/generators/project.rb
index 154a97c..cc60c64 100644
--- a/padrino-gen/lib/padrino-gen/generators/project.rb
+++ b/padrino-gen/lib/padrino-gen/generators/project.rb
@@ -35,7 +35,7 @@ module Padrino
class_option :template, :desc => 'Generate project from template', :aliases => '-p', :default => nil, :type => :string
# Definitions for the available customizable components
- component_option :orm, 'database engine', :aliases => '-d', :choices => [:activerecord, :mini_record, :datamapper, :mongomapper, :mongoid, :sequel, :couchrest, :ohm, :mongomatic, :ripple], :default => :none
+ component_option :orm, 'database engine', :aliases => '-d', :choices => [:activerecord, :mini_record, :datamapper, :mongomapper, :mongoid, :sequel, :couchrest, :ohm, :mongomatic, :ripple, :couchpotato], :default => :none
component_option :test, 'testing framework', :aliases => '-t', :choices => [:rspec, :shoulda, :cucumber, :bacon, :testspec, :riot, :minitest], :default => :none
component_option :mock, 'mocking library', :aliases => '-m', :choices => [:mocha, :rr], :default => :none
component_option :script, 'javascript library', :aliases => '-s', :choices => [:jquery, :prototype, :rightjs, :mootools, :extcore, :dojo], :default => :none
diff --git a/padrino-gen/lib/padrino-gen/padrino-tasks/couchpotato.rb b/padrino-gen/lib/padrino-gen/padrino-tasks/couchpotato.rb
new file mode 100644
index 0000000..e2b69c4
--- /dev/null
+++ b/padrino-gen/lib/padrino-gen/padrino-tasks/couchpotato.rb
@@ -0,0 +1,19 @@
+if defined?(CouchPotato)
+ namespace :couchpotato do
+ desc "Creates the database for the current environment if it doesn't exist"
+ task :create => :environment do
+ CouchPotato.couchrest_database.create!
+ end
+
+ desc "Drops the database for the current environment"
+ task :drop => :environment do
+ CouchPotato.couchrest_database.delete!
+ end
+
+ desc "Resets your database for the current environment"
+ task :reset => ["couchpotato:drop", "couchpotato:create"]
+
+ desc "Creates the database and initialize with the seed data"
+ task :setup => ["couchpotato:create", "seed"]
+ end
+end
diff --git a/padrino-gen/lib/padrino-gen/padrino-tasks/mongomapper.rb b/padrino-gen/lib/padrino-gen/padrino-tasks/mongomapper.rb
index 8e8d157..c7e4295 100644
--- a/padrino-gen/lib/padrino-gen/padrino-tasks/mongomapper.rb
+++ b/padrino-gen/lib/padrino-gen/padrino-tasks/mongomapper.rb
@@ -1,6 +1,6 @@
if defined?(MongoMapper)
namespace :mm do
- desc 'Drops all the collections for the database for the current Padrino.env'
+ desc 'Drops all the collections for the database for the current Rails.env'
task :drop => :environment do
MongoMapper.database.collections.select {|c| c.name !~ /system/ }.each(&:drop)
end
diff --git a/padrino-gen/test/test_model_generator.rb b/padrino-gen/test/test_model_generator.rb
index 741c6ee..b696c9e 100644
--- a/padrino-gen/test/test_model_generator.rb
+++ b/padrino-gen/test/test_model_generator.rb
@@ -357,6 +357,26 @@ describe "ModelGenerator" do
end
end
+ # COUCHPOTATO
+ context "model generator using couchpotato" do
+ should "generate model file with no properties" do
+ capture_io { generate(:project, 'sample_project', "--root=#{@apptmp}", '--script=none', '-t=bacon', '-d=couchpotato') }
+ capture_io { generate(:model, 'user', "-r=#{@apptmp}/sample_project") }
+ assert_match_in_file(/class User/m, "#{@apptmp}/sample_project/models/user.rb")
+ assert_match_in_file(/include CouchPotato::Persistence/m, "#{@apptmp}/sample_project/models/user.rb")
+ end
+
+ should "generate model file with given fields" do
+ capture_io { generate(:project, 'sample_project', "--root=#{@apptmp}", '--script=none', '-t=bacon', '-d=couchpotato') }
+ capture_io { generate(:model, 'person', "name:string", "age", "email:string", "-r=#{@apptmp}/sample_project") }
+ assert_match_in_file(/class Person/m, "#{@apptmp}/sample_project/models/person.rb")
+ assert_match_in_file(/include CouchPotato::Persistence/m, "#{@apptmp}/sample_project/models/person.rb")
+ assert_match_in_file(/property :name, :type => String/m, "#{@apptmp}/sample_project/models/person.rb")
+ assert_match_in_file(/property :age/m, "#{@apptmp}/sample_project/models/person.rb")
+ assert_match_in_file(/property :email, :type => String/m, "#{@apptmp}/sample_project/models/person.rb")
+ end
+ end
+
context "model generator testing files" do
# BACON
should "generate test file for bacon" do
diff --git a/padrino-gen/test/test_project_generator.rb b/padrino-gen/test/test_project_generator.rb
index 319249b..fe06d3d 100644
--- a/padrino-gen/test/test_project_generator.rb
+++ b/padrino-gen/test/test_project_generator.rb
@@ -218,7 +218,7 @@ describe "ProjectGenerator" do
should "properly generate mysql" do
out, err = capture_io { generate(:project, 'sample_project', "--root=#{@apptmp}", '--orm=activerecord','--adapter=mysql') }
- assert_match_in_file(/gem 'mysql', '~> 2.8'/, "#{@apptmp}/sample_project/Gemfile")
+ assert_match_in_file(/gem 'mysql'/, "#{@apptmp}/sample_project/Gemfile")
assert_match_in_file(/sample_project_development/, "#{@apptmp}/sample_project/config/database.rb")
assert_match_in_file(%r{:adapter => 'mysql'}, "#{@apptmp}/sample_project/config/database.rb")
end
@@ -338,6 +338,14 @@ describe "ProjectGenerator" do
assert_match_in_file(/Ripple.load_configuration/, "#{@apptmp}/sample_project/config/database.rb")
assert_match_in_file(/http_port: 8098/, "#{@apptmp}/sample_project/config/riak.yml")
end
+
+ should "properly generate for couchpotato" do
+ out, err = capture_io { generate(:project, 'project.com', "--root=#{@apptmp}", '--orm=couchpotato', '--script=none') }
+ assert_match(/applying.*?couchpotato.*?orm/, out)
+ assert_match_in_file(/gem 'couch_potato'/, "#{@apptmp}/project.com/Gemfile")
+ assert_match_in_file(/CouchPotato::Config.database_name/, "#{@apptmp}/project.com/config/database.rb")
+ assert_match_in_file(/project_com/, "#{@apptmp}/project.com/config/database.rb")
+ end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment