Rubernate 0.1.4 → 0.1.5

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.
@@ -32,8 +32,7 @@ module Callbacks
32
32
  end
33
33
 
34
34
  # Invoked if object referred by this one has been deleted
35
- # TODO: implement invokations
36
- def on_lose_ref refered_by
35
+ def on_lose_ref ref_prop, ref_obj
37
36
  end
38
37
  end
39
38
 
@@ -21,6 +21,16 @@ module DBI
21
21
  HASH_TIME_REF = (PARAM_FLAG_HASH | PARAM_FLAG_TIME).to_i
22
22
  HASH_DATE_REF = (PARAM_FLAG_HASH | PARAM_FLAG_DATE).to_i
23
23
 
24
+ # Indexes of columns of R_PARAMS table
25
+ P_PK = 0
26
+ P_NAME = 1
27
+ P_FLAGS = 2
28
+ P_INT = 3
29
+ P_FLT = 4
30
+ P_STR = 5
31
+ P_TIME = 6
32
+ P_REF = 7
33
+
24
34
  # Holds configuration information and serves as factory for Runtime objects.
25
35
  class Configuration
26
36
  # Accepts Runtime impl class, db initializer class, database url, user name, and user password
@@ -69,6 +79,9 @@ module DBI
69
79
  DELETE_OBJECT = <<-SQL
70
80
  DELETE FROM R_OBJECTS WHERE OBJECT_PK = ?
71
81
  SQL
82
+ CREATE_PEER = <<-SQL
83
+ INSERT INTO R_OBJECTS (OBJECT_PK, OBJECT_CLASS) values (?, ?)
84
+ SQL
72
85
  SAVE_PARAMS = <<-SQL
73
86
  INSERT INTO R_PARAMS VALUES (?, ?, ?, ?, ?, ?, ?, ?)
74
87
  SQL
@@ -87,17 +100,9 @@ module DBI
87
100
  WHERE O.OBJECT_PK = ?
88
101
  SQL
89
102
 
90
- # R_PARAMS table's column's indexes
91
- P_PK = 0
92
- P_NAME = 1
93
- P_FLAGS = 2
94
- P_INT = 3
95
- P_FLT = 4
96
- P_STR = 5
97
- P_TIME = 6
98
- P_REF = 7 # Refered object PK
99
- P_REF_CLASS = 8 # Refered object Class
100
- P_CLASS = 9 # Self object Class
103
+ # Adition columns for R_PARAMS table joined ...
104
+ P_REF_CLASS = 8 # with REF_VALUE
105
+ P_CLASS = 9 # with OBJECT_PK
101
106
 
102
107
  attr :dbh, false
103
108
 
@@ -116,7 +121,7 @@ module DBI
116
121
  @dbh.prepare SAVE_PARAMS do |sth|
117
122
  for object in objects
118
123
  object.peer.each {|name, param|
119
- save_param sth, object.primary_key, name.to_s, param
124
+ save_param sth, object, name.to_s, param
120
125
  }
121
126
  end
122
127
  end
@@ -184,16 +189,16 @@ module DBI
184
189
  @dbh.disconnect rescue Log.error 'Error during disconnect in session failed state'
185
190
  end
186
191
  private
187
- def save_param sth, pk, name, param
192
+ def save_param sth, obj, name, param
188
193
  case param
189
- when Persistent: save_ref sth, pk, name, param
190
- when Hash: save_hash sth, pk, name, param
191
- when Array: save_array sth, pk, name, param
192
- when Integer: save_int sth, pk, name, param
193
- when Float: save_float sth, pk, name, param
194
- when Time: save_time sth, pk, name, param
195
- when Date: save_date sth, pk, name, param
196
- else save_str sth, pk, name, param.to_s
194
+ when Persistent: save_ref sth, obj, name, param
195
+ when Hash: save_hash sth, obj, name, param
196
+ when Array: save_array sth, obj, name, param
197
+ when Integer: save_int sth, obj.primary_key, name, param
198
+ when Float: save_float sth, obj.primary_key, name, param
199
+ when Time: save_time sth, obj.primary_key, name, param
200
+ when Date: save_date sth, obj.primary_key, name, param
201
+ else save_str sth, obj.primary_key, name, param.to_s
197
202
  end
198
203
  end
199
204
 
@@ -217,16 +222,17 @@ module DBI
217
222
  sth.execute pk, name, PARAM_FLAG_DATE, nil, nil, nil, TimeType.new(date), nil
218
223
  end
219
224
 
