cramp 0.10 → 0.11

Sign up to get free protection for your applications and to get access to all the features.
data/lib/cramp.rb CHANGED
@@ -5,9 +5,14 @@ require 'active_support'
5
5
  require 'active_support/core_ext/class/inheritable_attributes'
6
6
  require 'active_support/core_ext/class/attribute_accessors'
7
7
  require 'active_support/core_ext/module/aliasing'
8
+ require 'active_support/core_ext/module/attribute_accessors'
8
9
  require 'active_support/core_ext/kernel/reporting'
9
10
  require 'active_support/concern'
11
+ require 'active_support/core_ext/hash/indifferent_access'
12
+ require 'active_support/buffered_logger'
10
13
 
11
14
  module Cramp
12
- VERSION = '0.10'
15
+ VERSION = '0.11'
16
+
17
+ mattr_accessor :logger
13
18
  end
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/hash/keys'
2
+
1
3
  module Cramp
2
4
  module Controller
3
5
  class Abstract
@@ -61,7 +63,7 @@ module Cramp
61
63
  end
62
64
 
63
65
  def params
64
- @params ||= @env['usher.params']
66
+ @params ||= request.params.update(@env['usher.params']).symbolize_keys
65
67
  end
66
68
 
67
69
  end
@@ -21,9 +21,11 @@ module Cramp
21
21
  end
22
22
 
23
23
  class Websocket < Abstract
24
-
25
24
  include PeriodicTimer
26
25
 
26
+ # TODO : Websockets shouldn't need this in an ideal world
27
+ include KeepConnectionAlive
28
+
27
29
  class_inheritable_accessor :on_data_callbacks, :instance_reader => false
28
30
  self.on_data_callbacks = []
29
31
 
@@ -48,13 +50,14 @@ module Cramp
48
50
  end
49
51
 
50
52
  def _on_data_receive(data)
51
- data = data.slice(/\000([^\377]*)\377/).gsub(/^\x00|\xff$/, '')
52
-
53
+ data = data.split(/\000([^\377]*)\377/).select{|d| !d.empty? }.collect{|d| d.gsub(/^\x00|\xff$/, '') }
53
54
  self.class.on_data_callbacks.each do |callback|
54
- EM.next_tick { send(callback, data) }
55
+ data.each do |message|
56
+ EM.next_tick { send(callback, message) }
57
+ end
55
58
  end
56
59
  end
57
-
60
+
58
61
  end
59
62
  end
60
63
  end
data/lib/cramp/model.rb CHANGED
@@ -21,6 +21,7 @@ module Cramp
21
21
  autoload :Attribute, "cramp/model/attribute"
22
22
  autoload :AttributeMethods, "cramp/model/attribute_methods"
23
23
  autoload :Status, "cramp/model/status"
24
+ autoload :Callbacks, "cramp/model/callbacks"
24
25
 
25
26
  def self.init(settings)
26
27
  Arel::Table.engine = Cramp::Model::Engine.new(settings)
@@ -17,7 +17,7 @@ class Arel::Session
17
17
 
18
18
  end
19
19
 
20
- class Arel::Relation
20
+ module Arel::Relation
21
21
  def call(&block)
22
22
  engine.read(self, &block)
23
23
  end
@@ -42,7 +42,10 @@ module Cramp
42
42
  if ma = self.class.model_attributes[name.to_sym]
43
43
  value = ma.check_value!(value)
44
44
  end
45
- @attributes[name] = value
45
+ if(@attributes[name] != value)
46
+ send "#{name}_will_change!".to_sym
47
+ @attributes[name] = value
48
+ end
46
49
  end
47
50
 
48
51
  def read_attribute(name)
@@ -5,6 +5,8 @@ module Cramp
5
5
  extend Finders
6
6
  include AttributeMethods
7
7
  include ActiveModel::Validations
8
+ include ActiveModel::Dirty
9
+ include Callbacks
8
10
 
9
11
  class << self
10
12
  def columns
@@ -48,6 +50,16 @@ module Cramp
48
50
  end
49
51
  end
50
52
 
