- Nekokak's core dump:Perl/DBICï¼ãã¥ã¼ããªã¢ã«
- 101号室:DBIx::Classのリレーションï¼ãã¼ãã«éã®é¢ä¿ãå³ã§èª¬æ
- PeroDoc和訳:DBIx::Class
- 今日のCPANモジュール:use DBIx::Class;
æ¬çªã®ã¢ããªã±ã¼ã·ã§ã³ãåããã®ã¯MySQLãPostgreSQLã ãã©ããã¹ãã¯SQLiteã§ããããã
ã¾ãã¯ãSQLiteã§ãã¹ããã§ããç°å¢ãDebian GNU/Linux Lennyä¸ã«ç¨æã
% sudo aptitude install libdbix-class-perl sqlite3 libdbd-sqlite3-perl
次ã«Nekokak's core dump:Perl/DBICã«ããããç·´ç¿ãã¦ã¿ãããã ããSQLiteã§ãPeroDoc和訳:DBIx::Class::Manual::Example - シンプルなCDデータベースの例ã«ãã£ã¬ã¯ããªãæ§æã
% mkdir -p app/db % cd app/db
ãã¼ã¿ãã¼ã¹ã®ã¹ãã¼ãã以ä¸ã®ããã«user.sqlã¨ãã¦ä½æã
create table user( id int(10) NOT NULL autoincrement, name varchar(256) NOT NULL, PRIMARY KEY (id) );
ãããå ã«ãã¼ã¿ãã¼ã¹ä½æã
% sqlite3 example.db < user.sql SQL error near line 1: near "autoincrement": syntax error
ãã£ããæ«æãGoogleã§ãsqlite autoincrementãã§æ¤ç´¢ããçµæè¦ã¤ãããã¼ã¸ã«ããã¨ãSQLiteã§ã¯INTEGER PRIMARY KEYã¨æå®ããã¨ãã®åãNULLã§INSERTããã¨ããã®åä¸ã®æå¤§æ°ï¼1ãå ¥åãããINTEGER PRIMARY KEY AUTOINCREMENTã¨ããã¨ããã®åãNULLã§INSERTããã¨ããã¼ãã«ã®ãã®åã«ããã¦ã¦ãã¼ã¯ãªæ°åãæ¿å ¥ãããããã出典ï¼ãSQLiteã¨MySQLã ã¨SQLã®æ¸ãæ¹ãããã¦éãã®ãã
user.sqlã以ä¸ã®ããã«å¤æ´ã
create table user( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL );
ãããå ã«ãã¼ã¿ãã¼ã¹ä½æã
% sqlite3 example.db < user.sql
ãã¨ã¯ãNekokak's core dump:Perl/DBICã«ããããç·´ç¿ãã¦ã¿ãã
% cd .. % mkdir -p Neko/Schema
Neko/Schema.pmã使ããã
package Neko::Schema; use strict; use warnings; use base 'DBIx::Class::Schema'; __PACKAGE__->load_classes(qw/User/); 1;
次ã«Neko/Schema/User.pmã使ããï¼SQLiteãªã®ã§PK::AutoãMySQLã ã¨PK::Auto::MySQLãããï¼ã
package Neko::Schema::User; use strict; use warnings; use base 'DBIx::Class'; __PACKAGE__->load_components(qw/ PK::Auto Core/); __PACKAGE__->table('user'); __PACKAGE__->add_columns(qw/id name/); __PACKAGE__->set_primary_key('id'); 1;
次ã«app/test.plãç¨æããinsert, select, update, deleteã試ã
#! /usr/bin/perl use strict; use warnings; use Neko::Schema; my $schema = Neko::Schema->connect('dbi:SQLite:db/example.db'); #my $schema = Neko::Schema->connect('dbi:mysql:nekodb','nekokak','******'); # insert $schema->resultset('User')->create({id => 1, name => 'nekokak'}); # select my $user = $schema->resultset('User')->find(1); print $user->id,"\n"; print $user->name,"\n"; # update $user->name('nomaneko'); $user->update; # select $user = $schema->resultset('User')->find(1); print $user->id,"\n"; print $user->name,"\n"; # delete $user->delete;
èªã¿é²ãã¦ã1対å¤ã®é¢ä¿ã®é¨åãã¾ãã¯ããã¼ãã«ã追å ãããapp/db/bookmark.sqlã以ä¸ã®å 容ã§ä½æããã
create table bookmark ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL REFERENCES user(id), url TEXT NOT NULL );
ãããå ã«ãã¼ãã«è¿½å ã
% sqlite3 db/example.db < db/bookmark.sql
app/Neko/Schema/Bookmark.pmã以ä¸ã®ããã«ä½æã
package Neko::Schema::Bookmark; use strict; use warnings; use base 'DBIx::Class'; __PACKAGE__->load_components(qw/ PK::Auto Core/); __PACKAGE__->table('bookmark'); __PACKAGE__->add_columns(qw/id user_id url/); __PACKAGE__->set_primary_key('id'); __PACKAGE__->belongs_to(user_id => 'Neko::Schema::User'); 1;
app/Neko/Schema/User.pmã以ä¸ã®ããã«å¤æ´ã
package Neko::Schema::User; use strict; use warnings; use base 'DBIx::Class'; __PACKAGE__->load_components(qw/ PK::Auto Core/); __PACKAGE__->table('user'); __PACKAGE__->add_columns(qw/id name/); __PACKAGE__->set_primary_key('id'); __PACKAGE__->has_many(bookmark => 'Neko::Schema::Bookmark', 'user_id'); 1;
app/Neko/Schema.pmã以ä¸ã®ããã«å¤æ´ã
package Neko::Schema; use strict; use warnings; use base 'DBIx::Class::Schema'; __PACKAGE__->load_classes(qw/User Bookmark/); 1;
ãªã¬ã¼ã·ã§ã³ã試ãã¦ã¿ãapp/test2.plã以ä¸ã®ããã«ä½æ
#! /usr/bin/perl use strict; use warnings; use Neko::Schema; my $schema = Neko::Schema->connect('dbi:SQLite:db/example.db'); # insert $schema->resultset('User')->create({id => 1, name => 'nekokak'}); $schema->resultset('User')->create({id => 2, name => 'nomaneko'}); # select my $userit = $schema->resultset('User'); while(my $user = $userit->next){ print $user->id,',',$user->name,"\n"; } # insert $schema->resultset('Bookmark')->create({id => 1, user_id => 1, url => 'http://hogehoge.jp'}); $schema->resultset('Bookmark')->create({id => 2, user_id => 1, url => 'http://hugahuga.jp'}); $schema->resultset('Bookmark')->create({id => 3, user_id => 2, url => 'http://kurukuru.jp'}); $schema->resultset('Bookmark')->create({id => 4, user_id => 2, url => 'http://borabora.jp'}); # select my $bookmarkit = $schema->resultset('Bookmark'); while(my $bookmark = $bookmarkit->next){ print $bookmark->id,",",$bookmark->user_id,",",$bookmark->url,"\n"; } $userit = $schema->resultset('User')->search({name => 'nekokak'}); while ( my $user = $userit->next ) { my $bkit = $user->bookmark; while ( my $bookmark = $bkit->next ) { print $bookmark->id,':',$user->id,':',$bookmark->url,"\n"; } } my $bkit = $schema->resultset('Bookmark')->search(); while ( my $bookmark = $bkit->next ) { my $user = $bookmark->user_id; print $user->id,':',$bookmark->id,':',$user->name,':',$bookmark->url,"\n"; } #delete $userit = $schema->resultset('User'); while(my $user = $userit->next){ $user->delete; } $bookmarkit = $schema->resultset('Bookmark'); while(my $bookmark = $bookmarkit->next){ $bookmark->delete; } exit;
inflateã¨deflateãä½ã®ãã¨ããããããªãã£ãã®ã§Googleæ§ã«ã伺ããWalrus, Digit.:Perlメモ/DBIx::Classモジュール: データベース入出時にフィールド値を変換する(inflate、deflate)ã«ããã¨INSERTãUPDATEãããã¨ãã®èªåè¨é²ã«ä¾¿å©ãããªæ©è½ã§ããã¨ãããã¨ãããã£ãã
DateTime::Format::SQLiteãªãã¦ç¡ããããªã®ã§ãDateTime::Format::MySQLã使ãã
- åèï¼発声練習:Perlにおける各種日付フォーマットの変換と比較
- åèï¼hide-k.net#blog: DBICでdatetime型カラムの検索条件ではまった件
- åèï¼つゆだくのSQLite3:SQLiteのデータ型
app/db/login.sqlã以ä¸ã®ããã«ç¨æããã
create table login ( id INTEGER PRIMARY KEY REFERENCES user(id), login_time DATETIME );
app/Neko/Schema/Login.pmã以ä¸ã®ããã«ç¨æããã
package Neko::Schema::Login; use strict; use warnings; use base 'DBIx::Class'; use DateTime::Format::MySQL; __PACKAGE__->load_components(qw/PK::Auto Core/); __PACKAGE__->table('login'); __PACKAGE__->add_columns(qw/id login_time/); __PACKAGE__->set_primary_key('id'); __PACKAGE__->might_have(id => 'Neko::Schema::User'); __PACKAGE__->inflate_column('login_time', { inflate => sub { DateTime::Format::MySQL->parse_datetime(shift); }, deflate => sub { DateTime::Format::MySQL->format_datetime(shift); }, });
app/Neko/Schema/User.pmã以ä¸ã®ããã«å¤æ´ã
package Neko::Schema::User; use strict; use warnings; use base 'DBIx::Class'; __PACKAGE__->load_components(qw/ PK::Auto Core/); __PACKAGE__->table('user'); __PACKAGE__->add_columns(qw/id name/); __PACKAGE__->set_primary_key('id'); __PACKAGE__->has_many(bookmark => 'Neko::Schema::Bookmark', 'user_id'); __PACKAGE__->might_have(id => 'Neko::Schema::Login'); 1;
app/Neko/Schema.pmã以ä¸ã®ããã«å¤æ´
package Neko::Schema; use strict; use warnings; use base 'DBIx::Class::Schema'; __PACKAGE__->load_classes(qw/User Bookmark Login/); 1;
inflateã¨deflateã試ãã¹ã¯ãªãããapp/test3.plã¨ãã¦ä»¥ä¸ã®ããã«æ¸ãã
#! /usr/bin/perl use strict; use warnings; use Neko::Schema; my $schema = Neko::Schema->connect('dbi:SQLite:db/example.db'); $schema->storage->debug(1); $schema->storage->debugfh(IO::File->new('/tmp/trace.out', 'a')); my $i = $schema->resultset('User')->create({name => 'nekokak'}); $schema->resultset('Login')->create({id => $i->last_insert_id, login_time => '2006-02-03'}); my $it = $schema->resultset('Login')->search(); while ( my $login = $it->next ) { my $u = $login->user_id; print $login->id,':',$u->name,':',$login->login_time,"\n"; } exit;
ããã§å®è¡ããã¨ã©ãããã¾ããããªãã
% perl test3.pl Can't locate object method "last_insert_id" via package "Neko::Schema::User" at test3.pl line 10.
æ¤ç´¢ãã¦ãåå 䏿ãã¨ããããããã¾ã§ã
SQLæã¯MySQLã¨SQLiteã§å ±æã§ããªãããã©ããã½ã¼ã¹ã³ã¼ãã¯connecté¨åãé¤ãå ±æã§ãããã