220
- def save_ref sth, pk, name, ref
221
- sth.execute pk, name, PARAM_FLAG_REF, nil, nil, nil, nil, ref.primary_key unless ref.removed?
225
+ def save_ref sth, obj, name, ref
226
+ sth.execute obj.primary_key, name, PARAM_FLAG_REF, nil, nil, nil, nil,
227
+ ref.primary_key unless ref_lost? obj, name, ref
222
228
  end
223
229
 
224
- def save_hash sth, pk, name, hash
225
- hash.delete_if {|key, ref| ref.removed?} # Discard removed objects
230
+ def save_hash sth, obj, name, hash
231
+ ref_lost_hash obj, name, hash
226
232
  if hash.empty?
227
- sth.execute pk, name, PARAM_FLAG_HASH, 0, nil, nil, nil, nil
233
+ sth.execute obj.primary_key, name, PARAM_FLAG_HASH, 0, nil, nil, nil, nil
228
234
  else
229
- hash.each {|key, ref| save_key_value sth, pk, name, key, ref.primary_key}
235
+ hash.each {|key, ref| save_key_value sth, obj.primary_key, name, key, ref.primary_key}
230
236
  end
231
237
  end
232
238
 
@@ -235,20 +241,20 @@ module DBI
235
241
  when Integer: sth.execute pk, name, HASH_INT_REF, key, nil, nil, nil, ref
236
242
  when Float: sth.execute pk, name, HASH_FLOAT_REF, nil, key, nil, nil, ref
237
243
  when String: sth.execute pk, name, HASH_STRING_REF, nil, nil, key, nil, ref
238
- when ::Date: sth.execute pk, name, HASH_DATE_REF, nil, nil, nil, TimeType.new(key), ref
239
- when ::Time: sth.execute pk, name, HASH_TIME_REF, nil, nil, nil, TimeType.new(key), ref
244
+ when ::Date: sth.execute pk, name, HASH_DATE_REF, nil, nil, nil, TimeType.new(key), ref
245
+ when ::Time: sth.execute pk, name, HASH_TIME_REF, nil, nil, nil, TimeType.new(key), ref
240
246
  when nil: sth.execute pk, name, PARAM_FLAG_HASH, nil, nil, nil, nil, ref
241
247
  else
242
248
  raise "invalid hash key value #{key}"
243
249
  end
244
250
  end
245
251
 
246
- def save_array sth, pk, name, array
247
- array.delete_if {|ref| !ref or ref.removed?} # Discard removed and nil items
252
+ def save_array sth, obj, name, array
253
+ ref_lost_array obj, name, array
248
254
  if array.empty? # Empty arrays should also be stored
249
- sth.execute pk, name, ARRAY_INT_REF, 0, nil, nil, nil, nil
255
+ sth.execute obj.primary_key, name, ARRAY_INT_REF, 0, nil, nil, nil, nil
250
256
  else
