- 名前
- 概要
- イントロダクション
- クラスメソッド
- コンストラクタとデストラクタ
- オブジェクトの取り出し
- イテレータ
- コピーと移動
- トリガ
- 制約
- データの正規化
- データの妥当性チェック
- 例外処理
- 警告 (Warning)
- インスタンスメソッド
- テーブルのリレーションシップ
- SQL文を定義する
- LAZY POPULATION
- トランザクション
- サブクラス化
- 注意
- クックブック
- サポートしているデータベース
- 現在の作者
- 名誉作者
- 謝辞
- サポート
- ライセンス
- 参考
名前¶
Class::DBI - シンプルなデータベース抽象クラス
概要¶
package Music::DBI;
use base 'Class::DBI';
Music::DBI->set_db('Main', 'dbi:mysql:dbname', 'username', 'password');
package Music::Artist;
use base 'Music::DBI';
Music::Artist->table('artist');
Music::Artist->columns(All => qw/artistid name/);
Music::Artist->has_many(cds => 'Music::CD');
package Music::CD;
use base 'Music::DBI';
Music::CD->table('cd');
Music::CD->columns(All => qw/cdid artist title year/);
Music::CD->has_many(tracks => 'Music::Track');
Music::CD->has_a(artist => 'Music::Artist');
Music::CD->has_a(reldate => 'Time::Piece',
inflate => sub { Time::Piece->strptime(shift, "%Y-%m-%d") },
deflate => 'ymd',
}
Music::CD->might_have(liner_notes => LinerNotes => qw/notes/);
package Music::Track;
use base 'Music::DBI';
Music::Track->table('track');
Music::Track->columns(All => qw/trackid cd position title/);
#-- Meanwhile, in a nearby piece of code! --#
my $artist = Music::Artist->create({ artistid => 1, name => 'U2' });
my $cd = $artist->add_to_cds({
cdid => 1,
title => 'October',
year => 1980,
});
# Oops, got it wrong.
$cd->year(1981);
$cd->update;
# etc.
foreach my $track ($cd->tracks) {
print $track->position, $track->title
}
$cd->delete; # also deletes the tracks
my $cd = Music::CD->retrieve(1);
my @cds = Music::CD->retrieve_all;
my @cds = Music::CD->search(year => 1980);
my @cds = Music::CD->search_like(title => 'October%');
イントロダクション¶
Class::DBI provides a convenient abstraction layer to a database.
Class::DBIはデータベースへの便利な抽象レイヤーを提供する。
It not only provides a simple database to object mapping layer, but can be used to implement several higher order database functions (triggers, referential integrity, cascading delete etc.), at the application level, rather than at the database.
このモジュールは、オブジェクトマッピング層に簡単なデータベースを提供 するだけでなく、データベースレベルよりもアプリケーションレベルで いくつかのより高レベルな一般的的なデータベース機能(トリガー、参照統合、 波及削除)を実装するために利用される。
This is particularly useful when using a database which doesn't support these (such as MySQL), or when you would like your code to be portable across multiple databases which might implement these things in different ways.
上記の機能をサポートしていないデータベース(MySQLなど)を使う際には 殊のほか便利である。あるいは、こういったことを様々な方法で実装している 複数のデータベースに対して、あなたのコードを移植しようとしている際にも 便利である。
In short, Class::DBI aims to make it simple to introduce 'best practice' when dealing with data stored in a relational database.
要するに、リレーショナルデータベースに保持されているデータを扱うときに ”最前のやり方”を導入しやすくするのがClass::DBIのねらいなのだ。
設定の仕方¶
- データベースを準備する
-
You must have an existing database set up, have DBI.pm installed and the necessary DBD:: driver module for that database. See DBI and the documentation of your particular database and driver for details.
既存のデータベースを準備しなければならない。DBI.pmとそのデータベースに 必要なDBD::ドライバーモジュールがインストールされていなければならない。 詳細については、DBI及び、実際のデータベースとドライバーのドキュメントを 参照のこと。
- オブジェクトが保持するテーブルを設定する
-
Class::DBI works on a simple one class/one table model. It is your responsibility to have your database tables already set up. Automating that process is outside the scope of Class::DBI.
Class::DBIは、単純な”1クラス1テーブル”モデルで動作する。データベースを 既に準備の出来ている状態にするのはあなたの責任だ。このプロセスを自動化する のはClass::DBIの範疇外である。
Using our CD example, you might declare a table something like this:
CDを例にとろう。次のようなテーブルを宣言するとする:
CREATE TABLE cd ( cdid INTEGER PRIMARY KEY, artist INTEGER, # references 'artist' title VARCHAR(255), year CHAR(4), );
- アプリケーションベースクラスを設定する
-
It's usually wise to set up a "top level" class for your entire application to inherit from, rather than have each class inherit directly from Class::DBI. This gives you a convenient point to place system-wide overrides and enhancements to Class::DBI's behavior.
通常は各クラスを直接Class::DBIから継承させるよりも、”トップレベル”クラスを つくり、アプリケーション全体はそれを継承する方が賢いやり方だ。こうすることで システム全体でオーバーライドしたり、Class::DBIの振る舞いを向上させるといった 利点が得られる。
package Music::DBI; use base 'Class::DBI';
- データベースへ接続する
-
Class::DBI needs to know how to access the database. It does this through a DBI connection which you set up by calling the set_db() method.
Class::DBIはデータベースにアクセスする方法を知る必要がある。これは あなたが用意したDBI接続を通じてなされるのだが、それにはset_db()メソッドを 呼び出す。
Music::DBI->set_db('Main', 'dbi:mysql:dbname', 'user', 'password');
By setting the connection up in your application base class all the table classes that inherit from it will share the same connection.
アプリケーションベースクラスの接続が確立すると、このクラスを継承している 全てのテーブルクラスが同じ接続を共有する。
The first parameter is the name for this database connection and it must be 'Main' for Class::DBI to function. See "set_db" below and Ima::DBI for more details on set_db().
最初のパラメータはこのデータベース接続のための名前であり、Class::DBIが 機能するには'Main'でなければならない。set_dbの詳細については、下記の "set_db"、ならびにIma::DBIを参照のこと。
- 各クラスを用意する
-
package Music::CD; use base 'Music::DBI';
Each class will inherit from your application base class, so you don't need to repeat the information on how to connect to the database.
各クラスはアプリケーションベースクラスを継承する。よって、データベース 接続方法の情報を繰り返す必要はない。
- テーブル名を宣言する
-
Inform Class::DBI what table you are using for this class:
このクラスがどんなテーブルのために用いられるのかをClass::DBIに教える。
Music::CD->table('cd');
- カラムを宣言する
-
This is done using the columns() method. In the simplest form, you tell it the name of all your columns (with the single primary key first):
これはcolumns()メソッドを使って行う。最も単純な形式は、全カラムの名前を クラスに伝えることだ。
Music::CD->columns(All => qw/cdid artist title year/);
If the primary key of your table spans multiple columns then declare them using a separate call to columns() like this:
テーブルの主キーが複数のカラムにまたがる場合は、次のようにして columns()を別々に呼び出して宣言する。
Music::CD->columns(Primary => qw/pk1 pk2/); Music::CD->columns(Others => qw/foo bar baz/);
For more information about how you can more efficiently use subsets of your columns, "Lazy Population"
カラムのサブセットをより効率的に利用する方法については、"Lazy Population" を参照。
- 実行
-
That's it! You now have a class with methods to create(), retrieve(), search() for, update() and delete() objects from your table, as well as accessors and mutators for each of the columns in that object (row).
これでよし! テーブルから生成されるオブジェクトに対してcreate()、retrieve()、 search()、update()そしてdelete()といったメソッドを持ったクラスを手に入れた。 これはそのオブジェクトの各カラムに対するアクセサとミューテータと同じように 作用する。
Let's look at all that in more detail:
それでは全てについて詳細をみてみよう:
クラスメソッド¶
set_db¶
__PACKAGE__->set_db('Main', $data_source, $user, $password, \%attr);
For details on this method, Ima::DBI.
このメソッドの詳細についてはIma::DBIを参照。
The special connection named 'Main' must always be set. Connections are inherited so it's usual to call set_db() just in your application base class.
'Main'と名づけられた特別な接続が常にセットされなければならない。 接続は継承されるので、通常はあなたのアプリケーションベースクラスで set_db()を呼び出す。
package Music::DBI;
use base 'Class::DBI';
Music::DBI->set_db('Main', 'dbi:foo:dbname', 'user', 'password');
package My::Other::Table;
use base 'Music::DBI';
Class::DBI helps you along a bit to set up the database connection. set_db() provides its own default attributes depending on the driver name in the data_source parameter. The set_db() method provides defaults for these attributes:
Class::DBIは、データベース接続を確立するために、少しだけ手伝いをする。 set_db()は、data_sourceパラメータにあるドライバー名に基づいたデフォルトの 属性を手供する。set_db()メソッドはデフォルトで以下の属性を提供する:
FetchHashKeyName => 'NAME_lc',
ShowErrorStatement => 1,
ChopBlanks => 1,
AutoCommit => 1,
(Except for Oracle and Pg, where AutoCommit is set to 0, placing the database in transactional mode).
(OracleとPgを除いて、AutoCommitに0を設定すると、そのデータベースは トランザクションモードになる)
The defaults can always be overridden or extended by supplying your own \%attr parameter. For example:
これらの既定値は\%attrパラメータを用意することで、常にオーバーライドや 拡張を行なえる。例えば:
Music::DBI->set_db('Main','dbi:foo:dbname','user','pass',{ChopBlanks=>0});
動的なデータベース接続¶
It is sometimes desirable to generate your database connection information dynamically, for example, to allow multiple databases with the same schema to not have to duplicate an entire class hierarchy.
時には、データベース接続の情報を動的に生成したい場合がある。例えば、 同じスキーマを用いる複数のデータベースが完全なクラスヒエラルキーを 重複させないようにする場合。
The preferred method for doing this is to supply your own db_Main() method rather than calling set_db(). This method should return a valid database handle.
これを行なうのに好ましい方法は、set_db()を呼び出すよりも、 あなた自身のdb_Main()メソッドを用意することだ。このメソッドは妥当な データベースハンドルを返す必要がある。
Note however that this is class data, and that changing it may have unexpected behaviour for instances of the class already in existence.
しかし注意して欲しいのだが、これはクラスデータであり、それを変更すると 既存クラスのインスタンスの振る舞いを予期せぬものにしてしまうかもしれない。
table¶
__PACKAGE__->table($table);
$table = Class->table;
$table = $obj->table;
An accessor to get/set the name of the database table in which this class is stored. It -must- be set.
このクラスが保持するデータベーステーブルの名前を取得・設定する ためのアクセサ。設定 -しなければ- ならない。
Table information is inherited by subclasses, but can be overridden.
テーブル情報はサブクラスによって継承されるが、オーバーライドは出来ない。
table_alias¶
package Shop::Order;
__PACKAGE__->table('orders');
__PACKAGE__->table_alias('orders');
When Class::DBI constructs SQL, it aliases your table name to a name representing your class. However, if your class's name is an SQL reserved word (such as 'Order') this will cause SQL errors. In such cases you should supply your own alias for your table name (which can, of course, be the same as the actual table name).
Class::DBIがSQLを構築するさい、モジュールはあなたのテーブル名に対して クラスを表す名前をあてる。しかし、クラス名がSQLの予約している単語(Orderなど) である場合、SQLエラーが発生する。このような場合に、テーブル名に対して独自の 別名を用意する必要がある(もちろん、これは実際のテーブル名と同じできる)。
This can also be passed as a second argument to 'table':
これはtableメソッドに二つ目の引数を渡すことでも可能だ:
__PACKAGE-->table('orders', 'orders');
As with table, this is inherited but can be overriden.
tableメソッド同様、継承はできるがオーバーライドはできない。
sequence / auto_increment¶
__PACKAGE__->sequence($sequence_name);
$sequence_name = Class->sequence;
$sequence_name = $obj->sequence;
If you are using a database which supports sequences and you want to use a sequence to automatically supply values for the primary key of a table, then you should declare this using the sequence() method:
もしもあなたがシーケンスをサポートしているデータベースを使っていて、かつ、 シーケンスを利用してテーブルの主キーの値を自動的に供給したいならば、 sequence()メソッドの使用を宣言するとよい:
__PACKAGE__->columns(Primary => 'id');
__PACKAGE__->sequence('class_id_seq');
Class::DBI will use the sequence to generate a primary key value when objects are created without one.
主キーなしでオブジェクトを生成すると、Class::DBIはシーケンスを利用する。
*NOTE* This method does not work for Oracle. However, Class::DBI::Oracle (which can be downloaded separately from CPAN) provides a suitable replacement sequence() method.
*注意* このメソッドはOracleでは動作しない。しかし、Class::DBI::Oracle (別途CPANからダウンロードできる)がsequence()メソッドのうまい代替手段を 提供している。
If you are using a database with AUTO_INCREMENT (e.g. MySQL) then you do not need this, and any call to create() without a primary key specified will fill this in automagically.
あなたの使っているデータベースがAUTO_INCREMENT機能を持っているなら (例:MySQL)、このメソッドを使う必要はない。主キー指定せずに create()を呼び出せば、自動的に主キーが生成される。
Sequence and auto-increment mechanisms only apply to tables that have a single column primary key. For tables with multi-column primary keys you need to supply the key values manually.
シーケンスと自動インクリメント機能は、主キーカラムが一つだけのテーブルに のみ適用される。複数の主キーカラムを持つテーブルに対しては、手動でキーの 値を設定してやらねばならない。
コンストラクタとデストラクタ¶
The following are methods provided for convenience to create, retrieve and delete stored objects. It's not entirely one-size fits all and you might find it necessary to override them.
ここで取り上げるのは、オブジェクトの生成、取り出し、削除の便宜を 図るためのメソッドである。メソッド単体であらゆる事態に対応できるわけでは ないので、必要に応じてそれらをオーバーライドすること。
create¶
my $obj = Class->create(\%data);
This is a constructor to create a new object and store it in the database.
新しいオブジェクトを生成し、データベース内に格納するためのコンストラクタである。
%data consists of the initial information to place in your object and the database. The keys of %data match up with the columns of your objects and the values are the initial settings of those fields.
%dataは、オブジェクトとデータベースに入れられる初期情報で構成される。 %dataのキーはオブジェクトのカラムに対応し、%dataの値はそれらのフィールドに 初期状態でセットされる。
my $cd = Music::CD->create({
cdid => 1,
artist => $artist,
title => 'October',
year => 1980,
});
If the table has a single primary key column and that column value is not defined in %data, create() will assume it is to be generated. If a sequence() has been specified for this Class, it will use that. Otherwise, it will assume the primary key can be generated by AUTO_INCREMENT and attempt to use that.
もしテーブルが単一の主キーカラムを持ち、そのカラム値が%dataにおいて定義 されていないならば、create()は生成されるべき値を仮定する。sequence()が このクラス用に指定されていれば、それが利用される。そうでなければ、 AUTO_INCREMENTによって生成可能な主キーを仮定し、その利用が試みられる。
The before_create
($data) trigger is invoked directly after storing the supplied values into the new object and before inserting the record into the database. The object stored in $self is a dummy for the final object, and will not support many of the normal operations. In particular, adding default values for columns etc should be done by treating $data purely as a data hash, rather than a fully fledged object (i.e. you should assign $data->{column} = $value, rather than calling $data->column($value).
与えられた値が新しいオブジェクトに格納された直後、かつ、そのレコードを データベースに挿入する前にbefore_create
($data)トリガが発動される。 $selfに格納されているオブジェクトは最終的なオブジェクトにとってダミー であり、通常の操作の多くをサポートしない。殊に、既定値をカラムその他に 追加する際には、$dataを一人前のオブジェクトとして扱うのではなく、純粋に データハッシュとして扱うことでなされるべきである(つまり、 $data->column($value)ではなくて $data->{column} = $value とする)。
For tables with multi-column primary keys you need to supply all the key values, either in the arguments to the create() method, or by setting the values in a before_create
trigger.
複数の主キーカラムを持つテーブルに対しては、全てのキー値をあなたが 提供しなければならない。これはcreate()への引数としてか、あるいは before_create
トリガ内で値をセットすることによって行なう。
If the class has declared relationships with foreign classes via has_a(), you can pass an object to create() for the value of that key. Class::DBI will Do The Right Thing.
もしそのクラスがhas_a()を通じて外部キーを持つリレーションシップを 宣言しているなら、そのキーの値のためにオブジェクトをcreate()に渡す ことができる。Class::DBIは適切に処理をする。
After the new record has been inserted into the database the data for non-primary key columns is discarded from the object. If those columns are accessed again they'll simply be fetched as needed. This ensures that the data in the application is consistant with what the database actually stored.
新しいレコードがデータベースに挿入された後、主キーカラム以外のデータは そのオブジェクトから破棄される。これらのカラムに再度アクセスすると 必要に応じてデータベースから取り出される。これにより、アプリケーション内の データは、データベースが実際に保持しているものと一致することが保証される。
The after_create
trigger is invoked after the database insert has executed.
データベースへの挿入が実行された後、after_create
トリガが発動する。
find_or_create¶
my $cd = Music::CD->find_or_create({ artist => 'U2', title => 'Boy' });
This checks if a CD can be found to match the information passed, and if not creates it.
これは、渡された情報にマッチしたCDがあったかどうかを判定し、もしも 存在しないならばデータを作成する。
delete¶
$obj->delete;
Music::CD->delete(year => 1980, title => 'Greatest %');
Deletes this object from the database and from memory. If you have set up any relationships using has_many, this will delete the foreign elements also, recursively (cascading delete). $obj is no longer usable after this call.
このオブジェクトをデータベースとメモリから削除する。もしもhas_manyを 使って何らかのリレーションシップを設定しているなら、このメソッドは 外部要素も再帰的に削除する(波及削除)。このメソッドを呼び出した後は もはや$objは使用不可能である。
If called as a class method, deletes all objects matching the search criteria given. Each object found will be deleted in turn, so cascading delete and other triggers will be honoured.
クラスメソッドとして呼び出すと、与えられた規準による検索にマッチした オブジェクトを全て削除する。見つかったオブジェクトは各々、その都度 削除される。そのため、波及削除とその他のトリガは履行される。
The before_delete
trigger is when an object instance is about to be deleted. It is invoked before any cascaded deletes. The after_delete
trigger is invoked after the record has been deleted from the database and just before the contents in memory are discarded.
オブジェクトインスタンスが削除され出すときが、before_delete
トリガの 発動するときである。このトリガは波及削除の前に発動する。after_delete
トリガはレコードがデータベースから削除された後、かつ、メモリ内の コンテンツが破棄される直前に発動される。
オブジェクトの取り出し¶
We provide a few simple search methods, more to show the potential of the class than to be serious search methods.
我々はわずかだがシンプルな検索用メソッドを提供する。これは大真面目な検索 メソッドである以上に、このクラスの潜在的能力を示している。
retrieve¶
$obj = Class->retrieve( $id );
$obj = Class->retrieve( %key_values );
Given key values it will retrieve the object with that key from the database. For tables with a single column primary key a single parameter can be used, otherwise a hash of key-name key-value pairs must be given.
キーの値を指定すると、データベースからそのキーを持ったオブジェクトを 取り出す。ひとつのカラム主キーを持ったテーブルに対しては、一つの パラメータが使用できる。そうでなければ、キー名・キー値のペアとなる ハッシュを指定しなければならない。
my $cd = Music::CD->retrieve(1) or die "No such cd";
retrieve_all¶
my @objs = Class->retrieve_all;
my $iterator = Class->retrieve_all;
Retrieves objects for all rows in the database. This is probably a bad idea if your table is big, unless you use the iterator version.
データベースの全行からオブジェクトを取り出す。テーブルが大きな場合に イテレータ版を使わないなら、恐らくこの方法はまずいことになるだろう。
search¶
@objs = Class->search(column1 => $value, column2 => $value ...);
This is a simple search for all objects where the columns specified are equal to the values specified e.g.:
このメソッドは単純に、指定したカラムと指定した値が等しい全オブジェクトを 探し出す。例えば:
@cds = Music::CD->search(year => 1990);
@cds = Music::CD->search(title => "Greatest Hits", year => 1990);
You may also specify the sort order of the results by adding a final hash of arguments with the key 'order_by':
引数の最後に'order_by'というキーのハッシュを加えることで、結果に対して ソート順も指定できる。
@cds = Music::CD->search(year => 1990, { order_by=>'artist' });
search_like¶
@objs = Class->search_like(column1 => $like_pattern, ....);
This is a simple search for all objects where the columns specified are like the values specified. $like_pattern is a pattern given in SQL LIKE predicate syntax. '%' means "any one or more characters", '_' means "any single character".
このメソッドは単純に、指定したカラムが指定した値と似ている全オブジェクトを 探し出す。$like_patternは、SQLのLIKE叙述構文で与えられたパターンである。 '%'は”一つないしはそれ以上の任意のキャラクタ”を、'_'は”任意の一キャラクタ” を意味している。
@cds = Music::CD->search_like(title => 'October%');
@cds = Music::CD->search_like(title => 'Hits%', artist => 'Various%');
You can also use 'order_by' with these, as with search().
search()同様、これらにも'order_byが使える。'
イテレータ¶
my $it = Music::CD->search_like(title => 'October%');
while (my $cd = $it->next) {
print $cd->title;
}
Any of the above searches (as well as those defined by has_many) can also be used as an iterator. Rather than creating a list of objects matching your criteria, this will return a Class::DBI::Iterator instance, which can return the objects required one at a time.
上記の検索メソッドは(has_manyによる定義と同様)イテレータとしても使える。 これは基準に適合したオブジェクトのリストを生成するのではなくて、 Class::DBI::Iteratorインスタンスを返す。このインスタンスは必要な オブジェクトを一度に返すことができる。
Currently the iterator initially fetches all the matching row data into memory, and defers only the creation of the objects from that data until the iterator is asked for the next object. So using an iterator will only save significant memory if your objects will inflate substantially when used.
現在のところ、イテレータはまず最初に適合した全ての行データをメモリに フェッチし、イテレータが次のオブジェクトを要求されるまで、そのデータから オブジェクトを生成するのを遅延する。よって、実質的には使用の際にオブジェクトが インフレートする場合にのみ、イテレータの利用でメモリが大幅に節約できる。
In the case of has_many relationships with a mapping method, the mapping method is not called until each time you call 'next'. This means that if your mapping is not a one-to-one, the results will probably not be what you expect.
マッピングメソッドを伴うhas_manyリレーションシップの場合、あなたが'next'を 呼び出すまでマッピングメソッドは呼ばれない。このことは、マッピングが一対一で ないなら、その結果は恐らくあなたが期待するようなものにはならないということを 意味している。
イテレータのサブクラス化¶
Music::CD->iterator_class('Music::CD::Iterator');
You can also subclass the default iterator class to override its functionality. This is done via class data, and so is inherited into your subclasses.
デフォルトのイテレータクラスのサブクラスをつくることで、その機能を オーバーライドすることもできる。これはクラスデータを通じてなされるので サブクラスへ継承される。
素早い取り出し¶
my $obj = Class->construct(\%data);
This is a protected method and can only be called by subclasses of Class::DBI. It is used to turn data from the database into objects, and should thus only be used when writing constructors.
これはprotectedメソッドであり、Class::DBIのサブクラスからのみ 呼び出せる。データベースのデータをオブジェクトに返すのに利用される。 それゆえ、コンストラクタを書くときにだけ使うようにするべきだ。
This is very handy for cheaply setting up lots of objects from data for without going back to the database.
データベースへ戻りに行かずとも、データから大量のオブジェクトを手軽に 用意できる点が大変便利だ。
For example, instead of doing one SELECT to get a bunch of IDs and then feeding those individually to retrieve() (and thus doing more SELECT calls), you can do one SELECT to get the essential data of many objects and feed that data to construct():
例えばSELECTでIDの束を取り出し、それらのIDを個々retrieve()に与える (つまり多くのSELECTコールを行なうということ)代わりに、一つのSELECTで 多くのオブジェクトの実質データを取り出し、そのデータをconstruct()に与え られる。
return map $class->construct($_), $sth->fetchall_hash;
The construct() method creates a new empty object, loads in the column values, and then invokes the select
trigger.
construct()メソッドは新規の空オブジェクトを生成し、そのカラムに値を ロードする。そしてそれからselect
トリガを発生させる。
コピーと移動¶
copy¶
$new_obj = $obj->copy;
$new_obj = $obj->copy($new_id);
$new_obj = $obj->copy({ title => 'new_title', rating => 18 });
This creates a copy of the given $obj, removes the primary key, sets any supplied column values and called create() to insert a new record in the database.
このメソッドは、$objのコピーをつくり、主キーを削除し、カラムの値を セットし、そして新たなレコードをデータベースに挿入するためにcreate()を 呼び出す。
For tables with a single column primary key, copy() can be called with no parameters and the new object will be assigned a key automatically. Or a single parameter can be supplied and will be used as the new key.
主キーが一つだけのテーブルは、copy()をパラメータ無しで呼べる。 この場合新しいオブジェクトには自動的に主キーが割り当てられる。 あるいはパラメータを一つ与えると、それが新しい主キーとして使われる。
For tables with a multi-olumn primary key, copy() must be called with parameters which supply new values for all primary key columns, unless a before_create
trigger will supply them. The create() method will fail if any primary key columns are not defined.
複数の主キーを持つテーブルでは、全ての主キー用に新しい値を提供しないといけ ないので、before_create
がそれらの新しい値を提供しない限り、パラメータを つけてcopy()を呼ばなければならない。主キーを定義しないとcreate()メソッドは 失敗する。
my $blrunner_dc = $blrunner->copy("Bladerunner: Director's Cut");
my $blrunner_unrated = $blrunner->copy({
Title => "Bladerunner: Director's Cut",
Rating => 'Unrated',
});
move¶
my $new_obj = Sub::Class->move($old_obj);
my $new_obj = Sub::Class->move($old_obj, $new_id);
my $new_obj = Sub::Class->move($old_obj, \%changes);
For transfering objects from one class to another. Similar to copy(), an instance of Sub::Class is created using the data in $old_obj (Sub::Class is a subclass of $old_obj's subclass). Like copy(), you can supply $new_id as the primary key of $new_obj (otherwise the usual sequence or autoincrement is used), or a hashref of multiple new values.
あるクラスから別のクラスへとオブジェクトを移動する。copy()と同じように $old_obj内のデータを使ってSub::Classのインスタンスを生成する(Sub::Classは $old_objのサブクラスのサブクラス)。copy()同様、$new_objの主キーとして $new_idを与えるか(与えなければ通常のシーケンス、あるいは自動インクリメントが 用いられる)、複数の新しい値のハッシュリファレンスを与える。
トリガ¶
__PACKAGE__->add_trigger(trigger_point_name => \&code_to_execute);
# e.g.
__PACKAGE__->add_trigger(after_create => \&call_after_create);
It is possible to set up triggers that will be called at various points in the life of an object. Valid trigger points are:
オブジェクトの生成消滅までの様々なポイントで呼び出すトリガを設定できる。 適切なポイントは以下とおり:
before_create (also used for deflation)
after_create
before_set_$column (also used by add_constraint)
after_set_$column (also used for inflation and by has_a)
before_update (also used for deflation and by might_have)
after_update
before_delete
after_delete
select (also used for inflation and by construct and _flesh)
You can create any number of triggers for each point, but you cannot specify the order in which they will be run. Each will be passed the object being dealt with (whose values you may change if required), and return values will be ignored.
各ポイント毎に任意の数のトリガをつくれるが、それらが実行される順番を 指定することはできない。各トリガにはデフォルトでオブジェクトが渡され (必要ならオブジェクトの値を変更する)、戻り値は無視される。
All triggers are passed the object they are being fired for. Some triggers are also passed extra parameters as name-value pairs. The individual triggers are documented with the methods that trigger them.
全てのトリガには、トリガを引き起こしたオブジェクトが渡される。また、 いくつかのトリガには、名前と値のペアによる追加のパラメータが渡される。 個々のトリガに関するドキュメントは、それを起こすメソッドのところで触れている。
制約¶
__PACKAGE__->add_constraint('name', column => \&check_sub);
# 例
__PACKAGE__->add_constraint('over18', age => \&check_age);
# シンプルな例
sub check_age {
my ($value) = @_;
return $value >= 18;
}
# クロスフィールドチェック - age < 18 ならSSNがなければならない
sub check_age {
my ($value, $self, $column_name, $changing) = @_;
return 1 if $value >= 18; # 十分な年齢だ
return 1 if $changing->{SSN}; # SSN (社会保障番号) を与えられる
return 0 if !ref($self); # これはcreateなのでSSNを持っていない
return 1 if $self->ssn; # 既にデータベース上にある
return 0; # どこにもSSNを発見できなかった
}
It is also possible to set up constraints on the values that can be set on a column. The constraint on a column is triggered whenever an object is created and whenever the value in that column is being changed.
カラムに設定できない値に対しても制約は設定できる。オブジェクトが生成される ときはいつでも、そしてそのカラムの値が変更されるときはいつでも、カラムに 対する制約が発動される。
The constraint code is called with four parameters:
制約のコードは四つのパラメータを伴って呼び出される。
- The new value to be assigned
- The object it will be assigned to
(or class name when initially creating an object)
- The name of the column
(useful if many constraints share the same code)
- A hash ref of all new column values being assigned
(useful for cross-field validation)
- 代入される新しい値
- 代入されるオブジェクト(最初にオブジェクトがcreateされるときはクラス名)
- カラム名(たくさんの制約が同じコードを共有している場合に便利)
- 代入される新しいカラム値全てのハッシュリファレンス
(クロスフィールドの妥当性チェックに便利)
The constraints are applied to all the columns being set before the object data is changed. Attempting to create or modify an object where one or more constraint fail results in an exception and the object remains unchanged.
制約は、そのオブジェクトデータが変更される前に、設定される全てのカラムに 対して適用される。オブジェクトの生成や変更を試み、一つ以上の制約が 失敗して例外を発生させると、そのオブジェクトは変更されないままである。
Note 1: Constraints are implemented using before_set_$column triggers. This will only prevent you from setting these values through a the provided create() or set() methods. It will always be possible to bypass this if you try hard enough.
注意1:制約はbefore_set_$columnトリガを使って実装されている。このため、 あなたが提供済みのcreate()やset()メソッドを通じてそれらを設定すること だけはできない。これについては、あなたが十分苦労をすればいつでも抜け道が ある。
Note 2: When an object is created constraints are currently only checked for column names included in the parameters to create(). This is probably a bug and is likely to change in future.
注意2:オブジェクトが生成されるとき、現在のところ制約はcreate()に 渡されたパラメータに含まれるカラム名だけをチェックする。これは 恐らくバグであり、将来は変更されるだろう。
データの正規化¶
Before an object is assigned data from the application (via create or a set accessor) the normalize_column_values() method is called with a reference to a hash containing the column names and the new values which are to be assigned (after any validation and constraint checking, as described below).
アプリケーションから(createやsetアクセサを通じて)オブジェクトに データが割り当てられる前に、ハッシュへのリファレンスを伴って normalize_column_values()メソッドが呼び出される。ハッシュはカラム名と 割り当てられる新しい値を含む(下記にあるように、妥当性チェックと制約 チェックの後)。
Currently Class::DBI does not offer any per-column mechanism here. The default method is empty. You can override it in your own classes to normalize (edit) the data in any way you need. For example the values in the hash for certain columns could be made lowercase.
現在のところ、Class::DBIはカラム毎のチェックメカニズムを提供していない。 デフォルトのメソッドは空だ。あなた自身のクラス内で、望むやり方で メソッドをオーバーライドすればデータの正規化(編集)が行える。例えば、 ハッシュ内のあるカラムの値を小文字にするとか。
The method is called as an instance method when the values of an existing object are being changed, and as a class method when a new object is being created.
既存のオブジェクトの値が変更されるとき、このメソッドはインスタンスメソッド として呼び出される。そして新しいオブジェクトが生成されるときには、クラス メソッドとして呼び出される。
データの妥当性チェック¶
Before an object is assigned data from the application (via create or a set accessor) the validate_column_values() method is called with a reference to a hash containing the column names and the new values which are to be assigned.
アプリケーションから(createかsetアクセサを通じて)オブジェクトにデータが 割り当てられる前に、validate_column_values()が呼び出される。このメソッド には、カラム名と割り当てられる新しい値を含んだハッシュへのリファレンスが 渡される。
The method is called as an instance method when the values of an existing object are being changed, and as a class method when a new object is being created.
既存のオブジェクトの値が変更されるとき、このメソッドはインスタンスメソッド として呼び出される。そして新しいオブジェクトが生成されるときには、クラス メソッドとして呼び出される。
The default method calls the before_set_$column trigger for each column name in the hash. Each trigger is called inside an eval. Any failures result in an exception after all have been checked. The exception data is a reference to a hash which holds the column name and error text for each trigger error.
デフォルトのメソッドは、ハッシュ内の各カラムに対するbefore_set_$column トリガを呼び出す。何か失敗すると、全てチェックし終えた後に例外を発生 させる。この例外データは、各トリガのエラー毎にカラム名とエラーテキストを 含んだハッシュリファレンスである。
When using this mechanism for form data validation, for example, this exception data can be stored in an exception object, via a custom _croak() method, and then caught and used to redisplay the form with error messages next to each field which failed validation.
フォームデータの妥当性チェックにこのメカニズムを使うと、例えば、例外 データをカスタマイズした_croak()を通じて例外オブジェクトに格納してから 捕捉できる。そして妥当性チェックに失敗した各フィールドの横にエラー メッセージを出しつつ、再度フォームの表示に利用できる。
例外処理¶
All errors that are generated, or caught and propagated, by Class::DBI are handled by calling the _croak() method (as an instance method if possible, or else as a class method).
エラーが発生、あるいは捕捉されて伝搬すると、Class::DBIは _croak()メソッドを呼び出して処理を行う(可能ならインスタンス メソッドとして、さもなければクラスメソッドとして)。
The _croak() method is passed an error message and in some cases some extra information as described below. The default behaviour is simply to call Carp::croak($message).
_croak()メソッドにはエラーメッセージが渡されるが、場合によっては 下記に示したように、追加情報が渡される。デフォルトの振る舞いは 単にCarp::croak($message)を呼び出すだけである。
Applications that require custom behaviour should override the _croak() method in their application base class (or table classes for table-specific behaviour). For example:
独自の振る舞いを必要とするアプリケーションでは、アプリケーション ベースクラスにおいて_croak()メソッドをオーバーライドすること (テーブル独自の振る舞いはテーブルクラスでオーバーライドする)。
use Error;
sub _croak {
my ($self, $message, %info) = @_;
# 無視する予定の二重挿入エラー以外は
# エラーを例外オブジェクトに変換
Error->throw(-text => $message, %info)
unless $message =~ /^Can't insert .* duplicate/;
return;
}
The _croak() method is expected to trigger an exception and not return. If it does return then it should use return;
so that an undef or empty list is returned as required depending on the calling context. You should only return other values if you are prepared to deal with the (unsupported) consequences.
_croak()メソッドは例外を発生させることが期待されるので、returnしない。 もし本当にreturnするなら、return;
とすること。こうすれば呼び出された 文脈に応じてundefか空リストが返される。もしも(サポートしていない)結果 を処理する準備ができているなら、他の値を返してもよい。
For exceptions that are caught and propagated by Class::DBI, $message includes the text of $@ and the original $@ value is available in $info{err}. That allows you to correctly propagate exception objects that may have been thrown 'below' Class::DBI (using Exception::Class::DBI for example).
Class::DBIが捕捉・伝搬した例外では、$messageは$@のテキストを含んでおり、 $@の元々の値は$info{err}から利用できる。これを使ってClass::DBI'に'投げ られた例外オブジェクトを正しく伝搬できる(例えばException::Class::DBI)。
Exceptions generated by some methods may provide additional data in $info{data} and, if so, also store the method name in $info{method}. For example, the validate_column_values() method stores details of failed validations in $info{data}. See individual method documentation for what additional data they may store, if any.
あるメソッドによって発生した例外は$info{data}に追加データを提供する。 そしてその場合、$info{method}にはメソッド名も格納される。例えば、 validate_column_values()メソッドは$info{data}に失敗した妥当性チェックの 詳細を格納する。どんな追加データが保持されるかについては、(もしあれば) 個々のメソッドのドキュメントを参照してもらいたい。
警告 (Warning)¶
All warnings are handled by calling the _carp() method (as an instance method if possible, or else as a class method). The default behaviour is simply to call Carp::carp().
全ての警告は_carp()メソッドを呼び出して処理される(可能なら インスタンスメソッドとして、そうでなければクラスメソッドとして)。 デフォルトの振る舞いは、単にCarp::carp()を呼び出すだけだ。
インスタンスメソッド¶
アクセサ¶
Class::DBI inherits from Class::Accessor and thus provides individual accessor methods for every column in your subclass. It also overrides the get() and set() methods provided by Accessor to automagically handle database reading and writing. (Note that as it doesn't make sense to store a list of values in a column, set() takes a hash of column => value pairs, rather than the single key => values of Class::Accessor).
Class::DBIはClass::Accessorを継承しているので、あなたのサブクラスにある カラム毎に個々のアクセサを提供する。また、Accessorが提供するget()とset() メソッドをオーバーライドして、データベースの読み書きを自動的に処理する ようにする(あるカラムの値のリストを格納するという意味ではないことに注意、 set()は column => value ペアのハッシュを取るのであって、 一つのkey => Class::Accessorの複数の値をとるのではない)。
基本となるset()とget()メソッド¶
$value = $obj->get($column_name);
@values = $obj->get(@column_names);
$obj->set($column_name => $value);
$obj->set($col1 => $value1, $col2 => $value2 ... );
These methods are the fundamental entry points for getting and seting column values. The extra accessor methods automatically generated for each column of your table are simple wrappers that call these get() and set() methods.
これらのメソッドは、カラム値の取得と設定の基礎をなすエントリーポイント である。あなたのテーブルの各カラム毎に自動で生成される追加のアクセサ メソッドは、単純にこれらget()とset()メソッドのラッパーである。
The set() method calls normalize_column_values() then validate_column_values() before storing the values. The before_set_$column
trigger is invoked by validate_column_values(), checking any constraints that may have been set up. The after_set_$column
trigger is invoked after the new value has been stored.
set()メソッドはnormalize_column_values()を呼び出し、それから値を格納する 前にvalidate_column_values()を呼び出す。before_set_$column
トリガは validate_column_values()によって発動され、用意されていた制約のチェックを 行う。after_set_$column
トリガは、その新しい値が格納された後で発動する。
It is possible for an object to not have all its column data in memory (due to lazy inflation). If the get() method is called for such a column then it will select the corresponding group of columns and then invoke the select
trigger.
オブジェクトは、一部のカラムデータをメモリに持たないでいることが可能だ (lazyインフレーション)。そのようなカラムに対してget()メソッドが 呼ばれると、メソッドは対応するカラムグループを選び、select
トリガを 発動する。
カラムアクセサメソッドの名前を変更する¶
If you want to change the name of your accessors, you need to provide an accessor_name() method, which will convert a column name to a method name.
アクセサの名前を変更したいなら、accessor_name()メソッドを用意することに なる。これはカラム名をメソッド名に変換する。
e.g: if your local naming convention was to prepend the word 'customer' to each column in the 'customer' table, so that you had the columns 'customerid', 'customername' and 'customerage', you would end up with code filled with calls to $customer->customerid, $customer->customername, $customer->customerage etc. By creating an accessor_name method like:
例えば:あなたの名前の付け方の慣習から、'customere'テーブルの内の 各コラムに対して'customer'という単語を付け加え、'customerid'、 'customername'そして'customerage'を持つとする。あなたのコードは $customer->customerid、$customer->customername、$customer->customerage を呼び出すだろう。そこで以下のaccessor_nameメソッドをつくることによって:
sub accessor_name {
my ($class, $column) = @_;
$column =~ s/^customer//;
return $column;
}
Your methods would now be the simpler $customer->id, $customer->name and $customer->age etc.
メソッドはよりシンプルに$customer->id、$customer->nameそして $customer->age等々となる。
Similarly, if you want to have distinct accessor and mutator methods, you would provide a mutator_name() method which would return the name of the method to change the value:
似たようなものだが、あなたがアクセサメソッドとミューテターメソッドを 区別したいなら、mutator_name()を用意する。このメソッドは、値を変更する ためのメソッドの名前を返す:
sub mutator_name {
my ($class, $column) = @_;
return "set_$column";
}
If you override the mutator_name, then the accessor method will be enforced as read-only, and the mutator as write-only.
mutator_nameをオーバーライドすると、アクセサメソッドは強制的に read-onlyになり、ミューテータはwrite-onlyとなる。
update vs 自動update¶
There are two modes for the accessors to work in: manual update and autoupdate. When in autoupdate mode, every time one calls an accessor to make a change an UPDATE will immediately be sent to the database. Otherwise, if autoupdate is off, no changes will be written until update() is explicitly called.
アクセサと協調して動作する二つのモード:updateとautoupdate。 autoupdateモードの場合、アクセサを呼び出して変更を行なうたびに、 直ちにデータベースにUPDATEが送られる。それ以外、autoupdateがオフの場合、 update()を明示的に呼び出さない限り、変更は書き込まれない。
This is an example of manual updating:
これは手動更新の例:
# NumExplodingSheep()とRating()の呼び出しはメモリ内に変更を加える
# だけで、データベースを変更しない。ひとたびupdate()を呼び出すと
# 変更は一挙にデータベースに書き込まれる。
$gone->NumExplodingSheep(5);
$gone->Rating('NC-17');
$gone->update;
And of autoupdating:
そして自動更新:
# このオブジェクトに対して自動更新を有効にする
$gone->autoupdate(1);
# アクセサを呼ぶ毎に新しい値が直接書き込まれる
$gone->NumExplodingSheep(5);
$gone->Rating('NC-17');
Manual updating is probably more efficient than autoupdating and it provides the extra safety of a discard_changes() option to clear out all unsaved changes. Autoupdating can be more convient for the programmer. Autoupdating is off by default.
手動更新はたぶん自動更新よりも効率的だ。そしてdiscard_changes()の 安全性を増す。つまり、未セーブの変更をクリアしてくれる選択肢が加わる。 自動更新はプログラマにとって、より便利になるだろう。自動更新はデフォルトで 無効になっている。
If changes are left un-updated or not rolledback when the object is destroyed (falls out of scope or the program ends) then Class::DBI's DESTROY method will print a warning about unsaved changes.
(スコープから外れるかプログラムが終了することで)オブジェクトが破壊 されるときに、変更点が未更新のままだったり、ロールバックしなかったりすると、 Class::DBIのDESTROYメソッドは未セーブの変更に関する警告を発する。
autoupdate¶
__PACKAGE__->autoupdate($on_or_off);
$update_style = Class->autoupdate;
$obj->autoupdate($on_or_off);
$update_style = $obj->autoupdate;
This is an accessor to the current style of auto-updating. When called with no arguments it returns the current auto-updating state, true for on, false for off. When given an argument it turns auto-updating on and off: a true value turns it on, a false one off.
これは現在の自動更新状態へのアクセサである。引数無しでメソッドを 呼び出すと、現在の自動更新状態、有効なら真、無効なら偽が返される。 引数を与えると自動更新を有効あるいは無効にする: 真値なら有効、偽値なら無効。
When called as a class method it will control the updating style for every instance of the class. When called on an individual object it will control updating for just that object, overriding the choice for the class.
クラスメソッドとして呼ぶと、全てのインスタンスに対して更新スタイルを 制御する。個々のオブジェクトで呼び出した場合は、クラスに対するスタイルを オーバーライドして、そのオブジェクトに対する制御を行なう。
__PACKAGE__->autoupdate(1); # クラスに対して自動更新を有効
$obj = Class->retrieve('Aliens Cut My Hair');
$obj->autoupdate(0); # このオブジェクトでは自動更新を無効
The update setting for an object is not stored in the database.
オブジェクトに対する更新の設定はデータベースに格納されない。
update¶
$obj->update;
If autoupdate is not enabled then changes you make to your object are not reflected in the database until you call update(). It is harmless to call update() if there are no changes to be saved. (If autoupdate is on there'll never be anything to save.)
autoupdateが有効でない場合、オブジェクトに対して行なった変更は、 update()を呼び出すまで、データベースに反映されない。セーブするべき 変更点なしにupdate()を呼んでも害は無い(自動更新が有効なら、セーブ するべきことは何も無いだろう)。
Note: If you have transactions turned on for your database (but see "TRANSACTIONS" below) you will also need to call dbi_commit(), as update() merely issues the UPDATE to the database).
注意:データベースのトランザクションを有効にしている場合(下の "トランザクション"を参照)、さらにdbi_commitを呼び出す必要がある。 というのも、update()は単にデータベースにUPDATEを送るだけだからだ。
After the database update has been executed, the data for columns that have been updated are deleted from the object. If those columns are accessed again they'll simply be fetched as needed. This ensures that the data in the application is consistant with what the database actually stored.
データベースの更新が実行された後、更新されたカラムのデータは オブジェクトから削除される。再度これらのカラムにアクセスすると、必要に 応じてデータベースから取り出してくる。これによって、アプリケーション内の データとデータベースが実際に保持しているものとの一致が保証される。
When update() is called the before_update
($self) trigger is always invoked immediately.
update()を呼び出すと、常に直ちにbefore_update
($self)トリガが 発動される。
If any columns have been updated then the after_update
trigger is invoked after the database update has executed and is passed: ($self, discard_columns => \@discard_columns, rows => $rows)
何らかのカラムが更新されると、データベースの更新が実行された後、 after_update
トリガが発動する。渡されるのは: ($self, discard_columns => \@discard_columns, rows => $rows)
(where rows is the return value from the DBI execute() method).
(rowsはDBI execute()メソッドからの戻値が入る)
The trigger code can modify the discard_columns array to affect which columns are discarded.
このトリガのコードは、discard_columns配列を変更することで、どの カラムを破棄するかに影響を及ぼすことができる。
For example:
Class->add_trigger(after_update => sub {
my ($self, %args) = @_;
my $discard_columns = $args{discard_columns};
# 'foo'で始まるフィールドの更新がなされた場合、md5_hashカラムは
# 破棄される。なぜならmd5_hashはトリガによって変更されてしまう
# からだ。
push @$discard_columns, 'md5_hash' if grep { /^foo/ } @$discard_columns;
});
Take care to not delete a primary key column unless you know what you're doing.
自分が何をしているのかわかっていないなら、主キーを削除しないように 注意すること。
The update() method returns the number of rows updated, which should always be 1, or else -1 if no update was needed. If the record in the database has been deleted, or its primary key value changed, then the update will not affect any records and so the update() method will return 0.
update()メソッドは更新された行の数を返す。これは常に1を返すか、あるいは 更新する必要がなかった場合には-1が返る。データベース内のレコードが削除 されると、あるいは主キーが変更されると、更新はいかなるレコードにも影響を 与えない。そのため、update()メソッドは0を返す。
discard_changes¶
$obj->discard_changes;
Removes any changes you've made to this object since the last update. Currently this simply discards the column values from the object.
最後に更新をしてからこのオブジェクトに加えた変更を取り除く。 現在のところ、これは単にオブジェクトからカラム値を破棄するだけだ。
If you're using autoupdate this method will throw an exception.
自動更新を使っている場合、このメソッドは例外を投げる。
is_changed¶
my $changed = $obj->is_changed;
my @changed_keys = $obj->is_changed;
Indicates if the given $obj has changes since the last update. Returns a list of keys which have changed.
指定した$objが最後の更新から変更されたかどうかを掲示する。変更された キーのリストを返す。
id¶
$id = $obj->id;
Returns a unique identifier for this object. It's the equivalent of $obj->get($self->columns('Primary')); A warning will be generated if this method is used on a table with a multi-column primary key.
このオブジェクトの一意な識別子を返す。obj->get($self->columns('Primary')); に等しい。複数の主キーカラムを持つテーブルでこのメソッドを使うと、 警告を発する。
オーバーロードされた演算子¶
Class::DBI and its subclasses overload the perl builtin stringify and bool operators. This is a significant convienience.
Class::DBIとそのサブクラスはperl組み込みの文字列演算子と ブール演算子をオーバーロードする。これは非常に便利だ。
The perl builtin bool operator is overloaded so that a Class::DBI object reference is true so long as all its key columns have defined values. (This means an object with an id() of zero is not considered false.)
組み込みのブール演算子がオーバーロードされる結果、Class::DBIオブジェクト リファレンスは、全カラムの値が定義されている限り真となる(つまり、id()が 0を返すオブジェクトでも偽とみなさないですむわけだ)。
When a Class::DBI object reference is used in a string context it will, by default, return the value of the primary key. (Composite primary key values will be separated by a slash).
Class::DBIオブジェクトリファレンスが文字列コンテキストで使われた場合、 デフォルトで主キーの値を返す(複合主キーの値はスラッシュで区切られる)。
You can also specify the column(s) to be used for stringification via the special 'Stringify' column group. So, for example, if you're using an auto-incremented primary key, you could use this to provide a more meaningful display string:
特別な'Stringify'カラムグループを通じて、カラムを文字列化するように 指定することもできる。だから例えば、あなたが自動インクリメントされる 主キーを使っているなら、この仕組みを使ってより意味のある文字列を表示 させることができる:
Widget->columns(Stringify => qw/name/);
If you need to do anything more complex, you can provide an stringify_self() method which stringification will call:
もっと複雑なことがしたいなら、文字列化で呼び出されるstringify_self()メソッド を用意できる。
sub stringify_self {
my $self = shift;
return join ":", $self->id, $self->name;
}
This overloading behaviour can be useful for columns that have has_a() relationships. For example, consider a table that has price and currency fields:
このオーバーロードの振る舞いは、has_a()リレーションシップを持つカラムに 対して有用となろう。例えば、価格と通貨フィールドを持つテーブルを考えてみる:
package Widget;
use base 'My::Class::DBI';
Widget->table('widget');
Widget->columns(All => qw/widgetid name price currency_code/);
$obj = Widget->retrieve($id);
print $obj->price . " " . $obj->currency_code;
The would print something like "42.07 USD
". If the currency_code field is later changed to be a foreign key to a new currency table then $obj->currency_code will return an object reference instead of a plain string. Without overloading the stringify operator the example would now print something like "42.07 Widget=HASH(0x1275}
" and the fix would be to change the code to add a call to id():
これは"42.07 USD
"のように表示されるだろう。currency_codeフィールドが 後で変更されて、新しい通貨テーブルの外部キーとなった場合、 $obj->currency_codeは平素な文字列の代わりにオブジェクトリファレンスを 返す。文字列演算子をオーバーロードできなければ、今やこの例は "42.07 Widget=HASH(0x1275}
"などと表示されてしまう。そしてid()を 呼び出すようにコードを修正してやらなければならないだろう。
print $obj->price . " " . $obj->currency_code->id;
However, with overloaded stringification, the original code continues to work as before, with no code changes needed.
しかし、文字列化演算子をオーバーロードできるので、元のコードは以前の ままに動作し、コードを変更する必要はなくなる。
This makes it much simpler and safer to add relationships to exisiting applications, or remove them later.
この機能を使うことで、既存のアプリケーションにリレーションシップを追加 したり、後でそれらを取り除いたりするのがより簡単に、より安全になる。
テーブルのリレーションシップ¶
Databases are all about relationships. And thus Class::DBI needs a way for you to set up descriptions of your relationhips.
データベースとは全てリレーションシップに関係したものだ。Class::DBIは あなたがリレーションシップの記述を設定してくれることを望む。
Currently we provide three such methods: 'has_a', 'has_many', and 'might_have'.
現在のところ、我々はそのような三つのメソッドを提供する:'has_a'、 'has_many'、そして'might_have'だ。
has_a¶
Music::CD->has_a(artist => 'Music::Artist');
print $cd->artist->name;
We generally use 'has_a' to supply lookup information for a foreign key, i.e. we declare that the value we have stored in the column is the primary key of another table. Thus, when we access the 'artist' method we don't just want that ID returned, but instead we inflate it to this other object.
我々は一般的に'has_a'を使って検索情報を外部キーに提供する。つまり、 カラム内に格納した値が、別のテーブルの主キーであると宣言している。 よって、'artist'メソッドにアクセスしたときにそのIDが返ってくるのを 望むのではなく、代わりにこの別のオブジェクトへインフレートする。
However, we can also use has_a to inflate the data value to any other object. A common usage would be to inflate a date field to a Time::Piece object:
しかし、has_aを使ってそのデータを任意の別のオブジェクトにインフレート することもできる。次の例はどちらもデータフィールドをTime::Piece オブジェクトにインフレートしている:
Music::CD->has_a(reldate => 'Date::Simple');
print $cd->reldate->format("%d %b, %Y");
Music::CD->has_a(reldate => 'Time::Piece',
inflate => sub { Time::Piece->strptime(shift, "%Y-%m-%d") },
deflate => 'ymd',
);
print $cd->reldate->strftime("%d %b, %Y");
If the foreign class is another Class::DBI representation we will call retrieve() on that class with our value. Any other object will be instantiated either by calling new($value) or using the given 'inflate' method. If the inflate method name is a subref, it will be executed, and will be passed the value as an argument.
外部クラスが別のClass::DBIの代表であるなら、自クラスの持っている値を 使ってretrieve()を呼び出す。それ以外のオブジェクトの場合は、new($vlue)を 呼び出すか、あるいは'inflate'メソッドを使うことでインスタンス化される。 もしinflateメソッドの名前がコードリファレンスであるなら、それが実行され、 引数としてその値が渡される。
When the object is being written to the database the object will be deflated either by calling the 'deflate' method (if given), or by attempting to stringify the object.
そのオブジェクトがデータベースに書き込まれるとき、(指定しているなら) 'deflate'メソッドを呼び出すか、あるいはそのオブジェクトを文字列化しよう と試みることによって、オブジェクトはデフレートされる。
*NOTE* You should not attempt to make your primary key column inflate using has_a() as bad things will happen. If you have two tables which share a primary key, consider using might_have() instead.
*注意* has_a()を使って主キーカラムをインフレートするべきではない。悪い ことが起きるだろう。主キーを共有する二つのテーブルがあるなら、代わりに might_have()の利用を検討すること。
has_many¶
Music::CD->has_many(tracks => 'Music::Track', 'cd');
my @tracks = $cd->tracks;
my $track6 = $cd->add_to_tracks({
position => 6,
title => 'Tomorrow',
});
We use 'has_many' to declare that someone else is storing our primary key in their table, and create a method which returns a list of all the associated objects, and another method to create a new associated object.
我々は'has_many'を使って、誰か他の人がその人のテーブルに我々の主キーを 保持していることを宣言し、関連する全オブジェクトのリストを返すメソッドと、 新しい関連オブジェクトを生成するもう一つのメソッドを生成する。
In the above example we say that the table of the Music::Track class contains our primary key in its 'cd' column, and that we wish to access all the occasions of that (i.e. the tracks on this cd) through the 'tracks' method. [Because the 'cd' is the moniker of the CD class, this argument is optional]
上の例では、Music::Trackクラスのテーブルは、'cd'カラムに我々の主キーを 含んでいる。そして'tracks'メソッドを通じて、そこにあるもの全て(つまり、 このCD上のトラック)にアクセスしようとしている['cd'はCDクラスの符牒 なので、この引数はオプションである]。
We also create an 'add_to_tracks' method that adds a track to a given CD. In this example this call is exactly equivalent to calling:
我々はまた、'add_to_tracks'を生成する。このメソッドは与えたCDにトラックを 追加する。上記例でこのメソッドを呼ぶことは、次の呼び出しと等価である:
my $track6 = Music::Track->create({
cd => $cd->id,
position => 6,
title => 'Tomorrow',
});
制限¶
Music::Artist->has_many(cds => 'Music::CD');
my @cds = $artist->cds(year => 1980);
When calling the has_many method, you can also supply any additional key/value pairs for restricting the search. The above example will only return the CDs with a year of 1980.
has_manyメソッドを呼び出すときに、検索に制限をかけるためにキー/値のペアを 追加で渡せる。上の例では1980年のCDだけが返される。
並び替え¶
Music::CD->has_many(tracks => 'Music::Track', { sort => 'playorder' });
Often you wish to order the values returned from has_many. This can be done by passing a hash ref containing a 'sort' value of the column by wish you want to order.
しばしば、has_manyから返される値を整列させたいことがある。これは 'sort'と並び替えたいカラム名のペアを含むハッシュリファレンスを渡す ことで可能だ。
マッピング¶
Music::CD->has_many(styles => [ 'Music::StyleRef' => 'style' ]);
For many-to-many relationships, where we have a lookup table, we can avoid having to set up a helper method to convert our list of cross-references into the objects we really want, by adding the mapping method to our foreign class declaration.
多対多のリレーションシップにおいて、ルックアップテーブルを持っている場合、 ヘルパーメソッドを用意してクロスリファレンスのリストを我々の望む オブジェクトに変換しなければならない状態を回避できる。これは、 マッピングメソッドに外部クラス宣言を追加することで行われる。
The above is exactly equivalent to:
上の例は次のものと正確に等価だ:
Music::CD->has_many(_style_refs => 'Music::StyleRef');
sub styles {
my $self = shift;
return map $_->style, $self->_style_refs;
}
might_have¶
Music::CD->might_have(method_name => Class => (@fields_to_import));
Music::CD->might_have(liner_notes => LinerNotes => qw/notes/);
my $liner_notes_object = $cd->liner_notes;
my $notes = $cd->notes; # $cd->liner_notes->notes; に等しい
might_have() is similar to has_many() for relationships that can have at most one associated objects. For example, if you have a CD database to which you want to add liner notes information, you might not want to add a 'liner_notes' column to your main CD table even though there is no multiplicity of relationship involved (each CD has at most one 'liner notes' field). So, we create another table with the same primary key as this one, with which we can cross-reference.
多くとも一つの関連したオブジェクトを持ちうるリレーションシップという点で、 might_have()はhas_many()に似ている。例えばCDのデータベースがあり、 ライナーノーツ情報をそこに加えたいとする。しかし例え複数のリレーションシップ (CDは多くとも一つ'liner notes'フィールドを持つ)が関わっていないとしても、 あなたはメインとなるCDテーブルに'liner_notes'カラムを付け加えたくはない だろう。そこで、同じ主キーを持ったもう一つのテーブルをこのカラムとして作成し、 それを利用してクロスリファレンスできるようにする。
But you don't want to have to keep writing methods to turn the the 'list' of liner_notes objects you'd get back from has_many into the single object you'd need. So, might_have() does this work for you. It creates you an accessor to fetch the single object back if it exists, and it also allows you import any of its methods into your namespace. So, in the example above, the LinerNotes class can be mostly invisible - you can just call $cd->notes and it will call the notes method on the correct LinerNotes object transparently for you.
しかし、has_manyから取得したliner_notesオブジェクトの'リスト'を、あなたの 望む一オブジェクトに戻すためにメソッドを書きつづけるなどということは したくない。そう、might_have()はあなたのためにこの仕事をやってくれる。 このメソッドは、もし存在するなら一つのオブジェクトを取り出すアクセサを 生成する。これを使って任意のメソッドをあなたの名前空間にインポートする こともできる。そこで上の例の場合、LinerNotesクラスをほとんど不可視に できる―$cd->notesと呼び出すだけでいい。そうすればあなたにとって透過的な 正しいLinerNotesを扱うnotesメソッドが呼び出される。
Making sure you don't have namespace clashes is up to you, as is correctly creating the objects, but I may make these simpler in later versions. (Particularly if someone asks for them!)
正しくオブジェクトを生成するためにも、名前空間の衝突が起きないように あなた自身で確認すること。ただ、私は今後のバージョンでこれらをより 簡単にできるようにするかもしれない(特に、誰かが私にそれを求めるなら!)。
注意¶
has_a(), might_have() and has_many() check that the relevant class has already been loaded. If it hasn't then they try to load the module of the same name using require. If the require fails because it can't find the module then it will assume it's not a simple require (i.e., Foreign::Class isn't in Foreign/Class.pm) and that you will take care of it and ignore the warning. Any other error, such as a syntax error, triggers an exception.
has_a()、might_have()そしてhas_many()は、関連モジュールが既にロード されているかチェックする。もしされていなければ、rquireを使って同じ名前の モジュールをロードしようと試みる。モジュールを見つけられず、requireが 失敗した場合、単純なrequireではだめであり(すなわち、Foreign::Class はForeign/Class.pmにはない)、あなたが処理の面倒をみて推定し、警告を 無視する。それ以外のエラー、例えば構文エラーなどは例外をトリガーする。
NOTE: The two classes in a relationship do not have to be in the same database, on the same machine, or even in the same type of database! It is quite acceptable for a table in a MySQL database to be connected to a different table in an Oracle database, and for cascading delete etc to work across these. This should assist greatly if you need to migrate a database gradually.
注意:リレーションシップにある二つのクラスが同じデータベース、同じマシン、 あるいは同じタイプのデータベースにさえもあってはならない! MySQL データベースがOracleデータベースの違うテーブルに接続したり、これらの データベースを横断して波及削除その他の操作が行なわれるのは、全く問題ない。 データベースを段階的に移植するつもりなら、このことが大いに役立つはずだ。
SQL文を定義する¶
There are several main approaches to setting up your own SQL queries:
あなた自身のSQL問い合わせを準備する主要なアプローチがいくつかある:
For queries which could be used to create a list of matching objects you can create a constructor method associated with this SQL and let Class::DBI do the work for you, or just inline the entire query.
オブジェクトにマッチするリスト生成に用いられる問い合わせをするために、 SQLに関連するコンストラクタメソッドを生成し、Class::DBIを働かせることが できる。あるいは完全なクエリーをインライン化できる。
For more complex queries you need to fall back on the underlying Ima::DBI query mechanism.
より複雑な問い合わせを利用するには、下支えしているIma::DBIの問い合わせ メカニズムを頼らなければならない。
add_constructor¶
__PACKAGE__->add_constructor(method_name => 'SQL_where_clause');
The SQL can be of arbitrary complexity and will be turned into: SELECT (essential columns) FROM (table name) WHERE <your SQL>
SQL文は好きなように複雑なものにでき、以下のようになる: SELECT (実質カラム) FROM (テーブル名) WHERE <あなたのSQL>
This will then create a method of the name you specify, which returns a list of objects as with any built in query.
これであなたの指定した名前のメソッドが生成される。このメソッドは、 組み込まれた問い合わせを使ってオブジェクトリストを返す。
For example:
例えば:
Music::CD->add_constructor(new_music => 'year > 2000');
my @recent = Music::CD->new_music;
You can also supply placeholders in your SQL, which must then be specified at query time:
また、SQL内にプレースホルダを入れられる。これは問い合わせ時に 指定されなければならない:
Music::CD->add_constructor(new_music => 'year > ?');
my @recent = Music::CD->new_music(2000);
retrieve_from_sql¶
On occassions where you want to execute arbitrary SQL, but don't want to go to the trouble of setting up a constructor method, you can inline the entire WHERE clause, and just get the objects back directly:
任意のSQLを実行はしたいが、コンストラクタメソッドの準備でゴタゴタに 巻き込まれたくないようなときは、完全なWHERE句を埋め込むやり方がある。 これで直接オブジェクトを取得できる:
my @cds = Music::CD->retrieve_from_sql(qq{
artist = 'Ozzy Osbourne' AND
title like "%Crazy" AND
year <= 1986
ORDER BY year
LIMIT 2,3
});
Ima::DBI queries¶
When you can't use 'add_constructor', e.g. when using aggregate functions, you can fall back on the fact that Class::DBI inherits from Ima::DBI and prefers to use its style of dealing with statemtents, via set_sql().
'add_constructor'が使えないとき、例えば集約関数を使う場合などは Class:DBIがIma::DBIを継承しており、set_sql()を通じて、SQL文を扱う スタイルを利用する事実に頼ればよい。
To assist with writing SQL that is inheritable into subclasses, several additional substitutions are available here: __TABLE__, __ESSENTIAL__ and __INDENTIFIER__. These represent the table name associated with the class, its essential columns, and the primary key of the current object, in the case of an instance method on it.
サブクラスへ継承可能なSQLを書く手助けとして、いくつかの追加的な代替手段が 利用可能である:__TABLE__、__ESSENTIAL__そして__INDENTIFIER__。 これらはそれぞれ、クラスに関連付けられたテーブル名、実質カラム、 そしてインスタンスメソッドとして使った場合の現在のオブジェクトの 主キーを表している。
For example, the SQL for the internal 'update' method is implemented as:
例えば、内部における'update'メソッド用のSQLはこのように実装されている:
__PACKAGE__->set_sql('update', <<"");
UPDATE __TABLE__
SET %s
WHERE __IDENTIFIER__
The 'longhand' version of the new_music constructor shown above would similarly be:
上の例であげたnew_musicを'省略しない記法'で書くと:
Music::CD->set_sql(new_music => qq{
SELECT __ESSENTIAL__
FROM __TABLE__
WHERE year > ?
};
This approach automatically sets up the method Music::CD->search_new_music(), which will execute this search and return the relevant objects or Iterator. (If you have placeholders in your query, you must pass the relevant arguments when calling your search method.)
この方法で自動的にMusic::CD->search_new_music()メソッドが用意され、 そのメソッドは検索を実行し、関連するオブジェクトやイテレータを返す。 (問い合わせの中にプレースホルダがある場合、検索メソッドを呼ぶ際に 関連する引数を渡さなければならない)
This does the equivalent of:
これは次と等価のものを実行する:
sub search_new_music {
my ($class, @args) = shift;
my $sth = $class->sql_new_music;
$sth->execute(@args);
return $class->sth_to_objects($sth);
}
The $sth which we use to return the objects here is a normal DBI-style statement handle, so if your results can't even be turned into objects easily, you can still call $sth->fetchrow_array etc and return whatever data you choose.
オブジェクトを返すためにここで我々が使っている$sthは、通常のDBI様 ステートメントハンドルである。そのため、あなたが得た結果が簡単には オブジェクトにならない場合でも、まだ$sth->fetchrow_arrayその他を 呼び出して、あなたが選んだデータなら何でも返すことができる。
Of course, any query can be added via set_sql, including joins. So, to add a query that returns the 10 Artists with the most CDs, you could write (with MySQL):
もちろん、set_sqlを通じて、どんな問い合わせも付け加えられる。joinを含めて。 そのため、最も多くのCDを出している10人のアーティストを返す問い合わせを加える には、このように書く(MySQLを使用):
Music::Artist->set_sql(most_cds => qq{
SELECT artist.id, COUNT(cd.id) AS cds
FROM artist, cd
WHERE artist.id = cd.artist
GROUP BY artist.id
ORDER BY cds DESC
LIMIT 10
});
my @artists = Music::Artist->search_most_cds();
Class::DBI::AbstractSearch¶
my @music = Music::CD->search_where(
artist => [ 'Ozzy', 'Kelly' ],
status => { '!=', 'outdated' },
);
The Class::DBI::AbstractSearch module, available from CPAN, is a plugin for Class::DBI that allows you to write arbitrarily complex searches using perl data structures, rather than SQL.
CPANから取得可能なClass::DBI::AbstractSearchモジュールは、 Class::DBIのプラグインであり、SQLではなくperlのデータ構造を 使って、任意の複雑な検索を書くことができる。
LAZY POPULATION¶
In the tradition of Perl, Class::DBI is lazy about how it loads your objects. Often, you find yourself using only a small number of the available columns and it would be a waste of memory to load all of them just to get at two, especially if you're dealing with large numbers of objects simultaneously.
Perlの伝統により、Class::DBIはあなたのオブジェクトをどのようにロードするか に関しては怠惰である。小数のカラムだけを利用するのに、メモリを浪費して全部の オブジェクトをロードしたあげく、ただ二つを取得するなどということがしばしば あるだろう。とくに、非常にたくさんのオブジェクトを同時に扱うような場合。
You should therefore group together your columns by typical usage, as fetching one value from a group can also pre-fetch all the others in that group for you, for more efficient access.
それゆえ、カラムをグループとしてまとめるべきである。典型例として、 グループから一つの値を取り出すのに、グループ内の他の全ての値も予め 取り出しておくことができ、より効率の良いアクセスを望める。
So for example, if we usually fetch the artist and title, but don't use the 'year' so much, then we could say the following:
そこで例えば、artistとtitleはいつも取り出すけれども、'year'はそれほど 使わない場合、以下のようにできる:
Music::CD->columns(Primary => qw/cdid/);
Music::CD->columns(Essential => qw/artist title/);
Music::CD->columns(Others => qw/year runlength/);
Now when you fetch back a CD it will come pre-loaded with the 'cdid', 'artist' and 'title' fields. Fetching the 'year' will mean another visit to the database, but will bring back the 'runlength' whilst it's there.
これでCDから取り出すときは、'cdid'、'artist'そして'title'フィールドが予め ロードされる。'year'を取り出すのはデータベースに対する別の訪問を意味するが、 この間に'runlength'は返ってくる。
This can potentially increase performance.
これは潜在的にパフォーマンスを向上させる可能性を持っている。
If you don't like this behavior, then just add all your non-primary key columns to the one group, and Class::DBI will load everything at once.
この振る舞いを望まないときは、非主キーカラムを全て一つのグループに 加えるだけでよい。そうすればClass::DBIは一度に全てをロードする。
columns¶
my @all_columns = $class->columns;
my @columns = $class->columns($group);
my @primary = $class->primary_columns;
my $primary = $class->primary_column;
my @essential = $class->_essential;
There are four 'reserved' groups. 'All', 'Essential', 'Primary' and 'TEMP'.
'予約された'グループがある。'All'、'Essential'、'Primary'そして 'TEMP'だ。
'All' are all columns used by the class. If not set it will be created from all the other groups.
'All'はクラスが使う全カラムである。これを設定しないと、他の全 グループから生成される。
'Primary' is the primary key columns for this class. It must be set before objects can be used.
'Primary'はこのクラスの主キーカラムである。オブジェクトが利用可能に なる前に、設定されなければならない。
If 'All' is given but not 'Primary' it will assume the first column in 'All' is the primary key.
'All'が指定されているが'Primary'が指定されていない場合、'ALL'の最初の カラムが主キーであると仮定される。
'Essential' are the minimal set of columns needed to load and use the object. Only the columns in this group will be loaded when an object is retrieve()'d. It is typically used to save memory on a class that has a lot of columns but where we mostly only use a few of them. It will automatically be set to 'All' if you don't set it yourself. The 'Primary' column is always part of your 'Essential' group and Class::DBI will put it there if you don't.
'Essential'は、オブジェクトをロードし利用するのに必要な最小限の カラムセットである。オブジェクトがretrieve()されるとき、このグループ内の カラムだけがロードされる。たくさんのカラムを持つが、そのうちのほんの少し だけを使うようなクラスでメモリを節約するというのが典型的な使い方だ。 このグループを指定しない場合、自動的に'All'の内容がセットされる。 'Primary'カラムは常に'Essential'グループの一部であり、あなたがセット しない場合、Class::DBIがそれを行なう。
For simplicity we provide primary_columns(), primary_column(), and _essential() methods which return these. The primary_column() method should only be used for tables that have a single primary key column.
簡略のため、これらの設定を返すprimary_columns()、primary_column()、 そして_essential()メソッドを用意している。primary_column()は、単一の 主キーカラムを持つテーブルに対してのみ使うべきである。
非永続フィールド¶
Music::CD->columns(TEMP => qw/nonpersistent/);
If you wish to have fields that act like columns in every other way, but that don't actually exist in the database (and thus will not persist), you can declare them as part of a column group of 'TEMP'.
いつでもカラムのように振舞うが、実際にはデータベース上に存在しない (それゆえ永続しない)フィールドが欲しいなら、'TEMP'というカラムグループ の一部として宣言することができる。
find_column¶
Class->find_column($column);
$obj->find_column($column);
The columns of a class are stored as Class::DBI::Column objects. This method will return you the object for the given column, if it exists. This is most useful either in a boolean context to discover if the column exists, or to 'normalize' a user-entered column name to an actual Column.
クラスのカラムは、Class::DBI::Columnオブジェクトとして保持されている。 このメソッドは、もし存在しているなら指定したカラムのオブジェクトを返す。 これは、そのカラムが存在しているかを調べるブールコンテキストか、あるいは ユーザーが入力したカラム名を実際のColumnへと'正規化'する場合のどちらかで 非常に役に立つ。
The interface of the Column object itself is still under development, so you shouldn't really rely on anything internal to it.
Columnオブジェクトのインターフェース自体はまだ開発途中である。 そのため、実際にはこのインターフェースに内在的に依存するべきではない。
トランザクション¶
Class::DBI suffers from the usual problems when dealing with transactions. In particular, you should be very wary when committing your changes that you may actually be in a wider scope than expected and that your caller may not be expecting you to commit.
Class::DBIはトランザクションを扱うときに生じる、よくある問題に苦しむ。 殊に、予想以上に広範囲のスコープにおいてあなたがなした変更をコミット する場合には、また、あなたがコミットすることを呼び出し側が予想して いない場合には細心の注意を払う必要がある。
However, as long as you are aware of this, and try to keep the scope of your transactions small, ideally always within the scope of a single method, you should be able to work with transactions with few problems.
しかしこのことに気づいている限り、また、トランザクションのスコープを 小さなものに、理念上は常に一つのメソッドのスコープ内に、維持しようと する限り、ほとんど問題なくトランザクションを使った仕事ができるはずだ。
dbi_commit / dbi_rollback¶
$obj->dbi_commit();
$obj->dbi_rollback();
We provide these thin aliases through to the DBI's commit() and rollback() commands to commit or rollback all changes to this object.
DBIのcommit()とrollback()コマンドへの貧弱なエイリアスを提供している。 これらは、このオブジェクトへの全変更をcommitあるいはrollbackするためにある。
局所化されたトランザクション (Localised Transactions)¶
A nice idiom for turning on a transaction locally (with AutoCommit turned on globally) (courtesy of Dominic Mitchell) is:
トランザクションを局所化(グローバルにAutoCommitを有効にする)する うまい慣用句(Dominic Mitchellに感謝)は:
sub do_transaction {
my $class = shift;
my ( $code ) = @_;
# このスコープに対してAutoCommitを無効にする。
# ローカルなAutoCommitがスコープを外れるとき、
# すなわち、このブロックを抜けると自動的にcommitされる。
local $class->db_Main->{ AutoCommit };
# トランザクション内で必要となるコードを実行。
eval { $code->() };
if ( $@ ) {
my $commit_error = $@;
eval { $class->dbi_rollback }; # これもdieするかもしれない!
die $commit_error;
}
}
And then you just call:
あとは呼び出すだけだ:
Music::DBI->do_transaction( sub {
my $artist = Music::Artist->create({ name => 'Pink Floyd' });
my $cd = $artist->add_to_cds({
title => 'Dark Side Of The Moon',
year => 1974,
});
});
Now either both will get added, or the entire transaction will be rolled back.
これで両方が付け加えられるか、さもなければトランザクションは完全に ロールバックする。
サブクラス化¶
The preferred method of interacting with Class::DBI is for you to write a subclass for your database connection, with each table-class inheriting in turn from it.
Class::DBIと相互作用する好ましいメソッドを使えば、データベース接続のための サブクラスを書ける。各テーブルクラスはそこから順番に継承する。
As well as encapsulating the connection information in one place, this also allows you to override default behaviour or add additional functionality across all of your classes.
一つの場所に接続情報をカプセル化するのと同様、これを使うことにより、 あなたのクラス全てを横断してデフォルトの振る舞いをオーバーライドしたり、 機能を追加することができる。
As the innards of Class::DBI are still in flux, you must exercise extreme caution in overriding private methods of Class::DBI (those starting with an underscore), unless they are explicitly mentioned in this documentation as being safe to override. If you find yourself needing to do this, then I would suggest that you ask on the mailing list about it, and we'll see if we can either come up with a better approach, or provide a new means to do whatever you need to do.
Class::DBIの内部構造はまだ流動的なので、Class::DBIのプライベートメソッド (アンダーバーで始まるメソッド)をオーバーライドする際は、極度の注意を 払わなければならない。このドキュメント内でオーバーライドしても安全であると 明示的に言及されていない限りは。もしオーバーライドの必要を感じたなら、 それに関してメーリングリストで尋ねて欲しい。よりよいアプローチを提案できるのか、 あるいは新しい手段を提供できるのかを我々は検討するだろう。
注意¶
複数カラムの外部キーはサポートしていない¶
主キーの値を変更したりインフレートしないこと¶
Altering your primary key column currently causes Bad Things to happen. I should really protect against this.
現状において、主キーカラムの変更は悪いことをもたらす。 私はそれを何とかしようと思う。
クックブック¶
I plan to include a 'Cookbook' of typical tricks and tips. Please send me your suggestions.
サポートしているデータベース¶
Theoretically Class::DBI should work with almost any standard RDBMS. Of course, in the real world, we know that that's not true. We know that it works with MySQL, PostgrSQL, Oracle and SQLite, each of which have their own additional subclass on CPAN that you should explore if you're using them.
理論的には、Class::DBIはほとんどの標準的なRDBMで動作するはずだ。 もちろん、現実にはそれが正しくないことを我々は知っている。 MySQL、PostgreSQL、OracleそしてSQLiteで動作することは知られており、 それぞれCPANに付加的なサブクラスが存在する。
L<Class::DBI::mysql>, L<Class::DBI::Pg>, L<Class::DBI::Oracle>,
L<Class::DBI::SQLite>
For the most part it's been reported to work with Sybase. Beyond that lies The Great Unknown(tm). If you have access to other databases, please give this a test run, and let me know the results.
大部分において、Sybaseでの動作レポートがなされている。それ以上については 偉大なる無名(The Great Unknown(tm))だ。もしあなたが他のデータベースに アクセスするのなら、このモジュールをテスト実行して頂きたい。そして 私に結果を知らせて欲しい。
This is known not to work with DBD::RAM. As a minimum it requires a database that supports table aliasing, and a DBI driver that supports placeholders.
このモジュールはDBD::RAMでは動作しないことが知られている。最低限、 テーブルエイリアスをサポートしているデータベースと、プレースホルダを サポートしているDBIドライバが必要である。
現在の作者¶
Tony Bowden <classdbi@tmtm.com>
名誉作者¶
Michael G Schwern <schwern@pobox.com>
謝辞¶
Tim Bunce, Tatsuhiko Miyagawa, Damian Conway, Uri Gutman, Mike Lambert and the POOP group.
サポート¶
Support for Class::DBI is via the mailing list. The list is used for general queries on the use of Class::DBI, bug reports, patches, and suggestions for improvements or new features.
Class::DBIのサポートはメーリングリストを通じてなされる。 そこではClass::DBIの利用についての一般的な問い合わせ、バグレポート、 そして新しい機能の改良の提案がされている。
To join the list visit http://groups.kasei.com/mail/info/cdbi-talk
The interface to Class::DBI is fairly stable, but there are still occassions when we need to break backwards compatability. Such issues will be raised on the list before release, so if you use Class::DBI in a production environment, it's probably a good idea to keep a watch on the list.
Class::DBIのインターフェースはうまく安定している。しかしまだ後方互換を 壊さなければならないときもある。そのような案件についてはリリース前に メーリングリストで提起するので、もしプロダクション環境でClass::DBIを 使う場合は、メーリングリストを眺め続けたほうがたぶん良いだろう。
ライセンス¶
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
参考¶
An article on Class::DBI was published on Perl.com recently. It's slightly out of date already, but it's a good introduction: http://www.perl.com/pub/a/2002/11/27/classdbi.html
最近Class::DBIの記事がPerl.comに載った。もういささか古くはなっているが、 優れた導入だ: http://www.perl.com/pub/a/2002/11/27/classdbi.html
http://poop.sourceforge.net/ provides a document comparing a variety of different approaches to database persistence, such as Class::DBI, Alazabo, Tangram, SPOPS etc.
http://poop.sourceforge.net/ はデータベースの永続に対する様々な 異なるアプローチ、Class::DBI、Alazabo、Tangram、SPOPS等々 の比較をしたドキュメントを提供している。
CPAN contains a variety of other modules that can be used with Class::DBI: Class::DBI::FromCGI, Class::DBI::AbstractSearch, Class::DBI::View, Class::DBI::Loader etc.
CPANにはClass:DBIと一緒に使う様々なモジュールがある: Class::DBI::FromCGI, Class::DBI::AbstractSearch, Class::DBI::View, Class::DBI::Loader 等々。
Class::DBI::SAK, the Swiss Army Knife for Class::DBI attempts to bring many of these together into one interface.
Class::DBI::SAK、これはClass::DBIにとってスイスアーミーナイフの ようなもので、これらを一つのインターフェースにまとめあげる試みである。
For a full list see: http://search.cpan.org/search?query=Class%3A%3ADBI&mode=module
完全なリストはここを参照: http://search.cpan.org/search?query=Class%3A%3ADBI&mode=module
Class::DBI is built on top of Ima::DBI, Class::Accessor and Class::Data::Inheritable.
Class::DBIはIma::DBI、Class::Accessorそして Class::Data::Inheritableの上に構築されている。