Databases & Dynamic Ruby Classes
by David J. Berube

Listing One

require 'config.rb'
require 'mysql'
$db = connect_db()
class Test_Object
    @@properties = ['property_one','property_two']
    MYTABLE = 'test_objects'
    attr_reader :object_id
    def initialize(object_id)
        @object_id=object_id
    end
    def method_missing( name, *args )
        method_name = name.to_s
          if (method_name.slice(-1,1) == '=')
            field_name = method_name.chop
            set field_name,args[0]
          else
            field_name=method_name
            if @@properties.include?(field_name)
            res= $db.query("SELECT #{field_name} FROM #{MYTABLE} 
                                     where object_id='#{@object_id}';")
            row = res.fetch_row
            if (res.num_rows()==0) or row.nil?
                nil
            else    
                row[0]
            end
             end
          end
    end
    def set( name, value )
        if @@properties.include?(field_name)
          $db.query("UPDATE #{MYTABLE} set #{name}=
            \"#{Mysql.escape_string(value)}\" where object_id=#{@object_id};")
        end
    end
end
#run some tests
test_object = Test_Object.new(1)
print "Testing property: #{test_object.property_one}\n"


Listing Two

require 'config.rb'
require 'mysql'
$db = connect_db()
class Test_Object
    @@properties = ['property_one','property_two']
    MYTABLE = 'test_objects'
    EXTENDED_PROPERTIES_TABLE = 'test_objects_props'
    attr_reader :object_id
    def initialize(object_id)
        @object_id=object_id
    end
    def method_missing( name, *args )
        method_name = name.to_s
          if (method_name.slice(-1,1) == '=')
            field_name = method_name.chop
            set field_name,args[0]
          else
            field_name=method_name
            if @@properties.include?(field_name)
            res= $db.query("SELECT #{field_name} FROM #{MYTABLE} 
                                     where object_id='#{@object_id}';")
            row = res.fetch_row
            if (res.num_rows()==0) or row.nil?
                nil
            else    
                row[0]
            end
              else
            get_property name   
             end
          end
    end
    def get_property(name)
        res= $db.query("select `code`,`value` 
             from #{EXTENDED_PROPERTIES_TABLE} 
              where object_id='#{@object_id}' and `property_name`='#{name}';")
        code,value = *res.fetch_row()
        if res.num_rows()==0
          nil
        else 
            if code.nil?
                if value.nil?
                    nil
                else
                    value
                end
            else
                begin
                    eval code
                    rescue Exception
                      if @args.nil?
                          raise Exception.exception("Error in evaluating for 
                            object ##{@object_id} in method #{name} 
                             with no arguments. Error description: \"#$!\"")
                      else
                          raise Exception.exception("Error in evaluating for 
                            object ##{@object_id} in method #{name} 
                                with arguments #{@args.join(",")}. 
                                    Error description: \"#$!\" ")
                      end
                end
                
                end
        end
    end
    def set( name, value )
        if @@properties.include?(field_name)
          $db.query("UPDATE #{MYTABLE} set #{name}=\
            "#{Mysql.escape_string(value)}\" where object_id=#{@object_id};")
        end
    end
end
#run some tests
test_object = Test_Object.new(1)
print "Extended property: #{test_object.test_extended_property}\n"
print "Extended method: #{test_object.test_extended_method}\n"


Listing Three

require 'config.rb'
require 'mysql'
$db = connect_db()
class Test_Object
    @@properties = ['parent','property_one','property_two']
    MYTABLE = 'test_objects'
    EXTENDED_PROPERTIES_TABLE = 'test_objects_props'
    attr_reader :object_id
    def initialize(object_id)
        @object_id=object_id
    end
    def method_missing( name, *args )
        method_name = name.to_s
          if (method_name.slice(-1,1) == '=')
            field_name = method_name.chop
            set field_name,args[0]
          else
            field_name=method_name
            if @@properties.include?(field_name)
            res= $db.query("SELECT #{field_name} FROM #{MYTABLE} 
                               where object_id='#{@object_id}';")
            row = res.fetch_row
            if (res.num_rows()==0) or row.nil?
                nil
            else    
                row[0]
            end
              else
            get_property name   
             end
          end
    end
    def get_property(name)
        res= $db.query("select `code`,`value` 
             from #{EXTENDED_PROPERTIES_TABLE} 
              where object_id='#{@object_id}' and `property_name`='#{name}';")
        code,value = *res.fetch_row()
        if res.num_rows()==0
          if not parent.nil?
            Test_Object.new(parent).get_property name
          else
            nil
          end
        else 
            if code.nil?
                if value.nil?
                    nil
                else
                    value
                end

           else
                    eval code 
                end
        end
    end

    def set( name, value )
        if @@properties.include?(field_name)
          $db.query("UPDATE #{MYTABLE} set #{name}=\
            "#{Mysql.escape_string(value)}\" where object_id=#{@object_id};")
        end
    end
end
#run some tests
test_object = Test_Object.new(1)
print "Extended property: #{test_object.test_extended_property}\n"
print "Extended method: #{test_object.test_extended_method}\n"
print "Inherited property: #{test_object.test_inherited_property}\n"


Listing Four

# Use this SQL script to create a test database to run the examples. 
# phpMyAdmin MySQL-Dump
# version 2.2.7-pl1
# http://phpwizard.net/phpMyAdmin/
# http://www.phpmyadmin.net/ (download page)
# Host: localhost
# Generation Time: Apr 10, 2004 at 10:09 AM
# Server version: 4.00.18
# PHP Version: 4.3.1
# Database : `test_database`
# --------------------------------------------------------

CREATE database test_database; 
USE test_database;

# Table structure for table `test_objects`
CREATE TABLE test_objects (
  object_id int(11) NOT NULL,
  property_one text NOT NULL,
  property_two text NOT NULL,
  parent int(11) NULL,
  PRIMARY KEY  (object_id)
) TYPE=MyISAM;

# Dumping data for table `test_objects`
INSERT INTO test_objects (object_id, property_one, property_two, parent) 
                                VALUES (0, 'parent of object 1', '', null);
INSERT INTO test_objects (object_id, property_one, property_two, parent) 
                             VALUES (1, 'property_one', 'property_two', 0);
# --------------------------------------------------------
# Table structure for table `test_props`

CREATE TABLE test_objects_props (
  property_name text NOT NULL,
  object_id int(11) NOT NULL,
  value text,
  code text
) TYPE=MyISAM;
# Dumping data for table `test_objects_props`
INSERT INTO test_objects_props (property_name, object_id, value, code) 
                VALUES ('test_extended_property', 1, 'test suceeded', NULL);
INSERT INTO test_objects_props (property_name, object_id, value, code) 
                  VALUES ('test_extended_method', 1, NULL, 'Kernel.rand()');
INSERT INTO test_objects_props (property_name, object_id, value, code) 
                  VALUES ('test_inherited_property', 0, 
                            'testing the inherited property suceeded', NULL);


Listing Five

require 'mysql';

$dbhost="localhost"
$dbname="test_database"
$dbuser="root"
$dbpasswd=""
$port = 7232

def connect_db
    Mysql.new($dbhost, $dbuser, $dbpasswd,$dbname)
end





5