53
+ def destroy(callback = nil, &block)
54
+ callback ||= block
55
+
56
+ relation.delete do
57
+ status = Status.new(self, true)
58
+ after_destroy_callbacks status
59
+ callback.arity == 1 ? callback.call(status) : callback.call if callback
60
+ end
61
+ end
62
+
51
63
  private
52
64
 
53
65
  def create_record(callback = nil, &block)
@@ -62,18 +74,33 @@ module Cramp
62
74
  saved = false
63
75
  end
64
76
 
65
- callback.arity == 1 ? callback.call(Status.new(self, saved)) : callback.call if callback
77
+ status = Status.new(self, saved)
78
+ after_save status
79
+ callback.arity == 1 ? callback.call(status) : callback.call if callback
66
80
  end
67
81
  end
68
82
 
69
83
  def update_record(callback = nil, &block)
70
84
  callback ||= block
71
85
 
72
- relation = self.class.arel_table.where(self.class[self.class.primary_key].eq(send(self.class.primary_key)))
73
-
74
86
  relation.update(arel_attributes) do |updated_rows|
75
- callback.arity == 1 ? callback.call(updated_rows) : callback.call if callback
87
+ status = Status.new(self, true)
88
+ after_save status
89
+ callback.arity == 1 ? callback.call(status) : callback.call if callback
90
+ end
91
+ end
92
+
93
+ def relation
94
+ self.class.arel_table.where(self.class[self.class.primary_key].eq(send(self.class.primary_key)))
95
+ end
96
+
97
+ def after_save(status)
98
+ if status.success?
99
+ @previously_changed = changes
100
+ changed_attributes.clear
76
101
  end
102
+
103
+ after_save_callbacks status
77
104
  end
78
105
 
79
106
  def arel_attributes(exclude_primary_key = true, attribute_names = @attributes.keys)
@@ -0,0 +1,41 @@
1
+ module Cramp
2
+ module Model
3
+ module Callbacks
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ class_inheritable_accessor :after_save_callback_names
8
+ class_inheritable_accessor :after_destroy_callback_names
9
+
10
+ self.after_save_callback_names = []
11
+ self.after_destroy_callback_names = []
12
+ end
13
+
14
+ module ClassMethods
15
+ def after_save(*method_names)
16
+ self.after_save_callback_names += method_names
17
+ end
18
+
19
+ def after_destroy(*method_names)
20
+ self.after_destroy_callback_names += method_names
21
+ end
22
+ end
23
+
24
+ private
25
+ def after_save_callbacks(result)
26
+ after_save_callback_names.collect do |callback_name|
27
+ callback = method callback_name
28
+ callback.arity == 1 ? callback.call(result) : callback.call if callback
29
+ end
30
+ end
31
+
32
+ def after_destroy_callbacks(result)
33
+ after_destroy_callback_names.collect do |callback_name|
34
+ callback = method callback_name
35
+ callback.arity == 1 ? callback.call(result) : callback.call if callback
36
+ end
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -1,45 +1,75 @@
1
+ require 'active_support/core_ext/module/attribute_accessors'
2
+
1
3
  module Cramp
2
4
  module Model
3
5
  class Engine
6
+ autoload :Connection, "cramp/model/engine/connection"
7
+
4
8
  include Quoting
5
9
 
6
10
  def initialize(settings)
7
- @settings = settings
11
+ @connection = Connection.new settings
8
12
  @quoted_column_names, @quoted_table_names = {}, {}
9
-
10
- EventedMysql.settings.update(settings)
11
13
  end
12
14
 
13
15
  def create(relation, &block)
14
- EventedMysql.insert(relation.to_sql) {|rows| yield(rows) if block_given? }
16
+ query = relation.to_sql
17
+ log_query(query)
18
+ @connection.insert(query) {|rows| yield(rows) if block_given? }
15
19
  end
16
20
 
17
21
  def read(relation, &block)
18
- EventedMysql.select(relation.to_sql) {|rows| yield(rows) }
22
+ query = relation.to_sql
23
+ log_query(query)
24
+ @connection.select(query) {|rows| yield(rows) }
19
25
  end
20
26
 
21
27
  def update(relation)
