Skip to content
Browse files

Remove cramp/model and move it to a new gem called tramp - http://git…

  • Loading branch information...
1 parent c8e125d commit 8c84041caff2e05094db6644b33ac4fde4566502 @lifo committed Jul 17, 2010
View
10 Gemfile
@@ -1,14 +1,10 @@
source 'http://rubygems.org'
-gem "cramp", :path => File.dirname(__FILE__)
+gem 'cramp', :path => File.dirname(__FILE__)
gem 'activesupport', '3.0.0.beta4'
-gem 'activemodel', '3.0.0.beta4'
-
-gem "arel", '>= 0.4.0'
-gem "rack", "1.1.0"
-gem "mysqlplus", "0.1.1"
-gem "eventmachine", "0.12.10"
+gem 'rack', '~> 1.1.0'
+gem 'eventmachine', '~> 0.12.10'
group :test do
gem 'usher'
View
19 Rakefile
@@ -8,21 +8,4 @@ Rake::TestTask.new(:test) do |t|
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
-Rake::Task['test'].comment = "Run model and controller tests"
-
-namespace :test do
- Rake::TestTask.new(:controller) do |t|
- t.libs << "test"
- t.pattern = 'test/controller/**/*_test.rb'
- t.verbose = true
- end
- Rake::Task['test:controller'].comment = "Run controller tests"
-
- Rake::TestTask.new(:model) do |t|
- t.libs << "test"
- t.pattern = 'test/model/**/*_test.rb'
- t.verbose = true
- end
- Rake::Task['test:model'].comment = "Run model tests"
-end
-
+Rake::Task['test'].comment = "Run tests"
View
15 cramp.gemspec
@@ -2,20 +2,15 @@ Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.name = 'cramp'
s.version = '0.10'
- s.summary = "Async ORM and controller layer."
- s.description = <<-EOF
- Cramp provides ORM and controller layers for developing asynchronous web applications.
- EOF
+ s.summary = 'Asynchronous web framework.'
+ s.description = 'Cramp is a framework for developing asynchronous web applications.'
- s.author = "Pratik Naik"
- s.email = "pratiknaik@gmail.com"
- s.homepage = "http://m.onkey.org"
+ s.author = 'Pratik Naik'
+ s.email = 'pratiknaik@gmail.com'
+ s.homepage = 'http://m.onkey.org'
s.add_dependency('activesupport', '~> 3.0.0.beta4')
- s.add_dependency('activemodel', '~> 3.0.0.beta4')
- s.add_dependency('arel', '~> 0.4.0')
s.add_dependency('rack', '~> 1.1.0')
- s.add_dependency('mysqlplus', '~> 0.1.1')
s.add_dependency('eventmachine', '~> 0.12.10')
s.files = Dir['README', 'MIT-LICENSE', 'lib/**/*']
View
40 lib/cramp/model.rb
@@ -1,40 +0,0 @@
-require 'cramp'
-require 'cramp/model/evented_mysql'
-require 'cramp/model/emysql_ext'
-
-require 'mysqlplus'
-
-require 'arel'
-require 'cramp/model/arel_monkey_patches'
-
-require 'active_model'
-
-module Cramp
- module Model
- autoload :Quoting, "cramp/model/quoting"
- autoload :Engine, "cramp/model/engine"
- autoload :Column, "cramp/model/column"
- autoload :Relation, "cramp/model/relation"
-
- autoload :Base, "cramp/model/base"
- autoload :Finders, "cramp/model/finders"
- autoload :Attribute, "cramp/model/attribute"
- autoload :AttributeMethods, "cramp/model/attribute_methods"
- autoload :Status, "cramp/model/status"
- autoload :Callbacks, "cramp/model/callbacks"
-
- def self.init(settings)
- Arel::Table.engine = Cramp::Model::Engine.new(settings)
- end
-
- def self.select(query, callback = nil, &block)
- callback ||= block
-
- EventedMysql.select(query) do |rows|
- callback.arity == 1 ? callback.call(rows) : callback.call if callback
- end
- end
-
- end
-end
-
View
66 lib/cramp/model/arel_monkey_patches.rb
@@ -1,66 +0,0 @@
-class Arel::Session
- def create(insert, &block)
- insert.call(&block)
- end
-
- def read(select, &block)
- select.call(&block)
- end
-
- def update(update, &block)
- update.call(&block)
- end
-
- def delete(delete, &block)
- delete.call(&block)
- end
-
-end
-
-module Arel::Relation
- def call(&block)
- engine.read(self, &block)
- end
-
- def all(&block)
- session.read(self) {|rows| block.call(rows) }
- end
-
- def first(&block)
- session.read(self) {|rows| block.call(rows[0]) }
- end
-
- def each(&block)
- session.read(self) {|rows| rows.each {|r| block.call(r) } }
- end
-
- def insert(record, &block)
- session.create(Arel::Insert.new(self, record), &block)
- end
-
- def update(assignments, &block)
- session.update(Arel::Update.new(self, assignments), &block)
- end
-
- def delete(&block)
- session.delete(Arel::Deletion.new(self), &block)
- end
-end
-
-class Arel::Deletion
- def call(&block)
- engine.delete(self, &block)
- end
-end
-
-class Arel::Insert
- def call(&block)
- engine.create(self, &block)
- end
-end
-
-class Arel::Update
- def call(&block)
- engine.update(self, &block)
- end
-end
View
104 lib/cramp/model/attribute.rb
@@ -1,104 +0,0 @@
-# Copyright (c) 2009 Koziarski Software Ltd
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-module Cramp
- module Model
- class Attribute
-
- FORMATS = {}
- FORMATS[Date] = /^\d{4}\/\d{2}\/\d{2}$/
- FORMATS[Integer] = /^-?\d+$/
- FORMATS[Float] = /^-?\d*\.\d*$/
- FORMATS[Time] = /\A\s*
- -?\d+-\d\d-\d\d
- T
- \d\d:\d\d:\d\d
- (\.\d*)?
- (Z|[+-]\d\d:\d\d)?
- \s*\z/ix # lifted from the implementation of Time.xmlschema
-
- CONVERTERS = {}
- CONVERTERS[Date] = Proc.new do |str|
- Date.strptime(str, "%Y/%m/%d")
- end
-
- CONVERTERS[Integer] = Proc.new do |str|
- Integer(str)
- end
-
- CONVERTERS[Float] = Proc.new do |str|
- Float(str)
- end
-
- CONVERTERS[Time] = Proc.new do |str|
- Time.xmlschema(str)
- end
-
- attr_reader :name
- def initialize(name, owner_class, options)
- @name = name.to_s
- @owner_class = owner_class
- @options = options
-
- # append_validations!
- define_methods!
- end
-
- # I think this should live somewhere in Amo
- def check_value!(value)
- # Allow nil and Strings to fall back on the validations for typecasting
- # Everything else gets checked with is_a?
- if value.nil?
- nil
- elsif value.is_a?(String)
- value
- elsif value.is_a?(expected_type)
- value
- else
- raise TypeError, "Expected #{expected_type.inspect} but got #{value.inspect}"
- end
- end
-
- def expected_type
- @options[:type] || String
- end
-
- def type_cast(value)
- if value.is_a?(expected_type)
- value
- elsif (converter = CONVERTERS[expected_type]) && (value =~ FORMATS[expected_type])
- converter.call(value)
- else
- value
- end
- end
-
- def append_validations!
- if f = FORMATS[expected_type]
- @owner_class.validates_format_of @name, :with => f, :unless => lambda {|obj| obj.send(name).is_a? expected_type }, :allow_nil => @options[:allow_nil]
- end
- end
-
- def define_methods!
- @owner_class.define_attribute_methods(true)
- end
-
- def primary_key?
- @options[:primary_key]
- end
-
- end
-
- end
-end
View
83 lib/cramp/model/attribute_methods.rb
@@ -1,83 +0,0 @@
-# Copyright (c) 2009 Koziarski Software Ltd
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-module Cramp
- module Model
- module AttributeMethods
-
- extend ActiveSupport::Concern
- include ActiveModel::AttributeMethods
-
- module ClassMethods
- def attribute(name, options = {})
- write_inheritable_hash(:model_attributes, {name => Attribute.new(name, self, options)})
- end
-
- def define_attribute_methods(force = false)
- return unless model_attributes
- undefine_attribute_methods if force
- super(model_attributes.keys)
- end
- end
-
- included do
- class_inheritable_hash :model_attributes
- undef_method(:id) if method_defined?(:id)
-
- attribute_method_suffix("", "=")
- end
-
- def write_attribute(name, value)
- if ma = self.class.model_attributes[name.to_sym]
- value = ma.check_value!(value)
- end
- if(@attributes[name] != value)
- send "#{name}_will_change!".to_sym
- @attributes[name] = value
- end
- end
-
- def read_attribute(name)
- if ma = self.class.model_attributes[name]
- ma.type_cast(@attributes[name])
- else
- @attributes[name]
- end
- end
-
- def attributes=(attributes)
- attributes.each do |(name, value)|
- send("#{name}=", value)
- end
- end
-
- protected
-
- def attribute_method?(name)
- @attributes.include?(name.to_sym) || model_attributes[name.to_sym]
- end
-
- private
-
- def attribute(name)
- read_attribute(name.to_sym)
- end
-
- def attribute=(name, value)
- write_attribute(name.to_sym, value)
- end
-
- end
- end
-end
View
119 lib/cramp/model/base.rb
@@ -1,119 +0,0 @@
-module Cramp
- module Model
- class Base
-
- extend Finders
- include AttributeMethods
- include ActiveModel::Validations
- include ActiveModel::Dirty
- include Callbacks
-
- class << self
- def columns
- @columns ||= arel_table.columns
- end
-
- def column_names
- columns.map(&:name)
- end
-
- def primary_key
- @primary_key ||= model_attributes.detect {|k, v| v.primary_key? }[0]
- end
-
- def instantiate(record)
- object = allocate
- object.instance_variable_set("@attributes", record.with_indifferent_access)
- object
- end
- end
-
- attr_reader :attributes
-
- def initialize(attributes = {})
- @new_record = true
- @attributes = {}.with_indifferent_access
- self.attributes = attributes
- end
-
- def new_record?
- @new_record
- end
-
- def save(callback = nil, &block)
- callback ||= block
-
- if valid?
- new_record? ? create_record(callback) : update_record(callback)
- else
- callback.arity == 1 ? callback.call(Status.new(self, false)) : callback.call if callback
- end
- end
-
- def destroy(callback = nil, &block)
- callback ||= block
-
- relation.delete do
- status = Status.new(self, true)
- after_destroy_callbacks status
- callback.arity == 1 ? callback.call(status) : callback.call if callback
- end
- end
-
- private
-
- def create_record(callback = nil, &block)
- callback ||= block
-
- self.class.arel_table.insert(arel_attributes(true)) do |new_id|
- if new_id.present?
- self.id = new_id
- saved = true
- @new_record = false
- else
- saved = false
- end
-
- status = Status.new(self, saved)
- after_save status
- callback.arity == 1 ? callback.call(status) : callback.call if callback
- end
- end
-
- def update_record(callback = nil, &block)
- callback ||= block
-
- relation.update(arel_attributes) do |updated_rows|
- status = Status.new(self, true)
- after_save status
- callback.arity == 1 ? callback.call(status) : callback.call if callback
- end
- end
-
- def relation
- self.class.arel_table.where(self.class[self.class.primary_key].eq(send(self.class.primary_key)))
- end
-
- def after_save(status)
- if status.success?
- @previously_changed = changes
- changed_attributes.clear
- end
-
- after_save_callbacks status
- end
-
- def arel_attributes(exclude_primary_key = true, attribute_names = @attributes.keys)
- attrs = {}
-
- attribute_names.each do |name|
- value = read_attribute(name)
- attrs[self.class.arel_table[name]] = value
- end
-
- attrs
- end
-
- end
- end
-end
View
41 lib/cramp/model/callbacks.rb
@@ -1,41 +0,0 @@
-module Cramp
- module Model
- module Callbacks
- extend ActiveSupport::Concern
-
- included do
- class_inheritable_accessor :after_save_callback_names
- class_inheritable_accessor :after_destroy_callback_names
-
- self.after_save_callback_names = []
- self.after_destroy_callback_names = []
- end
-
- module ClassMethods
- def after_save(*method_names)
- self.after_save_callback_names += method_names
- end
-
- def after_destroy(*method_names)
- self.after_destroy_callback_names += method_names
- end
- end
-
- private
- def after_save_callbacks(result)
- after_save_callback_names.collect do |callback_name|
- callback = method callback_name
- callback.arity == 1 ? callback.call(result) : callback.call if callback
- end
- end
-
- def after_destroy_callbacks(result)
- after_destroy_callback_names.collect do |callback_name|
- callback = method callback_name
- callback.arity == 1 ? callback.call(result) : callback.call if callback
- end
- end
-
- end
- end
-end
View
72 lib/cramp/model/column.rb
@@ -1,72 +0,0 @@
-# Some of it yanked from Rails
-
-# Copyright (c) 2004-2009 David Heinemeier Hansson
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-module Cramp
- module Model
- class Column < Struct.new(:name, :default, :sql_type, :null)
- attr_reader :type
-
- def initialize(name, default, sql_type, null)
- super
- @type = simplified_type(sql_type)
- end
-
- private
-
- def simplified_type(field_type)
- case field_type
- when /int/i
- :integer
- when /float|double/i
- :float
- when /decimal|numeric|number/i
- extract_scale(field_type) == 0 ? :integer : :decimal
- when /datetime/i
- :datetime
- when /timestamp/i
- :timestamp
- when /time/i
- :time
- when /date/i
- :date
- when /clob/i, /text/i
- :text
- when /blob/i, /binary/i
- :binary
- when /char/i, /string/i
- :string
- when /boolean/i
- :boolean
- end
- end
-
- def extract_scale(sql_type)
- case sql_type
- when /^(numeric|decimal|number)\((\d+)\)/i then 0
- when /^(numeric|decimal|number)\((\d+)(,(\d+))\)/i then $4.to_i
- end
- end
-
- end
- end
-end
View
21 lib/cramp/model/emysql_ext.rb
@@ -1,21 +0,0 @@
-class EventedMysql
- def self.execute_now(query)
- @n ||= 0
- connection = connection_pool[@n]
- @n = 0 if (@n+=1) >= connection_pool.size
- connection.execute_now(query)
- end
-
- def execute_now(sql)
- log 'mysql sending', sql
- @mysql.query(sql)
- rescue Mysql::Error => e
- log 'mysql error', e.message
- if DisconnectErrors.include? e.message
- @@queue << [response, sql, cblk, eblk]
- return close
- else
- raise e
- end
- end
-end
View
75 lib/cramp/model/engine.rb
@@ -1,75 +0,0 @@
-require 'active_support/core_ext/module/attribute_accessors'
-
-module Cramp
- module Model
- class Engine
- autoload :Connection, "cramp/model/engine/connection"
-
- include Quoting
-
- def initialize(settings)
- @connection = Connection.new settings
- @quoted_column_names, @quoted_table_names = {}, {}
- end
-
- def create(relation, &block)
- query = relation.to_sql
- log_query(query)
- @connection.insert(query) {|rows| yield(rows) if block_given? }
- end
-
- def read(relation, &block)
- query = relation.to_sql
- log_query(query)
- @connection.select(query) {|rows| yield(rows) }
- end
-
- def update(relation)
- query = relation.to_sql
- log_query(query)
- @connection.update(query) {|rows| yield(rows) if block_given? }
- end
-
- def delete(relation)
- query = relation.to_sql
- log_query(query)
- @connection.delete(relation.to_sql) {|rows| yield(rows) if block_given? }
- end
-
- def adapter_name
- "mysql"
- end
-
- def connection
- # Arel apparently uses this method to check whether the engine is connected or not
- @connection
- end
-
- def tables
- sql = "SHOW TABLES"
- tables = []
- result = @connection.execute_now(sql)
-
- result.each { |field| tables << field[0] }
- result.free
- tables
- end
-
- def columns(table_name, name = nil)
- sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}"
- columns = []
- result = @connection.execute_now(sql)
-
- result.each { |field| columns << Column.new(field[0], field[4], field[1], field[2] == "YES") }
- result.free
- columns
- end
-
- protected
-
- def log_query(sql)
- Cramp.logger.info("[QUERY] #{sql}") if Cramp.logger
- end
- end
- end
-end
View
32 lib/cramp/model/engine/connection.rb
@@ -1,32 +0,0 @@
-module Cramp
- module Model
- class Engine
- class Connection
- def initialize(settings)
- EventedMysql.settings.update(settings)
- end
-
- def execute_now(sql)
- EventedMysql.execute_now sql
- end
-
- def insert(sql, &block)
- EventedMysql.insert sql, block
- end
-
- def select(sql, &block)
- EventedMysql.select sql, block
- end
-
- def update(sql, &block)
- EventedMysql.update sql, block
- end
-
- def delete(sql, &block)
- EventedMysql.delete sql, block
- end
-
- end
- end
- end
-end
View
298 lib/cramp/model/evented_mysql.rb
@@ -1,298 +0,0 @@
-# Async MySQL driver for Ruby/EventMachine
-# (c) 2008 Aman Gupta (tmm1)
-# http://github.com/tmm1/em-mysql
-
-require 'eventmachine'
-require 'fcntl'
-
-class Mysql
- def result
- @cur_result
- end
-end
-
-class EventedMysql < EM::Connection
- def initialize mysql, opts
- @mysql = mysql
- @fd = mysql.socket
- @opts = opts
- @current = nil
- @@queue ||= []
- @processing = false
- @connected = true
-
- log 'mysql connected'
-
- self.notify_readable = true
- EM.add_timer(0){ next_query }
- end
- attr_reader :processing, :connected, :opts
- alias :settings :opts
-
- DisconnectErrors = [
- 'query: not connected',
- 'MySQL server has gone away',
- 'Lost connection to MySQL server during query'
- ] unless defined? DisconnectErrors
-
- def notify_readable
- log 'readable'
- if item = @current
- @current = nil
- start, response, sql, cblk, eblk = item
- log 'mysql response', Time.now-start, sql
- arg = case response
- when :raw
- result = @mysql.get_result
- @mysql.instance_variable_set('@cur_result', result)
- @mysql
- when :select
- ret = []
- result = @mysql.get_result
- result.each_hash{|h| ret << h }
- log 'mysql result', ret
- ret
- when :update
- result = @mysql.get_result
- @mysql.affected_rows
- when :insert
- result = @mysql.get_result
- @mysql.insert_id
- else
- result = @mysql.get_result
- log 'got a result??', result if result
- nil
- end
-
- @processing = false
- # result.free if result.is_a? Mysql::Result
- next_query
- cblk.call(arg) if cblk
- else
- log 'readable, but nothing queued?! probably an ERROR state'
- return close
- end
- rescue Mysql::Error => e
- log 'mysql error', e.message
- if e.message =~ /Deadlock/
- @@queue << [response, sql, cblk, eblk]
- @processing = false
- next_query
- elsif DisconnectErrors.include? e.message
- @@queue << [response, sql, cblk, eblk]
- return close
- elsif cb = (eblk || @opts[:on_error])
- cb.call(e)
- @processing = false
- next_query
- else
- raise e
- end
- # ensure
- # res.free if res.is_a? Mysql::Result
- # @processing = false
- # next_query
- end
-
- def unbind
- log 'mysql disconnect', $!
- # cp = EventedMysql.instance_variable_get('@connection_pool') and cp.delete(self)
- @connected = false
-
- # XXX wait for the next tick until the current fd is removed completely from the reactor
- #
- # XXX in certain cases the new FD# (@mysql.socket) is the same as the old, since FDs are re-used
- # XXX without next_tick in these cases, unbind will get fired on the newly attached signature as well
- #
- # XXX do _NOT_ use EM.next_tick here. if a bunch of sockets disconnect at the same time, we want
- # XXX reconnects to happen after all the unbinds have been processed
- EM.add_timer(0) do
- log 'mysql reconnecting'
- @processing = false
- @mysql = EventedMysql._connect @opts
- @fd = @mysql.socket
-
- @signature = EM.attach_fd @mysql.socket, true
- EM.set_notify_readable @signature, true
- log 'mysql connected'
- EM.instance_variable_get('@conns')[@signature] = self
- @connected = true
- make_socket_blocking
- next_query
- end
- end
-
- def execute sql, response = nil, cblk = nil, eblk = nil, &blk
- cblk ||= blk
-
- begin
- unless @processing or !@connected
- # begin
- # log 'mysql ping', @mysql.ping
- # # log 'mysql stat', @mysql.stat
- # # log 'mysql errno', @mysql.errno
- # rescue
- # log 'mysql ping failed'
- # @@queue << [response, sql, blk]
- # return close
- # end
-
- @processing = true
-
- log 'mysql sending', sql
- @mysql.send_query(sql)
- else
- @@queue << [response, sql, cblk, eblk]
- return
- end
- rescue Mysql::Error => e
- log 'mysql error', e.message
- if DisconnectErrors.include? e.message
- @@queue << [response, sql, cblk, eblk]
- return close
- else
- raise e
- end
- end
-
- log 'queuing', response, sql
- @current = [Time.now, response, sql, cblk, eblk]
- end
-
- def close
- @connected = false
- fd = detach
- log 'detached fd', fd
- end
-
- private
-
- def next_query
- if @connected and !@processing and pending = @@queue.shift
- response, sql, cblk, eblk = pending
- execute(sql, response, cblk, eblk)
- end
- end
-
- def log *args
- return unless @opts[:logging]
- p [Time.now, @fd, (@signature[-4..-1] if @signature), *args]
- end
-
- public
-
- def self.connect opts
- unless EM.respond_to?(:watch) and Mysql.method_defined?(:socket)
- raise RuntimeError, 'mysqlplus and EM.watch are required for EventedMysql'
- end
-
- if conn = _connect(opts)
- EM.watch conn.socket, self, conn, opts
- else
- EM.add_timer(5){ connect opts }
- end
- end
-
- self::Mysql = ::Mysql unless defined? self::Mysql
-
- # stolen from sequel
- def self._connect opts
- opts = settings.merge(opts)
-
- conn = Mysql.init
-
- # set encoding _before_ connecting
- if charset = opts[:charset] || opts[:encoding]
- conn.options(Mysql::SET_CHARSET_NAME, charset)
- end
-
- conn.options(Mysql::OPT_LOCAL_INFILE, 'client')
-
- conn.real_connect(
- opts[:host] || 'localhost',
- opts[:user] || opts[:username] || 'root',
- opts[:password],
- opts[:database],
- opts[:port],
- opts[:socket],
- 0 +
- # XXX multi results require multiple callbacks to parse
- # Mysql::CLIENT_MULTI_RESULTS +
- # Mysql::CLIENT_MULTI_STATEMENTS +
- (opts[:compress] == false ? 0 : Mysql::CLIENT_COMPRESS)
- )
-
- # increase timeout so mysql server doesn't disconnect us
- # this is especially bad if we're disconnected while EM.attach is
- # still in progress, because by the time it gets to EM, the FD is
- # no longer valid, and it throws a c++ 'bad file descriptor' error
- # (do not use a timeout of -1 for unlimited, it does not work on mysqld > 5.0.60)
- conn.query("set @@wait_timeout = #{opts[:timeout] || 2592000}")
-
- # we handle reconnecting (and reattaching the new fd to EM)
- conn.reconnect = false
-
- # By default, MySQL 'where id is null' selects the last inserted id
- # Turn this off. http://dev.rubyonrails.org/ticket/6778
- conn.query("set SQL_AUTO_IS_NULL=0")
-
- # get results for queries
- conn.query_with_result = true
-
- conn
- rescue Mysql::Error => e
- if cb = opts[:on_error]
- cb.call(e)
- nil
- else
- raise e
- end
- end
-end
-
-class EventedMysql
- def self.settings
- @settings ||= { :connections => 4, :logging => false }
- end
-
- def self.execute query, type = nil, cblk = nil, eblk = nil, &blk
- unless nil#connection = connection_pool.find{|c| not c.processing and c.connected }
- @n ||= 0
- connection = connection_pool[@n]
- @n = 0 if (@n+=1) >= connection_pool.size
- end
-
- connection.execute(query, type, cblk, eblk, &blk)
- end
-
- %w[ select insert update delete raw ].each do |type| class_eval %[
-
- def self.#{type} query, cblk = nil, eblk = nil, &blk
- execute query, :#{type}, cblk, eblk, &blk
- end
-
- ] end
-
- def self.all query, type = nil, &blk
- responses = 0
- connection_pool.each do |c|
- c.execute(query, type) do
- responses += 1
- blk.call if blk and responses == @connection_pool.size
- end
- end
- end
-
- def self.connection_pool
- @connection_pool ||= (1..settings[:connections]).map{ EventedMysql.connect(settings) }
- # p ['connpool', settings[:connections], @connection_pool.size]
- # (1..(settings[:connections]-@connection_pool.size)).each do
- # @connection_pool << EventedMysql.connect(settings)
- # end unless settings[:connections] == @connection_pool.size
- # @connection_pool
- end
-
- def self.reset_connection_pool!
- @connection_pool = nil
- end
-end
View
27 lib/cramp/model/finders.rb
@@ -1,27 +0,0 @@
-module Cramp
- module Model
- module Finders
-
- delegate :all, :first, :each, :where, :select, :group, :order, :limit, :offset, :to => :relation
-
- def [](attribute)
- arel_table[attribute]
- end
-
- def arel_table
- @arel_table ||= Arel::Table.new(table_name)
- end
-
- def relation
- Relation.new(self, arel_table)
- end
-
- private
-
- def table_name
- self.to_s.demodulize.underscore.pluralize
- end
-
- end
- end
-end
View
104 lib/cramp/model/quoting.rb
@@ -1,104 +0,0 @@
-# Yanked from Rails
-
-# Copyright (c) 2004-2009 David Heinemeier Hansson
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-module Cramp
- module Model
- module Quoting
- def quote_column_name(name)
- @quoted_column_names[name] ||= "`#{name}`"
- end
-
- def quote_table_name(name)
- @quoted_table_names[name] ||= quote_column_name(name).gsub('.', '`.`')
- end
-
- def quote(value, column = nil)
- if value.kind_of?(String) && column && column.type == :binary && column.class.respond_to?(:string_to_binary)
- s = value.unpack("H*")[0]
- "x'#{s}'"
- elsif value.kind_of?(BigDecimal)
- value.to_s("F")
- else
- super
- end
- end
-
- def quote(value, column = nil)
- # records are quoted as their primary key
- return value.quoted_id if value.respond_to?(:quoted_id)
-
- case value
- when String, ActiveSupport::Multibyte::Chars
- value = value.to_s
- if column && column.type == :binary && column.class.respond_to?(:string_to_binary)
- "#{quoted_string_prefix}'#{quote_string(column.class.string_to_binary(value))}'" # ' (for ruby-mode)
- elsif column && [:integer, :float].include?(column.type)
- value = column.type == :integer ? value.to_i : value.to_f
- value.to_s
- else
- "#{quoted_string_prefix}'#{quote_string(value)}'" # ' (for ruby-mode)
- end
- when NilClass then "NULL"
- when TrueClass then (column && column.type == :integer ? '1' : quoted_true)
- when FalseClass then (column && column.type == :integer ? '0' : quoted_false)
- when Float, Fixnum, Bignum then value.to_s
- # BigDecimals need to be output in a non-normalized form and quoted.
- when BigDecimal then value.to_s('F')
- else
- if value.acts_like?(:date) || value.acts_like?(:time)
- "'#{quoted_date(value)}'"
- else
- "#{quoted_string_prefix}'#{quote_string(value.to_yaml)}'"
- end
- end
- end
-
- # Quotes a string, escaping any ' (single quote) and \ (backslash)
- # characters.
- def quote_string(s)
- s.gsub(/\\/, '\&\&').gsub(/'/, "''") # ' (for ruby-mode)
- end
-
- def quoted_true
- "'t'"
- end
-
- def quoted_false
- "'f'"
- end
-
- def quoted_date(value)
- if value.acts_like?(:time)
- zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
- value.respond_to?(zone_conversion_method) ? value.send(zone_conversion_method) : value
- else
- value
- end.to_s(:db)
- end
-
- def quoted_string_prefix
- ''
- end
- end
- end
-end
View
62 lib/cramp/model/relation.rb
@@ -1,62 +0,0 @@
-module Cramp
- module Model
- class Relation
-
- def initialize(klass, relation)
- @klass, @relation = klass, relation
- end
-
- def each(callback = nil, &block)
- callback ||= block
-
- @relation.each do |row|
- object = @klass.instantiate(row)
- callback.call(object)
- end
- end
-
- def all(callback = nil, &block)
- callback ||= block
-
- @relation.all do |rows|
- objects = rows.map {|r| @klass.instantiate(r) }
- callback.call(objects)
- end
- end
-
- def first(callback = nil, &block)
- callback ||= block
-
- @relation.first do |row|
- object = row ? @klass.instantiate(row) : nil
- callback.call(object)
- end
- end
-
- def where(*conditions)
- Relation.new(@klass, @relation.where(*conditions))
- end
-
- def select(*selects)
- Relation.new(@klass, @relation.project(*selects))
- end
-
- def group(groups)
- Relation.new(@klass, @relation.group(groups))
- end
-
- def order(orders)
- Relation.new(@klass, @relation.order(orders))
- end
-
- def limit(limits)
- Relation.new(@klass, @relation.take(limits))
- end
-
- def offset(offsets)
- Relation.new(@klass, @relation.skip(offsets))
- end
-
- end
- end
-end
View
18 lib/cramp/model/status.rb
@@ -1,18 +0,0 @@
-module Cramp
- module Model
- class Status
-
- attr_reader :record
-
- def initialize(record, success)
- @record = record
- @success = success
- end
-
- def success?
- @success
- end
-
- end
- end
-end
View
1 test/model/base_test.rb
@@ -1 +0,0 @@
-require 'test_helper'

0 comments on commit 8c84041

Please sign in to comment.
Something went wrong with that request. Please try again.