251
- array.each_index {|idx| sth.execute pk, name,
257
+ array.each_index {|idx| sth.execute obj.primary_key, name,
252
258
  ARRAY_INT_REF, idx, nil, nil, nil, array[idx].primary_key}
253
259
  end
254
260
  end
@@ -1,4 +1,5 @@
1
1
  require 'dbi'
2
+ require 'rubernate/impl/dbi_generic'
2
3
 
3
4
  module Rubernate
4
5
  module DBI
@@ -1,4 +1,5 @@
1
1
  require 'dbi'
2
+ require 'rubernate/impl/dbi_generic'
2
3
 
3
4
  module Rubernate
4
5
  module DBI
@@ -6,9 +7,6 @@ module DBI
6
7
  SELECT_NEXT_PK = <<-SQL
7
8
  SELECT R_PK_SEQUENCE.NEXTVAL FROM DUAL
8
9
  SQL
9
- CREATE_PEER = <<-SQL
10
- INSERT INTO R_OBJECTS (OBJECT_PK, OBJECT_CLASS) values (?, ?)
11
- SQL
12
10
 
13
11
  # Creates record in r_objects for specified object
14
12
  def create object
@@ -0,0 +1,33 @@
1
+ require 'dbi'
2
+ require 'rubernate/impl/dbi_generic'
3
+
4
+ module Rubernate
5
+ module DBI
6
+ class PgRuntime < Runtime
7
+ SELECT_NEXT_PK = <<-SQL
8
+ SELECT NEXTVAL('R_PK_SEQUENCE')
9
+ SQL
10
+
11
+ # Invokes super and then issues 'BEGIN'
12
+ def initialize dbh
13
+ super
14
+ dbh.do 'BEGIN'
15
+ end
16
+
17
+ # Creates record in r_objects for specified object
18
+ def create object
19
+ object.peer = Rubernate::Peer.new
20
+ object.primary_key = @dbh.select_one(SELECT_NEXT_PK)[0].to_i
21
+ @dbh.do CREATE_PEER, object.primary_key, object.class.name
22
+ object.peer.dirty = true
23
+ object.primary_key
24
+ end
25
+
26
+ # Issues 'COMMIT' against database.
27
+ def close
28
+ dbh.do 'COMMIT'
29
+ super
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,9 +1,11 @@
1
1
  require 'rubernate/queries'
2
2
 
3
3
  module Rubernate
4
+ # This module contains implementation of Runtime that operates with memory instead database.
5
+ # It is intended only of testing.
4
6
  module Memory
5
7
  module Queries
6
- class Query < Rubernate::Queries::Generic::Expr
8
+ class Query < Rubernate::Queries::Expr
7
9
  def params v
8
10
  case v
9
11
  when Array: v
@@ -12,6 +14,7 @@ module Memory
12
14
  end
13
15
  end
14
16
  end
17
+
15
18
  class Factory < Rubernate::Queries::Factory
16
19
  def initialize
17
20
  super
@@ -19,6 +22,7 @@ module Memory
19
22
  end
20
23
  end
21
24
  end
25
+
22
26
  class Reference
23
27
  attr_reader :primary_key, :object_class
24
28
  def initialize pk, klass
@@ -101,24 +105,26 @@ module Memory
101
105
  def save objects
102
106
  objects = [objects] unless objects.kind_of? Array
103
107
  for object in objects
104
- @database[object.primary_key] = [object.class, save_peer(object.peer)]
108
+ @database[object.primary_key] = [object.class, save_peer(object)]
105
109
  object.peer.dirty = false
106
110
  end
107
111
  end
108
112
 
109
- def save_peer peer
113
+ def save_peer obj
110
114
  result = {}
111
- peer.each {|key, value| result[key] = save_param value }
115
+ obj.peer.each {|key, value| result[key] = save_param obj, key, value}
112
116
  result
113
117
  end
114
118
 
115
- def save_param value
119
+ def save_param obj, param, value
116
120
  case value
117
- when Persistent:
118
- Reference.new value.primary_key, value.class
121
+ when Persistent:
122
+ Reference.new value.primary_key, value.class unless ref_lost? obj, param, value
119
123
  when Array:
124
+ ref_lost_array obj, param, value
120
125
  value.collect{ |item| Reference.new item.primary_key, item.class }
121
126
  when Hash:
127
+ ref_lost_hash obj, param, value
122
128
  result = {}
123
129
  value.each {|key, value|
124
130
  result[key] = Reference.new value.primary_key, value.class
@@ -0,0 +1,25 @@
1
+ require 'erb'
2
+
3
+ module Rubernate
4
+ module DBI
5
+ # Base class for all database intitalizators
6
+ class GenericInit
7
+ # Used to remove leading spaces in scripts
8
+ INDENT = /^ /
9
+
10
+ # Prints initialization script and tryes to initialize databaes database if dbh is given.
11
+ # Must be implemented by subclasses.
12
+ def init_db dbh=nil
13
+ raise 'Not implemented...'
14
+ end
15
+
16
+ private
17
+ def exec_ddl dbh, stat
18
+ dbh.do stat
19
+ 'done'
20
+ rescue Exception => e
21
+ "failed: #{e}"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,13 +1,14 @@
1
1
  require 'erb'
2
+ require 'rubernate/init/init_generic'
2
3
 
3
4
  module Rubernate
4
5
  module DBI
5
- class MySqlInit
6
+ class MySqlInit < GenericInit
6
7
  CREATE_R_OBJECTS = %q{
7
8
  CREATE TABLE R_OBJECTS (
8
9
  OBJECT_PK INTEGER(20) PRIMARY KEY AUTO_INCREMENT,
9
10
  OBJECT_CLASS VARCHAR(100) NOT NULL) ENGINE=InnoDB;
10
- }.gsub(/^ /, '')
11
+ }.gsub(INDENT, '')
11
12
 
12
13
  CREATE_R_PARAMS = %q{
13
14
  CREATE TABLE R_PARAMS (
@@ -21,13 +22,13 @@ module DBI
21
22
  REF_VALUE INTEGER(20),
22
23
  CONSTRAINT R_PARAM_FK FOREIGN KEY (OBJECT_PK) REFERENCES R_OBJECTS(OBJECT_PK) ON DELETE CASCADE,
23
24
  CONSTRAINT R_REF_FK FOREIGN KEY (REF_VALUE) REFERENCES R_OBJECTS(OBJECT_PK) ON DELETE CASCADE) ENGINE=InnoDB;
24
- }.gsub(/^ /, '')
25
+ }.gsub(INDENT, '')
25
26
  CREATE_INDEX_O_PK_CLASS = %q{
26
27
  CREATE INDEX R_O_PK_CLASS ON R_OBJECTS (OBJECT_PK ASC, OBJECT_CLASS);
27
- }.gsub(/^ /, '')
28
+ }.gsub(INDENT, '')
28
29
  CREATE_INDEX_P_PK_NAME = %q{
29
30
  CREATE INDEX R_P_PK_NAME ON R_PARAMS (OBJECT_PK ASC, NAME);
30
- }.gsub(/^ /, '')
31
+ }.gsub(INDENT, '')
31
32
 