22
- EventedMysql.update(relation.to_sql) {|rows| yield(rows) if block_given? }
28
+ query = relation.to_sql
29
+ log_query(query)
30
+ @connection.update(query) {|rows| yield(rows) if block_given? }
23
31
  end
24
32
 
25
33
  def delete(relation)
26
- EventedMysql.delete(relation.to_sql) {|rows| yield(rows) if block_given? }
34
+ query = relation.to_sql
35
+ log_query(query)
36
+ @connection.delete(relation.to_sql) {|rows| yield(rows) if block_given? }
27
37
  end
28
38
 
29
39
  def adapter_name
30
- "Cramp MySQL Async Adapter"
40
+ "mysql"
41
+ end
42
+
43
+ def connection
44
+ # Arel apparently uses this method to check whether the engine is connected or not
45
+ @connection
46
+ end
47
+
48
+ def tables
49
+ sql = "SHOW TABLES"
50
+ tables = []
51
+ result = @connection.execute_now(sql)
52
+
53
+ result.each { |field| tables << field[0] }
54
+ result.free
55
+ tables
31
56
  end
32
57
 
33
58
  def columns(table_name, name = nil)
34
59
  sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}"
35
60
  columns = []
36
- result = EventedMysql.execute_now(sql)
61
+ result = @connection.execute_now(sql)
37
62
 
38
63
  result.each { |field| columns << Column.new(field[0], field[4], field[1], field[2] == "YES") }
39
64
  result.free
40
65
  columns
41
66
  end
42
67
 
68
+ protected
69
+
70
+ def log_query(sql)
71
+ Cramp.logger.info("[QUERY] #{sql}") if Cramp.logger
72
+ end
43
73
  end
44
74
  end
45
75
  end
@@ -0,0 +1,32 @@
1
+ module Cramp
2
+ module Model
3
+ class Engine
4
+ class Connection
5
+ def initialize(settings)
6
+ EventedMysql.settings.update(settings)
7
+ end
8
+
9
+ def execute_now(sql)
10
+ EventedMysql.execute_now sql
11
+ end
12
+
13
+ def insert(sql, &block)
14
+ EventedMysql.insert sql, block
15
+ end
16
+
17
+ def select(sql, &block)
18
+ EventedMysql.select sql, block
19
+ end
20
+
21
+ def update(sql, &block)
22
+ EventedMysql.update sql, block
23
+ end
24
+
25
+ def delete(sql, &block)
26
+ EventedMysql.delete sql, block
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
@@ -19,7 +19,7 @@ module Cramp
19
19
  private
20
20
 
21
21
  def table_name
22
- @table_name || self.to_s.pluralize
22
+ self.to_s.demodulize.underscore.pluralize
23
23
  end
24
24
 
25
25
  end
