cramp 0.10 → 0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.