Class: Norma::Database

Inherits:
Object show all
Defined in:
lib/norma/database.rb

Overview

Base class for database adapters. This class is modeled for a minimal Postgresql adapter as a reference point.

Direct Known Subclasses

Mysql, Postgres

Defined Under Namespace

Classes: InterfaceError, Mysql, Postgres

Constant Summary collapse

CORE =
[String, Symbol, Fixnum, Float, Range, Time, Array, Hash]

Instance Method Summary collapse

Constructor Details

#initialize(connection, logger = nil) ⇒ Database

Returns a new instance of Database.



14
15
16
17
18
19
# File 'lib/norma/database.rb', line 14

def initialize(connection, logger = nil)
  @connection = connection
  @logger = logger
  @runtime = 0
  @cache = {}
end

Instance Method Details

#bootstrapObject

Raises:



21
22
23
# File 'lib/norma/database.rb', line 21

def bootstrap
  raise InterfaceError, "no bootstrap method"
end

#delete(klass, id) ⇒ Object

Delete a record.

Raises:



36
37
38
# File 'lib/norma/database.rb', line 36

def delete(klass, id)
  raise InterfaceError, "no save method"
end

#insert_class_sql(object) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/norma/database.rb', line 101

def insert_class_sql(object)
  return '' unless respond_to?("sql#{object.class}")

  atts = send("sql#{object.class}", object)        
  keys = atts.keys.join(',')
  vals = atts.values.join(',')

  sql = ''
  sql << %|INSERT INTO obj#{object.class} |
  sql << %|(id, #{keys})\n|
  sql << %|VALUES (#{object.record_id}, #{vals})|
  sql << ';'
  sql
end

#insert_ivar_sql(object, field, value) ⇒ Object



127
128
129
130
131
132
133
134
# File 'lib/norma/database.rb', line 127

def insert_ivar_sql(object, field, value)
  name = field.sub(/^@/,'')
  sql = ''
  sql << %|INSERT INTO ivar |
  sql << %|(obj_id, val_id, name)\n|
  sql << %|VALUES (#{object.record_id}, #{value.record_id}, '#{name}')|
  sql << ';'
end

#insert_object_sql(object) ⇒ Object



79
80
81
82
83
84
85
86
# File 'lib/norma/database.rb', line 79

def insert_object_sql(object)
  sql = ''
  sql << %|INSERT INTO obj |
  sql << %|(id, class)\n|
  sql << %|VALUES (#{object.record_id}, '#{object.class}')|
  sql << ';'
  sql
end

#insert_sql(object) ⇒ Object



64
65
66
# File 'lib/norma/database.rb', line 64

def insert_sql(object)
  insert_object_sql(object) + insert_class_sql(object)
end

#load(id, object = nil) ⇒ Object

Load a record. This calls read, but caches the result. This is very important, otherwise an object will be loaded more than once.



54
55
56
# File 'lib/norma/database.rb', line 54

def load( id, object=nil )
  @cache[id] ||= read(id)
end

#mint_idObject

Return next available object record index.

Raises:



46
47
48
# File 'lib/norma/database.rb', line 46

def mint_id
  raise InterfaceError, "no mint_id method"
end

#newArray(rec) ⇒ Object



210
211
212
213
214
215
216
# File 'lib/norma/database.rb', line 210

def newArray(rec)
  ary = []
  rec[1].scan(/\d+/).each do |i|
    ary << load(i.to_i)
  end
  ary
end

#newFixnum(rec) ⇒ Object



194
195
196
# File 'lib/norma/database.rb', line 194

def newFixnum(rec)
  Integer(rec[1])
end

#newFloat(rec) ⇒ Object



198
199
200
# File 'lib/norma/database.rb', line 198

def newFloat(rec)
  Float(rec[1])
end

#newHash(rec) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
# File 'lib/norma/database.rb', line 218

def newHash(rec)
  keys = []
  rec[1].scan(/\d+/).each do |id|
    keys << load(id.to_i)
  end
  vals = []
  rec[2].scan(/\d+/).each do |id|
    vals << load(id.to_i)
  end
  Hash[*keys.zip(vals)]
end

#newRange(rec) ⇒ Object



202
203
204
# File 'lib/norma/database.rb', line 202

def newRange(rec)
  Range.new(rec[1], rec[2], rec[3])
end

#newString(rec) ⇒ Object



190
191
192
# File 'lib/norma/database.rb', line 190

def newString(rec)
  rec[1]
end

#newSymbol(rec) ⇒ Object

Record -> Object #



185
186
187
# File 'lib/norma/database.rb', line 185

def newSymbol(rec)
  rec[1].to_sym
end

#newTime(rec) ⇒ Object



206
207
208
# File 'lib/norma/database.rb', line 206

def newTime(rec)
  rec[1]  # TODO: parse time string
end

#read(id, object = nil) ⇒ Object

Read a record.

Raises:



26
27
28
# File 'lib/norma/database.rb', line 26

def read(id, object=nil)
  raise InterfaceError, "no read method"
end

#save(klass, obj, id = nil) ⇒ Object

Save (or insert) a record.

Raises:



31
32
33
# File 'lib/norma/database.rb', line 31

def save(klass, obj, id=nil)
  raise InterfaceError, "no save method"
end

#select(&block) ⇒ Object

Select records.

Raises:



41
42
43
# File 'lib/norma/database.rb', line 41

def select(&block)
  raise InterfaceError, "no select method"
end

#sqlArray(object) ⇒ Object



171
172
173
# File 'lib/norma/database.rb', line 171

def sqlArray(object)
  { :values => "'{" + object.map{|o|"#{o.record_id}"}.join(',') + "}'" }
end

#sqlFixnum(object) ⇒ Object



153
154
155
# File 'lib/norma/database.rb', line 153

def sqlFixnum(object)
  { :value => object.to_i }
end

#sqlFloat(object) ⇒ Object



157
158
159
# File 'lib/norma/database.rb', line 157

def sqlFloat(object)
  { :value => object.to_f }
end

#sqlHash(object) ⇒ Object



175
176
177
178
179
# File 'lib/norma/database.rb', line 175

def sqlHash(object)
  { :keys => object.keys,
    :values => object.values 
  }
end

#sqlRange(object) ⇒ Object



161
162
163
164
165
# File 'lib/norma/database.rb', line 161

def sqlRange(object)
  { :begins    => object.begin,
    :ends      => object.end,
    :exclusive => object.exclude_end? }
end

#sqlString(object) ⇒ Object



149
150
151
# File 'lib/norma/database.rb', line 149

def sqlString(object)
  { :value => object.inspect }
end

#sqlSymbol(object) ⇒ Object

def sqlObject(object)

object.inspect

end



145
146
147
# File 'lib/norma/database.rb', line 145

def sqlSymbol(object)
  { :value => object.to_s.inspect }
end

#sqlTime(object) ⇒ Object



167
168
169
# File 'lib/norma/database.rb', line 167

def sqlTime(object)
  { :value => object.strftime('%Y-%m-%d %H:%M:%S').inspect }
end

#update_class_sql(object) ⇒ Object



89
90
91
92
93
94
95
96
97
98
# File 'lib/norma/database.rb', line 89

def update_class_sql(object)
  return '' unless respond_to?("sql#{object.class}")
  sql = ''
  sql << %|UPDATE obj#{object.class}\n|
  sql << %|SET |
  sql << send("sql#{object.class}").map{|k,v|"#{k}=#{v}"}.join(' ')
  sql << %|\nWHERE id=#{object.id}|
  sql << ';'
  sql
end

#update_ivar_sql(object, field, value) ⇒ Object



117
118
119
120
121
122
123
124
# File 'lib/norma/database.rb', line 117

def update_ivar_sql(object, field, value)
  name = field.sub(/^@/,'')
  sql = ''
  sql << %|UPDATE ivar\n|
  sql << %|SET val_id=#{value.record_id}\n|
  sql << %|WHERE obj_id=#{object.record_id} AND name='#{name}'|
  sql << ';'
end

#update_object_sql(object) ⇒ Object



69
70
71
72
73
74
75
76
# File 'lib/norma/database.rb', line 69

def update_object_sql(object)
  sql = ''
  sql << %|UPDATE obj\n|
  sql << %|SET class='#{object.class}'\n|
  sql << %|WHERE id=#{object.record_id}|
  sql << ';'
  sql
end

#update_sql(object) ⇒ Object



59
60
61
# File 'lib/norma/database.rb', line 59

def update_sql(object)
  update_object_sql(object) + update_class_sql(object)
end