32
33
  TEMPLATE = %q{
33
34
  #
@@ -46,10 +47,10 @@ module DBI
46
47
  #
47
48
  # End
48
49
  #
49
- }.gsub(/^ /, '')
50
+ }.gsub(INDENT, '')
50
51
 
51
52
  # Prints initialization script and tryes to initialize databaes database if dbh is given.
52
- def self.init_db dbh=nil
53
+ def init_db dbh=nil
53
54
  puts ERB.new(TEMPLATE).result(binding)
54
55
  if dbh
55
56
  puts "\nInitializing database ... "
@@ -59,13 +60,6 @@ module DBI
59
60
  puts "Creation of index on r_params - #{exec_ddl dbh, CREATE_INDEX_P_PK_NAME}"
60
61
  end
61
62
  end
62
-
63
- def self.exec_ddl dbh, stat
64
- dbh.do stat
65
- 'done'
66
- rescue Exception => e
67
- "failed: #{e}"
68
- end
69
63
  end
70
64
  end
71
65
  end
@@ -1,13 +1,14 @@
1
1
  require 'erb'
2
+ require 'rubernate/init/init_generic'
2
3
 
3
4
  module Rubernate
4
5
  module DBI
5
- class OracleInit
6
+ class OracleInit < GenericInit
6
7
  CREATE_R_OBJECTS = %q{
7
8
  CREATE TABLE R_OBJECTS (
8
9
  OBJECT_PK NUMBER(20) PRIMARY KEY,
9
10
  OBJECT_CLASS VARCHAR2(100) NOT NULL)
10
- }.gsub(/^ /, '')
11
+ }.gsub(INDENT, '')
11
12
 
12
13
  CREATE_R_PARAMS = %q{
13
14
  CREATE TABLE R_PARAMS (
@@ -21,16 +22,16 @@ module DBI
21
22
  REF_VALUE NUMBER(20),
22
23
  CONSTRAINT R_PARAM_FK FOREIGN KEY (OBJECT_PK) REFERENCES R_OBJECTS(OBJECT_PK) ON DELETE CASCADE,
23
24
  CONSTRAINT R_REF_FK FOREIGN KEY (REF_VALUE) REFERENCES R_OBJECTS(OBJECT_PK) ON DELETE CASCADE)
24
- }.gsub(/^ /, '')
25
+ }.gsub(INDENT, '')
25
26
  CREATE_INDEX_O_PK_CLASS = %q{
26
27
  CREATE INDEX R_O_PK_CLASS ON R_OBJECTS (OBJECT_PK ASC, OBJECT_CLASS)
27
- }.gsub(/^ /, '')
28
+ }.gsub(INDENT, '')
28
29
  CREATE_INDEX_P_PK_NAME = %q{
29
30
  CREATE INDEX R_P_PK_NAME ON R_PARAMS (OBJECT_PK ASC, NAME)
30
- }.gsub(/^ /, '')
31
+ }.gsub(INDENT, '')
31
32
  CREATE_R_PK_SEQUENCE = %q{
32
33
  CREATE SEQUENCE R_PK_SEQUENCE START WITH 1001 INCREMENT BY 1
33
- }.gsub(/^ /, '')
34
+ }.gsub(INDENT, '')
34
35
 
35
36
  TEMPLATE = %q{
36
37
  /**
@@ -57,15 +58,14 @@ module DBI
57
58
  /**
58
59
  * Create primary key sequence
59
60
  */ <%= CREATE_R_PK_SEQUENCE %>/
60
-
61
61
 
62
62
  /**
63
63
  * End
64
64
  */
65
- }.gsub(/^ /, '')
65
+ }.gsub(INDENT, '')
66
66
 
