Class: Og::SqlStore
Overview
An abstract SQL powered store.
Direct Known Subclasses
KirbyStore, MysqlStore, Sqlite2Store, SqliteStore, SqlserverStore
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_boolean, parse_date, parse_float, parse_int, parse_timestamp, quote, table, tableize, timestamp
Methods inherited from Store
#close, create, #delete, destroy, for_name, #force_save!, #insert, #save, #transaction
Constructor Details
#initialize(options) ⇒ SqlStore
Returns a new instance of SqlStore.
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/og/store/sql.rb', line 248 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.
246 247 248 |
# File 'lib/og/store/sql.rb', line 246 def conn @conn end |
Instance Method Details
#aggregate(options) ⇒ Object Also known as: count
Perform an aggregation over query results.
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 |
# File 'lib/og/store/sql.rb', line 469 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.
527 528 529 530 |
# File 'lib/og/store/sql.rb', line 527 def commit @transaction_nesting -= 1 exec('COMMIT') if @transaction_nesting < 1 end |
#delete_all(klass) ⇒ Object
510 511 512 513 514 |
# File 'lib/og/store/sql.rb', line 510 def delete_all(klass) sql = "DELETE FROM #{klass.table}" sql << " WHERE ogtype='#{klass}'" if klass.schema_inheritance? and not klass.schema_inheritance_root? exec sql end |
#enable_logging ⇒ Object
– FIXME: not working. ++
273 274 275 276 277 278 279 |
# File 'lib/og/store/sql.rb', line 273 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.
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/og/store/sql.rb', line 307 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 #-- # FIXME: use an SQL agnostic name like schema instead # of table. #++ 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)
434 435 436 437 438 |
# File 'lib/og/store/sql.rb', line 434 def find() klass = [:class] sql = (klass, ) read_all(query(sql), klass, ) end |
#find_one(options) ⇒ Object
Find one object.
442 443 444 445 446 447 448 |
# File 'lib/og/store/sql.rb', line 442 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.
491 492 493 494 495 496 497 498 499 |
# File 'lib/og/store/sql.rb', line 491 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.
355 356 357 358 359 360 361 |
# File 'lib/og/store/sql.rb', line 355 def load(pk, klass) pk_field = klass.primary_key.field || klass.primary_key.symbol sql = "SELECT * FROM #{klass::OGTABLE} WHERE #{pk_field}=#{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.
296 297 298 299 300 301 302 303 |
# File 'lib/og/store/sql.rb', line 296 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.
366 367 368 369 370 371 372 373 374 |
# File 'lib/og/store/sql.rb', line 366 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.
534 535 536 537 |
# File 'lib/og/store/sql.rb', line 534 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.
453 454 455 456 |
# File 'lib/og/store/sql.rb', line 453 def select(sql, klass) sql = "SELECT * FROM #{klass.table} " + sql unless sql =~ /SELECT/i read_all(query(sql), klass) end |
#select_one(sql, klass) ⇒ Object Also known as: find_by_sql_one
Specialized one result version of select.
461 462 463 464 |
# File 'lib/og/store/sql.rb', line 461 def select_one(sql, klass) sql = "SELECT * FROM #{klass.table} " + sql unless sql =~ /SELECT/i read_one(query(sql), klass) end |
#sql_update(sql) ⇒ Object
Encapsulates a low level update method.
543 544 545 546 |
# File 'lib/og/store/sql.rb', line 543 def sql_update(sql) exec(sql) # return affected rows. end |
#start ⇒ Object
Start a new transaction.
520 521 522 523 |
# File 'lib/og/store/sql.rb', line 520 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.
504 505 506 507 508 |
# File 'lib/og/store/sql.rb', line 504 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.
284 285 286 287 288 289 290 291 |
# File 'lib/og/store/sql.rb', line 284 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 :( ++
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 |
# File 'lib/og/store/sql.rb', line 383 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.
413 414 415 416 417 418 419 420 421 422 423 424 425 |
# File 'lib/og/store/sql.rb', line 413 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.
405 406 407 |
# File 'lib/og/store/sql.rb', line 405 def update_properties(target, *properties) update(target, :only => properties) end |