# * George Moschovitis # (c) 2004-2005 Navel, all rights reserved. # $Id: og.rb 300 2005-03-16 13:23:10Z gmosx $ require 'glue' require 'glue/logger' require 'glue/attribute' require 'glue/property' require 'glue/array' require 'glue/hash' require 'glue/time' require 'glue/pool' require 'glue/validation' # Og (ObjectGraph) is an efficient, yet simple Object-Relational # mapping library. # # === Features # # The library provides the following features: # # + Object-Relational mapping. # + Absolutely no configuration files. # + Multiple backends (PostgreSQL, MySQL, SQLite, Oracle). # + ActiveRecord-style meta language and db aware methods. # + Deserialize to Ruby Objects. # + Deserialize sql join queries to Ruby Objects (temporarily dissabled). # + Serialize arbitrary ruby object graphs through YAML. # + Connection pooling. # + Thread safety. # + SQL transactions. # + Lifecycle callbacks. # + Lifecycle observers. # + Transparent support for cascading deletes for all backends. # + Hierarchical structures (preorder traversal, materialized paths) # + Works safely as part of distributed application. # + Simple implementation. # # === Meta language # # primary_key :pid (NOT IMPLEMENTED) # name_key :name (NOT IMPLEMENTED) # prop_accessor Fixnum, :pid, :sql => "smallint DEFAULT 1" # has_many Child, :children # many_to_many Role, :roles # sql_index :pid # # === Property Metadata # # Og defines, reserves and uses the following property # metadata types: # # [+:sql_index+] # Create an sql index for this property. # # [+:unique+] # This value of the property must be unique. # # [+:name_key+] # This property is used as name-key. # # === Design # # Keep the main classes backend agnostic. # # For class ids we use the name instead of a hash. Class ids are # typically not used in querys, they are stored for completeness. # If we store a hash we cannot reclaim the class thus invalidating # the point. Instead of .name(), to_s() is used so the methods # are more flexible (they accept class names too!!) # # Og allows the serialization of arbitrary Ruby objects. Just # mark them as Object (or Array or Hash) in the prop_accessor # and the engine will serialize a YAML dump of the object. # Arbitrary object graphs are supported too. # # This is NOT a singleton, an application may access multiple # databases. # # The og.xxx methods are more flexible and allow you to use # multiple databases for example. # # === Managed Objects Lifecycle Callbacks # # * og_pre_read # * og_post_read # * og_pre_insert # * og_post_insert # * og_pre_update # * og_post_update # * og_pre_insert_update # * og_post_insert_update # * self.og_pre_delete # # A class level callback is used for delete because typically you call # delete with an oid and not an object to avoid a deserialization. # # === Future # # * Support prepared statements (pgsql) # * Support stored procedures (pgsql) # * Support caching. # * Deserialize to OpenStruct. # * Better documentation. module Og # The version. Version = '0.13.0' # Library path. LibPath = File.dirname(__FILE__) # If true, check for implicti changes in the object # graph. For example when you add an object to a parent # the object might be removed from his previous parent. # In this case Og emmits a warning. mattr_accessor :check_implicit_graph_changes, false # If true, only allow reading from the database. Usefull # for maintainance. # WARNING: not implemented yet. mattr_accessor :read_only_mode, false # If true, the library automatically 'enchants' managed classes. # In enchant mode, special db aware methods are added to # managed classes and instances. # If false, Og enchants only classes that define properties. mattr_accessor :enchant_managed_classes, true # If true, use Ruby's advanced introspection capabilities to # automatically manage classes tha define properties. mattr_accessor :auto_manage_classes, true # If true, automatically include the Og meta-language into Module. # If false, the polution of the Module object is avoided. However # if you include a prop_accessor or a managed Mixin in your # object MetaLanguage gets automatically extended in the class. mattr_accessor :include_meta_language, true # Attach the following prefix to all generated SQL table names. # Usefull on hosting scenarios where you have to run multiple # web applications/sites on a single database. mattr_accessor :table_prefix, nil # If true, Og tries to create/update the schema in the # data store. For production/live environments set this to false # and only set to true when the object model is upadated. # For debug/development environments this should stay true # for convienience. mattr_accessor :create_schema, true # The active database. Og allows you to access multiple # databases from a single application. mattr_accessor :db # Set the active database. def self.use(db) @@db = db @@db.get_connection end # The adapter of the active database. def self.adapter @@db.adapter end # Marker module. If included this in a class, the Og automanager # ignores this class. module Unmanageable; end end # gmosx: leave this here. require 'og/database' require 'og/validation'