Class: Og::SqlStore
Overview
An abstract SQL powered store.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#conn ⇒ Object
The connection to the backend SQL RDBMS.
Attributes inherited from Store
#options, #transaction_nesting
Instance Method Summary collapse
-
#aggregate(options) ⇒ Object
(also: #count)
Perform an aggregation over query results.
-
#commit ⇒ Object
Commit a transaction.
- #delete_all(klass) ⇒ Object
-
#enable_logging ⇒ Object
– FIXME: not working.
-
#enchant(klass, manager) ⇒ Object
Enchants a class.
-
#find(options) ⇒ Object
Find a collection of objects.
-
#find_one(options) ⇒ Object
Find one object.
-
#initialize(options) ⇒ SqlStore
constructor
A new instance of SqlStore.
-
#join(obj1, obj2, table, options = nil) ⇒ Object
Relate two objects through an intermediate join table.
-
#load(pk, klass) ⇒ Object
(also: #exist?)
Loads an object from the store using the primary key.
-
#managed_tables(manager) ⇒ Object
Returns a list of tables within the database that are there to support a class managed by the supplied manager.
-
#reload(obj, pk) ⇒ Object
Reloads an object from the store.
-
#rollback ⇒ Object
Rollback a transaction.
-
#select(sql, klass) ⇒ Object
(also: #find_by_sql)
Perform a custom sql query and deserialize the results.
-
#select_one(sql, klass) ⇒ Object
(also: #find_by_sql_one)
Specialized one result version of select.
-
#sql_update(sql) ⇒ Object
Encapsulates a low level update method.
-
#start ⇒ Object
Start a new transaction.
-
#unjoin(obj1, obj2, table) ⇒ Object
Unrelate two objects be removing their relation from the join table.
-
#unmanaged_tables(manager) ⇒ Object
Returns a list of tables that exist within the database but are not managed by the supplied manager.
-
#update(obj, options = nil) ⇒ Object
If a properties collection is provided, only updates the selected properties.
-
#update_by_sql(target, set, options = nil) ⇒ Object
More generalized method, also allows for batch updates.
-
#update_properties(target, *properties) ⇒ Object
(also: #pupdate, #update_property)
Update selected properties of an object or class of objects.
Methods included from SqlUtils
blob, build_join_name, create_join_table_sql, date, escape, join_class_ordering, join_object_ordering, join_table, join_table_index, join_table_info, join_table_key, join_table_keys, ordered_join_table_keys, parse_blob, parse_date, parse_float, parse_int, parse_timestamp, quote, table, tableize, timestamp
Methods inherited from Store
#close, create, #delete, destroy, for_name, #insert, #save, #transaction
Constructor Details
#initialize(options) ⇒ SqlStore
Returns a new instance of SqlStore.
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/og/store/sql.rb', line 235 def initialize() super # The default Ruby <-> SQL type mappings, should be valid # for most RDBM systems. @typemap = { Integer => 'integer', Fixnum => 'integer', Float => 'float', String => 'text', Time => 'timestamp', Date => 'date', TrueClass => 'boolean', Object => 'text', Array => 'text', Hash => 'text', Og::Blob => 'bytea' # psql } end |
Instance Attribute Details
#conn ⇒ Object
The connection to the backend SQL RDBMS.
233 234 235 |
# File 'lib/og/store/sql.rb', line 233 def conn @conn end |
Instance Method Details
#aggregate(options) ⇒ Object Also known as: count
Perform an aggregation over query results.
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 |
# File 'lib/og/store/sql.rb', line 448 def aggregate() if .is_a?(String) sql = else aggregate = [:aggregate] || 'COUNT(*)' sql = "SELECT #{aggregate} FROM #{[:class].table}" if condition = [:condition] sql << " WHERE #{condition}" sql << " AND " if [:class].schema_inheritance_child? else sql << " WHERE " if [:class].schema_inheritance_child? end sql << "ogtype='#{[:class]}'" if [:class].schema_inheritance_child? end query(sql).first_value.to_i end |
#commit ⇒ Object
Commit a transaction.
504 505 506 507 |
# File 'lib/og/store/sql.rb', line 504 def commit @transaction_nesting -= 1 exec('COMMIT') if @transaction_nesting < 1 end |
#delete_all(klass) ⇒ Object
489 490 491 |
# File 'lib/og/store/sql.rb', line 489 def delete_all(klass) exec "DELETE FROM #{klass.table}" end |
#enable_logging ⇒ Object
– FIXME: not working. ++
260 261 262 263 264 265 266 |
# File 'lib/og/store/sql.rb', line 260 def enable_logging require 'glue/aspects' klass = self.class klass.send :include, Glue::Aspects klass.pre "Logger.info sql", :on => [:exec, :query] Glue::Aspects.wrap(klass, [:exec, :query]) end |
#enchant(klass, manager) ⇒ Object
Enchants a class.
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'lib/og/store/sql.rb', line 294 def enchant(klass, manager) # setup the table where this class is mapped. if klass.schema_inheritance_child? # farms: allow deeper inheritance (TODO: use annotation :superclass) klass.const_set 'OGTABLE', table(klass.schema_inheritance_root_class) else klass.const_set 'OGTABLE', table(klass) end klass.module_eval 'def self.table; OGTABLE; end' eval_og_allocate(klass) super unless klass.polymorphic_parent? # precompile class specific lifecycle methods. eval_og_create_schema(klass) eval_og_insert(klass) eval_og_update(klass) eval_og_delete(klass) # create the table if needed. klass.allocate.og_create_schema(self) # finish up with eval_og_read, since we can't do that # until after the table is created. # Possible FIXME: This means you can't do any find-type # operations in og_create_schema. Luckily, you're most # likely to want to do .create, which is covered by # og_insert. eval_og_read(klass) end end |
#find(options) ⇒ Object
Find a collection of objects.
Examples
User.find(:condition => ‘age > 15’, :order => ‘score ASC’, :offet => 10, :limit =>10) Comment.find(:include => :entry)
413 414 415 416 417 |
# File 'lib/og/store/sql.rb', line 413 def find() klass = [:class] sql = (klass, ) read_all(query(sql), klass, ) end |
#find_one(options) ⇒ Object
Find one object.
421 422 423 424 425 426 427 |
# File 'lib/og/store/sql.rb', line 421 def find_one() klass = [:class] # gmosx, THINK: should not set this by default. # options[:limit] ||= 1 sql = (klass, ) read_one(query(sql), klass, ) end |
#join(obj1, obj2, table, options = nil) ⇒ Object
Relate two objects through an intermediate join table. Typically used in joins_many and many_to_many relations.
470 471 472 473 474 475 476 477 478 |
# File 'lib/og/store/sql.rb', line 470 def join(obj1, obj2, table, = nil) first, second = join_object_ordering(obj1, obj2) first_key, second_key = ordered_join_table_keys(obj1.class, obj2.class) if exec "INSERT INTO #{table} (#{first_key},#{second_key}, #{.keys.join(',')}) VALUES (#{first.pk},#{second.pk}, #{.values.map { |v| quote(v) }.join(',')})" else exec "INSERT INTO #{table} (#{first_key},#{second_key}) VALUES (#{first.pk}, #{second.pk})" end end |
#load(pk, klass) ⇒ Object Also known as: exist?
Loads an object from the store using the primary key.
335 336 337 338 339 340 |
# File 'lib/og/store/sql.rb', line 335 def load(pk, klass) sql = "SELECT * FROM #{klass::OGTABLE} WHERE #{klass.pk_symbol}=#{pk}" sql << " AND ogtype='#{klass}'" if klass.schema_inheritance_child? res = query sql read_one(res, klass) end |
#managed_tables(manager) ⇒ Object
Returns a list of tables within the database that are there to support a class managed by the supplied manager.
283 284 285 286 287 288 289 290 |
# File 'lib/og/store/sql.rb', line 283 def managed_tables(manager) ret = Array.new manager.managed_classes.each do |klass| ret << klass::OGTABLE ret.concat(klass.relations.reject{|rel| not rel.[:join_table]}.map{|rel| rel.[:join_table]}) end ret end |
#reload(obj, pk) ⇒ Object
Reloads an object from the store.
345 346 347 348 349 350 351 352 353 |
# File 'lib/og/store/sql.rb', line 345 def reload(obj, pk) raise 'Cannot reload unmanaged object' unless obj.saved? sql = "SELECT * FROM #{obj.class.table} WHERE #{obj.class.pk_symbol}=#{pk}" sql << " AND ogtype='#{obj.class}'" if obj.class.schema_inheritance_child? res = query sql obj.og_read(res.next, 0) ensure res.close if res end |
#rollback ⇒ Object
Rollback a transaction.
511 512 513 514 |
# File 'lib/og/store/sql.rb', line 511 def rollback @transaction_nesting -= 1 exec('ROLLBACK') if @transaction_nesting < 1 end |
#select(sql, klass) ⇒ Object Also known as: find_by_sql
Perform a custom sql query and deserialize the results.
432 433 434 435 |
# File 'lib/og/store/sql.rb', line 432 def select(sql, klass) sql = "SELECT * FROM #{klass.table} " + sql unless sql =~ /SELECT/ read_all(query(sql), klass) end |
#select_one(sql, klass) ⇒ Object Also known as: find_by_sql_one
Specialized one result version of select.
440 441 442 443 |
# File 'lib/og/store/sql.rb', line 440 def select_one(sql, klass) sql = "SELECT * FROM #{klass.table} " + sql unless sql =~ /SELECT/ read_one(query(sql), klass) end |
#sql_update(sql) ⇒ Object
Encapsulates a low level update method.
520 521 522 523 |
# File 'lib/og/store/sql.rb', line 520 def sql_update(sql) exec(sql) # return affected rows. end |
#start ⇒ Object
Start a new transaction.
497 498 499 500 |
# File 'lib/og/store/sql.rb', line 497 def start exec('START TRANSACTION') if @transaction_nesting < 1 @transaction_nesting += 1 end |
#unjoin(obj1, obj2, table) ⇒ Object
Unrelate two objects be removing their relation from the join table.
483 484 485 486 487 |
# File 'lib/og/store/sql.rb', line 483 def unjoin(obj1, obj2, table) first, second = join_object_ordering(obj1, obj2) first_key, second_key = ordered_join_table_keys(obj1.class, obj2.class) exec "DELETE FROM #{table} WHERE #{first_key}=#{first.pk} AND #{second_key}=#{second.pk}" end |
#unmanaged_tables(manager) ⇒ Object
Returns a list of tables that exist within the database but are not managed by the supplied manager.
271 272 273 274 275 276 277 278 |
# File 'lib/og/store/sql.rb', line 271 def unmanaged_tables(manager) ret = Array.new mt = managed_tables(manager) @conn.list_tables.each do |table| ret << table unless mt.include?(table) end ret end |
#update(obj, options = nil) ⇒ Object
If a properties collection is provided, only updates the selected properties. Pass the required properties as symbols or strings. – gmosx, THINK: condition is not really useful here :( ++
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
# File 'lib/og/store/sql.rb', line 362 def update(obj, = nil) if and properties = [:only] if properties.is_a?(Array) set = [] for p in properties set << "#{p}=#{quote(obj.send(p))}" end set = set.join(',') else set = "#{properties}=#{quote(obj.send(properties))}" end sql = "UPDATE #{obj.class.table} SET #{set} WHERE #{obj.class.pk_symbol}=#{obj.pk}" sql << " AND #{[:condition]}" if [:condition] sql_update(sql) else obj.og_update(self, ) end end |
#update_by_sql(target, set, options = nil) ⇒ Object
More generalized method, also allows for batch updates.
392 393 394 395 396 397 398 399 400 401 402 403 404 |
# File 'lib/og/store/sql.rb', line 392 def update_by_sql(target, set, = nil) set = set.gsub(/@/, '') if target.is_a?(Class) sql = "UPDATE #{target.table} SET #{set} " sql << " WHERE #{[:condition]}" if and [:condition] sql_update(sql) else sql = "UPDATE #{target.class.table} SET #{set} WHERE #{target.class.pk_symbol}=#{target.pk}" sql << " AND #{[:condition]}" if and [:condition] sql_update(sql) end end |
#update_properties(target, *properties) ⇒ Object Also known as: pupdate, update_property
Update selected properties of an object or class of objects.
384 385 386 |
# File 'lib/og/store/sql.rb', line 384 def update_properties(target, *properties) update(target, :only => properties) end |