67
67
  # Prints initialization script and tryes to initialize databaes database if dbh is given.
68
- def self.init_db dbh=nil
68
+ def init_db dbh
69
69
  puts ERB.new(TEMPLATE).result(binding)
70
70
  if dbh
71
71
  puts "\nInitializing database ... "
@@ -76,13 +76,6 @@ module DBI
76
76
  puts "Creation of pk sequence - #{exec_ddl dbh, CREATE_R_PK_SEQUENCE}"
77
77
  end
78
78
  end
79
-
80
- def self.exec_ddl dbh, stat
81
- dbh.do stat
82
- 'done'
83
- rescue Exception => e
84
- "failed: #{e}"
85
- end
86
79
  end
87
80
  end
88
81
  end
@@ -0,0 +1,78 @@
1
+ require 'erb'
2
+ require 'rubernate/init/init_generic'
3
+
4
+ module Rubernate
5
+ module DBI
6
+ class PgInit < GenericInit
7
+ CREATE_R_OBJECTS = %q{
8
+ CREATE TABLE R_OBJECTS (
9
+ OBJECT_PK INTEGER PRIMARY KEY,
10
+ OBJECT_CLASS VARCHAR(100))
11
+ }.gsub(INDENT, '')
12
+ CREATE_R_PARAMS = %q{
13
+ CREATE TABLE R_PARAMS (
14
+ OBJECT_PK INTEGER NOT NULL REFERENCES R_OBJECTS(OBJECT_PK) ON DELETE CASCADE,
15
+ NAME VARCHAR NOT NULL,
16
+ FLAGS INTEGER NOT NULL,
17
+ INT_VALUE INTEGER,
18
+ FLT_VALUE FLOAT,
19
+ STR_VALUE VARCHAR,
20
+ DAT_VALUE TIMESTAMP WITH TIME ZONE,
21
+ REF_VALUE INTEGER REFERENCES R_OBJECTS(OBJECT_PK) ON DELETE CASCADE)
22
+ }.gsub(INDENT, '')
23
+ CREATE_INDEX_O_PK_CLASS = %q{
24
+ CREATE INDEX R_O_PK_CLASS ON R_OBJECTS (OBJECT_PK, OBJECT_CLASS)
25
+ }.gsub(INDENT, '')
26
+ CREATE_INDEX_P_PK_NAME = %q{
27
+ CREATE INDEX R_O_CLASS ON R_OBJECTS (OBJECT_CLASS)
28
+ }.gsub(INDENT, '')
29
+ CREATE_R_PK_SEQUENCE = %q{
30
+ CREATE SEQUENCE R_PK_SEQUENCE;
31
+ }.gsub(INDENT, '')
32
+
33
+ TEMPLATE = %q{
34
+ /**
35
+ * Creates Rubernate tables for PostgreSQL database.
36
+ * Copyright (C) 2006 Andrey Ryabov <andrey_ryabov@bk.ru>
37
+ */
38
+
39
+ /**
40
+ * Create r_objects table
41
+ */ <%= CREATE_R_OBJECTS %>/
42
+
43
+ /**
44
+ * Create r_params table
45
+ */ <%= CREATE_R_PARAMS %>/
46
+
47
+ /**
48
+ * Create index on r_objects
49
+ */ <%= CREATE_INDEX_O_PK_CLASS %>/
50
+
51
+ /**
52
+ * Create index on r_params
53
+ */ <%= CREATE_INDEX_P_PK_NAME %>/
54
+
55
+ /**
56
+ * Create primary key sequence
57
+ */ <%= CREATE_R_PK_SEQUENCE %>/
58
+
59
+ /**
60
+ * End
61
+ */
62
+ }.gsub(INDENT, '')
63
+
64
+ # Prints initialization script and tryes to initialize databaes database if dbh is given.
65
+ def init_db dbh=nil
66
+ puts ERB.new(TEMPLATE).result(binding)
67
+ if dbh
68
+ puts "\nInitializing database ... "
69
+ puts "Creation of r_objects - #{exec_ddl dbh, CREATE_R_OBJECTS}"
70
+ puts "Creation of r_params - #{exec_ddl dbh, CREATE_R_PARAMS}"
71
+ puts "Creation of pk sequence - #{exec_ddl dbh, CREATE_R_PK_SEQUENCE}"
72
+ puts "Creation of index on r_objects - #{exec_ddl dbh, CREATE_INDEX_O_PK_CLASS}"
73
+ puts "Creation of index on r_params - #{exec_ddl dbh, CREATE_INDEX_P_PK_NAME}"
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end