@@ -79,16 +79,6 @@ module Cramp
79
79
  s.gsub(/\\/, '\&\&').gsub(/'/, "''") # ' (for ruby-mode)
80
80
  end
81
81
 
82
- # Quotes the column name. Defaults to no quoting.
83
- def quote_column_name(column_name)
84
- column_name
85
- end
86
-
87
- # Quotes the table name. Defaults to column name quoting.
88
- def quote_table_name(table_name)
89
- quote_column_name(table_name)
90
- end
91
-
92
82
  def quoted_true
93
83
  "'t'"
94
84
  end
metadata CHANGED
@@ -1,7 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cramp
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.10"
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 11
8
+ version: "0.11"
5
9
  platform: ruby
6
10
  authors:
7
11
  - Pratik Naik
@@ -9,69 +13,95 @@ autorequire:
9
13
  bindir: bin
10
14
  cert_chain: []
11
15
 
12
- date: 2010-02-19 00:00:00 +00:00
16
+ date: 2010-05-11 00:00:00 +01:00
13
17
  default_executable:
14
18
  dependencies:
15
19
  - !ruby/object:Gem::Dependency
16
20
  name: activesupport
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
21
+ prerelease: false
22
+ requirement: &id001 !ruby/object:Gem::Requirement
20
23
  requirements:
21
- - - "="
24
+ - - ~>
22
25
  - !ruby/object:Gem::Version
23
- version: 3.0.0.beta
24
- version:
26
+ segments:
27
+ - 3
28
+ - 0
29
+ - 0
30
+ - beta3
31
+ version: 3.0.0.beta3
32
+ type: :runtime
33
+ version_requirements: *id001
25
34
  - !ruby/object:Gem::Dependency
26
35
  name: activemodel
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
30
38
  requirements:
31
- - - "="
39
+ - - ~>
32
40
  - !ruby/object:Gem::Version
33
- version: 3.0.0.beta
34
- version:
41
+ segments:
42
+ - 3
43
+ - 0
44
+ - 0
45
+ - beta3
46
+ version: 3.0.0.beta3
47
+ type: :runtime
48
+ version_requirements: *id002
35
49
  - !ruby/object:Gem::Dependency
36
50
  name: arel
37
- type: :runtime
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
40
53
  requirements:
41
54
  - - "="
42
55
  - !ruby/object:Gem::Version
43
- version: 0.2.1
44
- version:
56
+ segments:
57
+ - 0
58
+ - 3
59
+ - 3
60
+ version: 0.3.3
61
+ type: :runtime
62
+ version_requirements: *id003
45
63
  - !ruby/object:Gem::Dependency
46
64
  name: rack
47
- type: :runtime
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
50
67
  requirements:
51
68
  - - ~>
52
69
  - !ruby/object:Gem::Version
70
+ segments:
71
+ - 1
72
+ - 1
73
+ - 0
53
74
  version: 1.1.0
54
- version:
75
+ type: :runtime
76
+ version_requirements: *id004
55
77
  - !ruby/object:Gem::Dependency
56
78
  name: mysqlplus
57
- type: :runtime
58
- version_requirement:
59
- version_requirements: !ruby/object:Gem::Requirement
79
+ prerelease: false
80
+ requirement: &id005 !ruby/object:Gem::Requirement
60
81
  requirements:
61
82
  - - ~>
62
83
  - !ruby/object:Gem::Version
84
+ segments:
85
+ - 0
86
+ - 1
87
+ - 1
63
88
  version: 0.1.1
64
- version:
89
+ type: :runtime
90
+ version_requirements: *id005
65
91
  - !ruby/object:Gem::Dependency
66
92
  name: eventmachine
67
- type: :runtime
68
- version_requirement:
69
- version_requirements: !ruby/object:Gem::Requirement
93
+ prerelease: false
94
+ requirement: &id006 !ruby/object:Gem::Requirement
70
95
  requirements:
71
96
  - - ~>
72
97
  - !ruby/object:Gem::Version
98
+ segments:
99
+ - 0
100
+ - 12
101
+ - 10
73
102
  version: 0.12.10
74
- version:
103
+ type: :runtime
104
+ version_requirements: *id006
75
105
  description: " Cramp provides ORM and controller layers for developing asynchronous web applications.\n"
76
106
  email: pratiknaik@gmail.com
77
107
  executables: []
@@ -98,8 +128,10 @@ files:
98
128
  - lib/cramp/model/attribute.rb
99
129
  - lib/cramp/model/attribute_methods.rb
100
130
  - lib/cramp/model/base.rb
131
+ - lib/cramp/model/callbacks.rb
101
132
  - lib/cramp/model/column.rb
102
133
  - lib/cramp/model/emysql_ext.rb
134
+ - lib/cramp/model/engine/connection.rb
103
135
  - lib/cramp/model/engine.rb
104
136
  - lib/cramp/model/evented_mysql.rb
105
137
  - lib/cramp/model/finders.rb
@@ -121,18 +153,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
121
153
  requirements:
122
154
  - - ">="
123
155
  - !ruby/object:Gem::Version
156
+ segments:
157
+ - 0
124
158
  version: "0"
125
- version:
126
159
  required_rubygems_version: !ruby/object:Gem::Requirement
127
160
  requirements:
128
161
  - - ">="
129
162
  - !ruby/object:Gem::Version
163
+ segments:
164
+ - 0
130
165
  version: "0"
131
- version:
132
166
  requirements: []
133
167
 
134
168
  rubyforge_project:
135
- rubygems_version: 1.3.5
169
+ rubygems_version: 1.3.6
136
170
  signing_key:
137
171
  specification_version: 3
138
172
  summary: Async ORM and controller layer.