5e4ed9f 13 years ago
1 contributor
280 lines | 6.184kb
  1. package DBIx::Custom::Model;
  2. use Object::Simple -base;
  3.  
  4. use Carp 'croak';
  5. use DBIx::Custom::Util '_subname';
  6.  
  7. # Carp trust relationship
  8. push @DBIx::Custom::CARP_NOT, __PACKAGE__;
  9.  
  10. has [qw/dbi table/],
  11. bind_type => sub { [] },
  12. columns => sub { [] },
  13. join => sub { [] },
  14. primary_key => sub { [] };
  15.  
  16. our $AUTOLOAD;
  17.  
  18. sub AUTOLOAD {
  19. my $self = shift;
  20.  
  21. # Method name
  22. my ($package, $mname) = $AUTOLOAD =~ /^([\w\:]+)\:\:(\w+)$/;
  23.  
  24. # Method
  25. $self->{_methods} ||= {};
  26. if (my $method = $self->{_methods}->{$mname}) {
  27. return $self->$method(@_)
  28. }
  29. elsif (my $dbi_method = $self->dbi->can($mname)) {
  30. $self->dbi->$dbi_method(@_);
  31. }
  32. elsif ($self->{dbh} && (my $dbh_method = $self->dbh->can($mname))) {
  33. $self->dbi->dbh->$dbh_method(@_);
  34. }
  35. else {
  36. croak qq{Can't locate object method "$mname" via "$package" }
  37. . _subname;
  38. }
  39. }
  40.  
  41. my @methods = qw/insert insert_at update update_at update_all
  42. delete delete_at delete_all select select_at count/;
  43. foreach my $method (@methods) {
  44.  
  45. my $code = sub {
  46. my $self = shift;
  47. $self->dbi->$method(
  48. @_ % 2 ? shift : (),
  49. table => $self->table,
  50. bind_type => $self->bind_type,
  51. primary_key => $self->primary_key,
  52. type => $self->type,
  53. $method =~ /^select/ ? (join => $self->join) : (),
  54. @_
  55. )
  56. };
  57. no strict 'refs';
  58. my $class = __PACKAGE__;
  59. *{"${class}::$method"} = $code;
  60. }
  61.  
  62. sub execute {
  63. my $self = shift;
  64. return $self->dbi->execute(
  65. shift,
  66. shift,
  67. table => $self->table,
  68. bind_type => $self->bind_type,
  69. primary_key => $self->primary_key,
  70. type => $self->type,
  71. @_
  72. );
  73. }
  74.  
  75. sub DESTROY { }
  76.  
  77. sub helper {
  78. my $self = shift;
  79. # Merge
  80. my $methods = ref $_[0] eq 'HASH' ? $_[0] : {@_};
  81. $self->{_methods} = {%{$self->{_methods} || {}}, %$methods};
  82. return $self;
  83. }
  84.  
  85. sub mycolumn {
  86. my $self = shift;
  87. my $table = shift unless ref $_[0];
  88. my $columns = shift;
  89. $table ||= $self->table || '';
  90. $columns ||= $self->columns;
  91. return $self->dbi->mycolumn($table, $columns);
  92. }
  93.  
  94. sub new {
  95. my $self = shift->SUPER::new(@_);
  96. # Check attribute names
  97. my @attrs = keys %$self;
  98. foreach my $attr (@attrs) {
  99. croak qq{"$attr" is invalid attribute name } . _subname
  100. unless $self->can($attr);
  101. }
  102. return $self;
  103. }
  104.  
  105. # DEPRECATED!
  106. has 'filter';
  107. has 'name';
  108. has type => sub { [] };
  109.  
  110.  
  111. # DEPRECATED!
  112. sub method {
  113. warn "method method is DEPRECATED! use helper instead";
  114. return shift->helper(@_);
  115. }
  116.  
  117. 1;
  118.  
  119. =head1 NAME
  120.  
  121. DBIx::Custom::Model - Model
  122.  
  123. =head1 SYNOPSIS
  124.  
  125. use DBIx::Custom::Model;
  126.  
  127. my $model = DBIx::Custom::Model->new(table => 'books');
  128.  
  129. =head1 ATTRIBUTES
  130.  
  131. =head2 C<dbi>
  132.  
  133. my $dbi = $model->dbi;
  134. $model = $model->dbi($dbi);
  135.  
  136. L<DBIx::Custom> object.
  137.  
  138. =head2 C<join>
  139.  
  140. my $join = $model->join;
  141. $model = $model->join(
  142. ['left outer join company on book.company_id = company.id']
  143. );
  144. Join clause, this value is passed to C<select> method.
  145.  
  146. =head2 C<primary_key>
  147.  
  148. my $primary_key = $model->primary_key;
  149. $model = $model->primary_key(['id', 'number']);
  150.  
  151. Primary key,this is passed to C<insert>, C<update>,
  152. C<delete>, and C<select> method.
  153.  
  154. =head2 C<table>
  155.  
  156. my $model = $model->table;
  157. $model = $model->table('book');
  158.  
  159. Table name, this is passed to C<select> method.
  160.  
  161. =head2 C<bind_type>
  162.  
  163. my $type = $model->bind_type;
  164. $model = $model->bind_type(['image' => DBI::SQL_BLOB]);
  165. Database data type, this is used as type optioon of C<insert>,
  166. C<update>, C<update_all>, C<delete>, C<delete_all>,
  167. C<select>, and C<execute> method
  168.  
  169. =head1 METHODS
  170.  
  171. L<DBIx::Custom::Model> inherits all methods from L<Object::Simple>,
  172. and you can use all methods of L<DBIx::Custom> and L<DBI>
  173. and implements the following new ones.
  174.  
  175. =head2 C<count>
  176.  
  177. my $count = $model->count;
  178.  
  179. Get rows count.
  180.  
  181. Options is same as C<select> method's ones.
  182.  
  183. =head2 C<delete>
  184.  
  185. $model->delete(...);
  186. Same as C<delete> of L<DBIx::Custom> except that
  187. you don't have to specify C<table> and C<primary_key> option.
  188.  
  189. =head2 C<delete_all>
  190.  
  191. $model->delete_all(...);
  192. Same as C<delete_all> of L<DBIx::Custom> except that
  193. you don't have to specify C<table> and C<primary_key> option.
  194.  
  195. =head2 C<execute>
  196.  
  197. $model->execute(...);
  198.  
  199. Same as C<execute> of L<DBIx::Custom> except that
  200. you don't have to specify C<table> and C<primary_key> option.
  201.  
  202. =head2 C<insert>
  203.  
  204. $model->insert(...);
  205. Same as C<insert> of L<DBIx::Custom> except that
  206. you don't have to specify C<table> and C<primary_key> option.
  207.  
  208. =head2 C<helper>
  209.  
  210. $model->helper(
  211. update_or_insert => sub {
  212. my $self = shift;
  213. # ...
  214. },
  215. find_or_create => sub {
  216. my $self = shift;
  217. # ...
  218. );
  219.  
  220. Register helper. These helper is called directly from L<DBIx::Custom::Model> object.
  221.  
  222. $model->update_or_insert;
  223. $model->find_or_create;
  224.  
  225. =head2 C<mycolumn>
  226.  
  227. my $column = $self->mycolumn;
  228. my $column = $self->mycolumn(book => ['author', 'title']);
  229. my $column = $self->mycolumn(['author', 'title']);
  230.  
  231. Create column clause for myself. The follwoing column clause is created.
  232.  
  233. book.author as author,
  234. book.title as title
  235.  
  236. If table name is ommited, C<table> attribute of the model is used.
  237. If column names is omitted, C<columns> attribute of the model is used.
  238.  
  239. =head2 C<new>
  240.  
  241. my $model = DBIx::Custom::Model->new;
  242.  
  243. Create a L<DBIx::Custom::Model> object.
  244.  
  245. =head2 C<select>
  246.  
  247. $model->select(...);
  248. Same as C<select> of L<DBIx::Custom> except that
  249. you don't have to specify C<table>, C<primary_key> and C<jon> option.
  250.  
  251. =head2 C<update>
  252.  
  253. $model->update(...);
  254. Same as C<update> of L<DBIx::Custom> except that
  255. you don't have to specify C<table> and C<primary_key> option.
  256.  
  257. =head2 C<update_all>
  258.  
  259. $model->update_all(param => \%param);
  260. Same as C<update_all> of L<DBIx::Custom> except that
  261. you don't have to specify C<table> and C<primary_key> option.
  262.  
  263. =cut