TOP>>リファレンス>>リファレンス(OBAQ編) 概略ツアーOBAQ構成定義アプリケーションサーバ<リファレンス>サイトマップ

obaq/sql


データモデルオブジェクトとラッパーオブジェクト

obaq/sqlはデータモデルオブジェクトとラッパーオブジェクトを提供します。

データモデルオブジェクト

データモデルオブジェクトとは、RDBのテーブル定義(フィールド定義)の情報を保持しているオブジェクトです。 以下のクラス群を総称してデータモデルオブジェクトといいます。

  • class DataBase
  • class Table
  • class IntField, class VarCharField等のフィールドオブジェクト

これらによって、次のようなことが可能になります。

  • スキーマの生成

    createtable等のテーブル定義のためのSQLを生成します。

  • ラッパーオブジェクトの生成

    次項で説明するラッパーオブジェクトを生成することができます。

  • Queryオブジェクトの生成

    sqlのselect文を生成するQueryオブジェクトを生成できます。

  • データ定義とプログラムの分離

    データベースのテーブル定義を修正してもプログラムの修正が不要(かごく少量)になります。 単純なフィールドごとのコピー等の処理はほとんど不要になります。

ラッパーオブジェクト

ruby-postgresによってデータベースにアクセスすると、 結果は文字列の配列として返されます。 ほとんどの場合、この配列を数値(Integer)や日付(Date)などの対応するRubyのデータに変換する処理が必要になります。 この処理を自動的に行うのがラッパーオブジェクトです。

ラッパーオブジェクトには、以下の機能があります。

  • フィールド名でメンバーにアクセスする
  • 対応するデータモデルオブジェクトにアクセスする
  • insert文、update文、delete文等のSQLを生成する

module WrapperMixin

ラッパーオブジェクトにMixinされるモジュール。

ラッパーオブジェクトはひとつのクラスでなく、 各テーブルごとに個別のクラスが自動生成されます。 このWrapperMixinモジュールは、全てのラッパーオブジェクトにincludeされます。

すなわち、このモジュールの機能(メソッド)は全てのラッパーオブジェクトが持っています。

WrapperMixin#get_table

対応するテーブルのデータモデルオブジェクトを返却します。

WrapperMixin#each_field(&block)

対応するフィールドのデータモデルオブジェクトごとにブロックを呼びます。

WrapperMixin#check_data

対応するフィールドとテーブルのデータモデルオブジェクトのcheck_dataを呼び出して、 データをチェックします。

WrapperMixin#insert_sql

現在、ラッパーオブジェクトに設定されている値をもとに、insert文を生成します。

r = shohin.new_wrapper_object(1, "a", 2)
puts r.insert_sql 
# => insert into 
       Shohin(shohin_code,shohin_name,unit_price) 
       values(1,'a',2)

nilが設定されているフィールドとSerialFieldは飛ばして処理します。

WrapperMixin#update_sql

現在、ラッパーオブジェクトに設定されている値をもとに、update文を生成します。 nilが設定されているフィールドは飛ばして処理します。

WrapperMixin#delete_sql

現在、ラッパーオブジェクトに設定されている値をもとに、delete文を生成します。

class DataBase

DataBase#find_table(table_name)

テーブルに対応するデータモデルオブジェクトを返却します

DataBase#create_tables

テーブル定義のSQL(create table文)を生成します。 返却値は、SQL命令1つの文字列を要素とする配列です。

DataBase#create_dbobjects

DBObjectを定義するSQLを生成します。

DataBase#create_all

create_table + create_dbobjects

DataBase#drop_tables
DataBase#drop_dbobjects
DataBase#drop_all
DataBase#install_datamodel(mod)

module modに各テーブルに対応するデータモデルオブジェクトを定数として定義します。 テーブル名が定数名になります。

DataBase#bind_fields(f1, f2)

フィールドの対応を記憶します。

DataBase#each_binded_fields(t1, t2, &block)

テーブルt1,t2の中で対応するフィールドのペアごとにblockを実行します。

DataBase#new_wrapper_object(table, *args)

テーブルtableからラッパーオブジェクトを生成します。 argsは、データ定義のフィールドの並びどおりに、初期値を渡します。

DataBase#wrapper_object_factory

テーブル名と、ラッパーオブジェクト生成クラスの対応を保持しているHashです。 独自のラッパーオブジェクトを使用したい時に、ここにそのラッパーを生成するクラスを登録します。

class MyUriage < Uriage
  ....
end

db = Uriage.db
db.wrapper_object_factory[Uriage] = MyUriage

r = uriage.new_wrapper_object(1, 'aaa', 2)
# r は MyUriageのインスタンスになっている

class DBObject

テーブル生成時に、Talbe以外のオブジェクトを同時に生成したい場合、 このクラスを使用して、追加のSQLを埋めこみます。

DataBase db1
  Table paths
    #....

  DBObject table_index
    create_sql = <<END
      create index paths_index on paths 
        using btree(upper path) text_ops
    END
    drop_sql = 'drop index paths_index'

SceamaCommandSet
  CreateTables

この結果

create table paths ..... ;
create index paths_index .... ;

というSQLが実行されます。

アプリケーションプログラムの実行時には データモデルオブジェクトとして使用されることはありません。

DBObjectのオプション

DBObject#create_sql

そのオブジェクトを生成するために使用するSQL文

DBObject#drop_sql

そのオブジェクトを削除するために使用するSQL文

DBObject#long_name

説明用の名称

DBObject#description

説明文

class Table

Table#primary_keys

そのテーブルのprimary keyに対応するデータモデルオブジェクトの配列

Table#[field_name]

field_nameのフィールドに対応するデータモデルオブジェクト

Table#create_table

Tableを定義するSQL文。 命令ひとつを要素とする配列。

Table#drop_table

Tableを削除するSQL文

Table#wrapper_object_creator

ラッパーオブジェクトを生成するクラスを生成して返却する。 このクラスは、フィールド名をメンバーとするStructであり、 以下のモジュールをincludeしている

  • Obaq
  • HtmlGen
  • ExpandByMember
  • WrapperMixin
Table#new_wrapper_object(*args)

ラッパーオブジェクトを生成する argsはラッパーオブジェクトに渡される。 通常は、スキーマで定義されている順番にフィールドの初期値を渡す。

Table#check_data(r)

rの内容の正当性をチェックする。 エラーがあるとDBDataErrorをraiseする。 デフォルトでは何もチェックしないので、必要ならばこのメソッドを再定義する

Table#raise_error(msg)

DBDataErrorをraiseする

class Field

class Fieldのオプション

Field#primary_key

このフィールドが主キーである場合にtrueを設定する

Field#not_null

trueであれば、フィールド定義にNOT NULLを付加する。

Field#unique

trueであれば、フィールド定義にUNIQUEを付加する。

Field#default_value

nil以外であれば、フィールド定義にDEFAULT VALUEを付加する。

Field#long_name

説明用の名称

Field#description

説明文

class Fieldのメソッド

Field#bind_to_field(table_name, field_name)

テーブルtable_nameのフィールドfield_nameとこのフィールドを関連づける。 関連づけられたフィールドには、Queryの生成時にwhere x = yの条件が自動的に付加される。

Field#db

このフィールドを保持しているDataBaseを返却する

Field#fullname

テーブル名.フィールド名

Field#field_def

SQLのフィールド定義

Field#==(x)

QueryCondオブジェクトを生成する

Field#<=(x)

QueryCondオブジェクトを生成する

Field#>=(x)

QueryCondオブジェクトを生成する

Field#<(x)

QueryCondオブジェクトを生成する

Field#>(x)

QueryCondオブジェクトを生成する

Field#---(x)

xのクラスによって、対応するQueryCondオブジェクトを生成する

Field#desc
Field#check_data(d)
Field#ruby2sql(x)

xの値をSQL形式に変更する(サブクラスで定義)

Field#sql2ruby(x)

xの値をRubyとして一般的なタイプに変換する(サブクラスで定義)

class IntField

class SerialField

連番を表わすフィールドです。

このタイプのフィールドが定義されていると、テーブル定義時に以下のようなSQLによって、 対応するシーケンスとインデックスが生成されます。

create table Shohin ( 
  shohin_code integer  default nextval('Shohin_shohin_code_seq') ,
  shohin_name varchar(20) ,
  unit_price integer  );
create sequence Shohin_shohin_code_seq;
create unique index Shohin_shohin_code_index on Shohin (shohin_code)
SerialField#curr_val

現在のシーケンス値を取り出すSQL文(select currval('...') )を生成します。 このSQLは、同一セッション内でこのテーブルに対するinsert文かnext_valが実行されていないと、 使用することはできません。(postgreSQLの制限)

SerialField#next_val

class EnumField

列挙値(数種類の決まった値)しか持てないフィールドです。

EnumField shohin_type 
  .add_enum 1 Foods
  .add_enum 2 Drinks
  .add_enum 3 Books

このフィールドは、1,2,3のどれかの値(かnull値)しか持てないようになります。 データベース内では整数(integer)のフィールドとして定義され、 整数値を格納します。 Rubyのコードでは、:Foods, :Drinks, :Booksといったシンボル値で処理されます。

r = shohin.new_wrapper_object(1, "a", :Foods)
puts r.insert_sql
# =>"insert into 
       Shohin(shohin_code,shohin_name,shohin_type) 
         values(1,'a',1)"

q = Query.new(shohin)
fetch_db(q) |tupl|
  r = q.tupl_to_wrapper(tupl)
  puts r.shohin_type   # => Foods
  case r.shohin_type
  when :Foods
    ...
  when :Drinks
    ...
  when :Books
    ...
  end
end
EnumField#add_enum(value, enum_name)

このフィールドが持ち得る値を追加します。 ここに列挙されてないフィールドの値をDBに格納しようとすると、 insert_sql,update_sql等でDBDataErrorの例外が発生します。

class BoolField

真偽値しか持てないフィールドです。 データベース内では整数フィールドとして定義され、真の場合0、偽の場合1が格納されます。

class Fieldのオプション

BoolField#default_true

このオプションを指定すると、既定値が真になります。

BoolField#default_false

このオプションを指定すると、既定値が偽になります。

class DateTimeField

class VarCharField

class TextField

class FunctionObject

class Desc

class Query

Query#new(table_or_field ... )

Queryオブジェクトを生成します。 パラメータはテーブルまたはフィールドに対応するデータモデルオブジェクトです。 テーブルを指定した場合は、そのテーブルの全フィールドに対する問い合わせを生成します。

Query#cond=(c)

select文の where句に入る条件を設定します。

Query#ordry_by

select文のorder by句に入るフィールドのデータモデルオブジェクトの配列です。

Query#to_s

select文を生成します。

Query#tupl_to_wrapper(tupl)

この問合せの結果として、 ruby-postgresから返却された配列からラッパーオブジェクトを生成します。

q = Query.new(Uriage)
fetch_db(q) do |tupl|
  r = q.tupl_to_wrapper(tupl)
  # rはUriageのラッパーオブジェクトになっている
  puts r.shohin_code
  ...

問い合わせに複数のテーブルが関連する時は、 テーブルのデータモデルオブジェクトをキーとして、 そのテーブルのラッパーオブジェクトを値とするHashを返却します。 テーブル名を小文字に変換したものもメンバー名として使用できます。

q = Query.new(Uriage, Shohin)
fetch_db(q) do |tupl|
  r = q.tupl_to_wrapper(tupl)

  puts r.uriage.dt # r[Uriage].dtも可
  puts r.shohin.shohin_code
  ...

class QueryCond

QueryCondはQueryの条件(cond)に設定する条件を表すオブジェクトです。

QueryCond#new(left, op ,right)

左辺、演算子、右辺を指定してQueryCondを生成する

QueryCond#to_s

条件を文字列として生成する

QueryCond#|(cond)

(self) or (cond)という複合条件を生成する

QueryCond#&(cond)

(self) and (cond)という複合条件を生成する

class NullCond

class RangePair

RangePair#new(first, last)

firstからlastまでの範囲でRangePairを生成します

RangePair#new(x)

x[0]からx[1]までの範囲でRangePairを生成します。

RangePair#include?(v)

vがfirst以上last以下ならば真。

RangePair#===(v)

include?(v)と同じ

RangePair#<=>
RangePair#+(r)

selfとrが重なっていなければ、RangeArray.new(self, r)。 重なっていれば、両者の和の範囲を持つRangePairを生成する。

class RangeArray

RangeArray#new(*args)

argsはRangePairか2要素の配列。 RangeArrayを生成します。

RangeArray#normalize

重複無しで同じ範囲を示すRangeArrayを生成します。

RangeArray#[i]

i番目のRangePairを返却します。

RangeArray#size

含まれるRangePairの数を返却します。

RangeArray#==(ra)
RangeArray#include?(v)

vを含むRangePairを要素に含んでいれば真。

RangeArray#===(v)

include?(v)と同じ

RangeArray#+(ra)

selfとrの両方を示すRangeArrayを生成する。

RangeArray#each(&block)
RangeArray#to_s

class DBConnection

class DBScript

class SchemaCommandSet

class SchemaApp

class CreateDB

class DropDB

class CreateTables

class CreateDocument


ページトップへ