Showing 5 changed files with 357 additions and 1 deletions
+1 -1
Changes
... ...
@@ -1,5 +1,5 @@
1 1
 0.1648
2
-  add experimental each_table() method
2
+  add experimental update_at(), delete_at(), select_at()
3 3
   add experimental setup_model()
4 4
   add experimental DBIx::Custom::Model columns attirbute
5 5
   add experimental DBIx::Custom::Model foreign_key() attribute 
+164
lib/DBIx/Custom.pm
... ...
@@ -291,6 +291,45 @@ sub delete {
291 291
 
292 292
 sub delete_all { shift->delete(allow_delete_all => 1, @_) }
293 293
 
294
+our %VALID_DELETE_AT_ARGS
295
+  = map { $_ => 1 } qw/table where append filter query
296
+                       primary_key param/;
297
+
298
+sub delete_at {
299
+    my ($self, %args) = @_;
300
+    
301
+    # Check arguments
302
+    foreach my $name (keys %args) {
303
+        croak qq{"$name" is invalid argument}
304
+          unless $VALID_DELETE_AT_ARGS{$name};
305
+    }
306
+    
307
+    # Primary key
308
+    my $primary_keys = delete $args{primary_key};
309
+    $primary_keys = [$primary_keys] unless ref $primary_keys;
310
+    
311
+    # Where clause
312
+    my $where = {};
313
+    if (exists $args{where}) {
314
+        my $where_columns = delete $args{where};
315
+        $where_columns = [$where_columns] unless ref $where_columns;
316
+        
317
+        for(my $i = 0; $i < @$primary_keys; $i ++) {
318
+           $where->{$primary_keys->[$i]} = $where_columns->[$i];
319
+        }
320
+    }
321
+    elsif (exists $args{param}) {
322
+        my $param = delete $args{param};
323
+        
324
+        for(my $i = 0; $i < @$primary_keys; $i ++) {
325
+           $where->{$primary_keys->[$i]}
326
+             = delete $param->{$primary_keys->[$i]};
327
+        }
328
+    }
329
+    
330
+    return $self->delete(where => $where, %args);
331
+}
332
+
294 333
 sub DESTROY { }
295 334
 
296 335
 our %VALID_EXECUTE_ARGS = map { $_ => 1 } qw/param filter table/;
... ...
@@ -594,6 +633,44 @@ sub select {
594 633
     return $result;
595 634
 }
596 635
 
636
+our %VALID_SELECT_AT_ARGS
637
+  = map { $_ => 1 } qw/table column where append relation filter query selection
638
+                       param primary_key/;
639
+
640
+sub select_at {
641
+    my ($self, %args) = @_;
642
+    
643
+    # Check arguments
644
+    foreach my $name (keys %args) {
645
+        croak qq{"$name" is invalid argument}
646
+          unless $VALID_SELECT_AT_ARGS{$name};
647
+    }
648
+    
649
+    # Primary key
650
+    my $primary_keys = delete $args{primary_key};
651
+    $primary_keys = [$primary_keys] unless ref $primary_keys;
652
+    
653
+    # Where clause
654
+    my $where = {};
655
+    if (exists $args{where}) {
656
+        my $where_columns = delete $args{where};
657
+        $where_columns = [$where_columns] unless ref $where_columns;
658
+        
659
+        for(my $i = 0; $i < @$primary_keys; $i ++) {
660
+           $where->{$primary_keys->[$i]} = $where_columns->[$i];
661
+        }
662
+    }
663
+    elsif (exists $args{param}) {
664
+        my $param = delete $args{param};
665
+        for(my $i = 0; $i < @$primary_keys; $i ++) {
666
+           $where->{$primary_keys->[$i]}
667
+             = delete $param->{$primary_keys->[$i]};
668
+        }
669
+    }
670
+    
671
+    return $self->select(where => $where, %args);
672
+}
673
+
597 674
 sub model {
598 675
     my ($self, $name, $model) = @_;
599 676
     
... ...
@@ -778,6 +855,47 @@ sub update {
778 855
 
779 856
 sub update_all { shift->update(allow_update_all => 1, @_) };
780 857
 
858
+our %VALID_UPDATE_AT_ARGS
859
+  = map { $_ => 1 } qw/table param
860
+                       where append filter query
861
+                       primary_key param/;
862
+
863
+sub update_at {
864
+    my ($self, %args) = @_;
865
+    
866
+    # Check arguments
867
+    foreach my $name (keys %args) {
868
+        croak qq{"$name" is invalid argument}
869
+          unless $VALID_UPDATE_AT_ARGS{$name};
870
+    }
871
+    
872
+    # Primary key
873
+    my $primary_keys = delete $args{primary_key};
874
+    $primary_keys = [$primary_keys] unless ref $primary_keys;
875
+    
876
+    # Where clause
877
+    my $where = {};
878
+    my $param = {};
879
+    
880
+    if (exists $args{where}) {
881
+        my $where_columns = delete $args{where};
882
+        $where_columns = [$where_columns] unless ref $where_columns;
883
+        
884
+        for(my $i = 0; $i < @$primary_keys; $i ++) {
885
+           $where->{$primary_keys->[$i]} = $where_columns->[$i];
886
+        }
887
+    }
888
+    elsif (exists $args{param}) {
889
+        $param = delete $args{param};
890
+        for(my $i = 0; $i < @$primary_keys; $i ++) {
891
+           $where->{$primary_keys->[$i]}
892
+             = delete $param->{$primary_keys->[$i]};
893
+        }
894
+    }
895
+    
896
+    return $self->update(where => $where, param => $param, %args);
897
+}
898
+
781 899
 sub where {
782 900
     my $self = shift;
783 901
 
... ...
@@ -1212,6 +1330,27 @@ Arguments is same as C<delete> method,
1212 1330
 except that C<delete_all> don't have C<where> argument.
1213 1331
 Return value of C<delete_all()> is the count of affected rows.
1214 1332
 
1333
+=head3 C<delete_at()>
1334
+
1335
+To delete row by using primary key, use C<delete_at()>
1336
+
1337
+    $dbi->delete_at(
1338
+        table => 'book',
1339
+        primary_key => ['id'],
1340
+        where => ['123']
1341
+    );
1342
+
1343
+In this example, row which id column is 123 is deleted.
1344
+NOTE that you must pass array reference as C<where>.
1345
+
1346
+You can also write arguments like this.
1347
+
1348
+    $dbi->delete_at(
1349
+        table => 'book',
1350
+        primary_key => ['id'],
1351
+        param => {id => '123'}
1352
+    );
1353
+
1215 1354
 =head2 C<insert>
1216 1355
 
1217 1356
     $dbi->insert(table  => $table, 
... ...
@@ -1401,6 +1540,15 @@ First element is a string. it contains tags,
1401 1540
 such as "{= title} or {like author}".
1402 1541
 Second element is paramters.
1403 1542
 
1543
+=head3 C<select_at()>
1544
+
1545
+To select row by using primary key, use C<select_at()>.
1546
+
1547
+    $dbi->select_at(table => 'book', primary_key => ['id'], where => ['123']);
1548
+
1549
+In this example, row which id colunm is 123 is selected.
1550
+NOTE that you must pass array reference as C<where>.
1551
+
1404 1552
 =head2 C<update>
1405 1553
 
1406 1554
     $dbi->update(table  => $table, 
... ...
@@ -1453,6 +1601,22 @@ Arguments is same as C<update> method,
1453 1601
 except that C<update_all> don't have C<where> argument.
1454 1602
 Return value of C<update_all()> is the count of affected rows.
1455 1603
 
1604
+=head3 C<update_at()>
1605
+
1606
+To update row by using primary key, use C<update_at()>
1607
+
1608
+    $dbi->update_at(
1609
+        table => 'book',
1610
+        primary_key => ['id'],
1611
+        where => ['123'],
1612
+        param => {name => 'Ken'}
1613
+    );
1614
+
1615
+In this example, row which id column is 123 is updated.
1616
+NOTE that you must pass array reference as C<where>.
1617
+If C<param> contains primary key,
1618
+the key and value is delete from C<param>.
1619
+
1456 1620
 =head2 C<(experimental) where>
1457 1621
 
1458 1622
     my $where = $dbi->where;
+43
lib/DBIx/Custom/Guide.pod
... ...
@@ -380,6 +380,45 @@ You don't have to wirte last semicolon in C<execute()>.
380 380
 
381 381
     $dbi->execute('select * from book');
382 382
 
383
+=head3 Update by using primary key : C<update_at()>
384
+
385
+To update row by using primary key, use C<update_at()>
386
+
387
+    $dbi->update_at(
388
+        table => 'book', primary_key => ['id'],
389
+        where => ['123'], param => {name => 'Ken'}
390
+    );
391
+
392
+In this example, row which id column is 123 is updated.
393
+NOTE that you must pass array reference as C<where>.
394
+If C<param> contains primary key, the key and value is delete from C<param>.
395
+
396
+=head3 Delete by using primary key : C<delete_at()>
397
+
398
+To delete row by using primary key, use C<delete_at()>
399
+
400
+    $dbi->delete_at(table => 'book', primary_key => ['id'], where => ['123']);
401
+
402
+In this example, row which id column is 123 is deleted.
403
+NOTE that you must pass array reference as C<where>.
404
+
405
+You can also write arguments like this.
406
+
407
+    $dbi->delete_at(table => 'book', primary_key => ['id'], param => {id => '123'});
408
+
409
+=head3 Select by using primary key : C<select_at()>
410
+
411
+To select row by using primary key, use C<select_at()>.
412
+
413
+    $dbi->select_at(table => 'book', primary_key => ['id'], where => ['123']);
414
+
415
+In this example, row which id colunm is 123 is selected.
416
+NOTE that you must pass array reference as C<where>.
417
+
418
+You can also write arguments like this.
419
+
420
+    $dbi->select_at(table => 'book', primary_key => ['id'], param => {id => '123'});
421
+
383 422
 =head2 3. Fetch row
384 423
 
385 424
 Return value of C<select()> is L<DBIx::Custom::Result> object.
... ...
@@ -1073,11 +1112,15 @@ Model examples
1073 1112
     package MyModel::book;
1074 1113
     use base 'DBIx::Custom::Model';
1075 1114
     
1115
+    __PACKAGE__->attr('primary_key' => sub { ['id'] };
1116
+    
1076 1117
     sub insert { ... }
1077 1118
     sub list { ... }
1078 1119
     
1079 1120
     package MyModel::company;
1080 1121
     use base 'DBIx::Custom::Model';
1122
+
1123
+    __PACKAGE__->attr('primary_key' => sub { ['id'] };
1081 1124
     
1082 1125
     sub insert { ... }
1083 1126
     sub list { ... }
+43
lib/DBIx/Custom/Guide/Ja.pod
... ...
@@ -386,6 +386,45 @@ SQLを実行するにはC<execute()>を使用します。
386 386
 
387 387
     $dbi->execute('select * from book');
388 388
 
389
+=head3 プライマリーキーを利用した行の更新 C<update_at()>
390
+
391
+プライマリーを使用して行を更新するにはC<update_at()>を使用します。
392
+
393
+    $dbi->update_at(
394
+        table => 'book', primary_key => ['id'],
395
+        where => ['123'], param => {name => 'Ken'}
396
+    );
397
+
398
+この例ではidの列が123の行が更新されます。C<where>には、配列の
399
+リファレンスを渡す必要があることに注意してください。
400
+なおC<param>にプライマリーキーが含まれていた場合は、そのキーが削除さされます。
401
+
402
+=head3 プライマリーキーを利用した行の削除 C<delete_at()>
403
+
404
+プライマリーを使用して行を削除するにはC<delete_at()>を使用します。
405
+
406
+    $dbi->delete_at(table => 'book', primary_key => ['id'], where => ['123']);
407
+
408
+この例ではidの列が123の行が削除されます。C<where>には、配列の
409
+リファレンスを渡す必要があることに注意してください。
410
+
411
+また下のような記述方法も許されています。
412
+
413
+    $dbi->delete_at(table => 'book', primary_key => ['id'], param => {id => '123'});
414
+
415
+=head3 プライマリーキーを利用した行の選択 C<select_at()>
416
+
417
+プライマリーを使用して行を選択するにはC<select_at()>を使用します。
418
+
419
+    $dbi->select_at(table => 'book', primary_key => ['id'], where => ['123']);
420
+
421
+この例ではidの列が123の行が選択されます。C<where>には、配列の
422
+リファレンスを渡す必要があることに注意してください。
423
+
424
+また下のような記述方法も許されています。
425
+
426
+    $dbi->select_at(table => 'book', primary_key => ['id'], param => {id => '123'});
427
+
389 428
 =head2 3. 行のフェッチ
390 429
 
391 430
 C<select()>メソッドの戻り値はL<DBIx::Custom::Result>オブジェクトです。
... ...
@@ -1101,11 +1140,15 @@ C<select_at()>で利用されます。
1101 1140
     package MyModel::book;
1102 1141
     use base 'DBIx::Custom::Model';
1103 1142
     
1143
+    __PACKAGE__->attr('primary_key' => sub { ['id'] };
1144
+    
1104 1145
     sub insert { ... }
1105 1146
     sub list { ... }
1106 1147
     
1107 1148
     package MyModel::company;
1108 1149
     use base 'DBIx::Custom::Model';
1150
+
1151
+    __PACKAGE__->attr('primary_key' => sub { ['id'] };
1109 1152
     
1110 1153
     sub insert { ... }
1111 1154
     sub list { ... }
+106
t/dbix-custom-core-sqlite.t
... ...
@@ -1394,3 +1394,109 @@ $dbi->execute('create table test (id, name, primary key (id, name));');
1394 1394
 $dbi->setup_model;
1395 1395
 is_deeply($dbi->model('book')->columns, ['id']);
1396 1396
 is_deeply($dbi->model('company')->columns, ['id', 'name']);
1397
+
1398
+test 'delete_at';
1399
+$dbi = DBIx::Custom->connect($NEW_ARGS->{0});
1400
+$dbi->execute($CREATE_TABLE->{1});
1401
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2, key3 => 3});
1402
+$dbi->delete_at(
1403
+    table => 'table1',
1404
+    primary_key => ['key1', 'key2'],
1405
+    where => [1, 2],
1406
+);
1407
+is_deeply($dbi->select(table => 'table1')->fetch_hash_all, []);
1408
+
1409
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2, key3 => 3});
1410
+$dbi->delete_at(
1411
+    table => 'table1',
1412
+    primary_key => 'key1',
1413
+    where => 1,
1414
+);
1415
+is_deeply($dbi->select(table => 'table1')->fetch_hash_all, []);
1416
+
1417
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2, key3 => 3});
1418
+$dbi->delete_at(
1419
+    table => 'table1',
1420
+    primary_key => ['key1', 'key2'],
1421
+    param => {key1 => 1, key2 => 2},
1422
+);
1423
+is_deeply($dbi->select(table => 'table1')->fetch_hash_all, []);
1424
+
1425
+
1426
+test 'update_at';
1427
+$dbi = DBIx::Custom->connect($NEW_ARGS->{0});
1428
+$dbi->execute($CREATE_TABLE->{1});
1429
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2, key3 => 3});
1430
+$dbi->update_at(
1431
+    table => 'table1',
1432
+    primary_key => ['key1', 'key2'],
1433
+    where => [1, 2],
1434
+    param => {key3 => 4}
1435
+);
1436
+is($dbi->select(table => 'table1')->fetch_hash_first->{key1}, 1);
1437
+is($dbi->select(table => 'table1')->fetch_hash_first->{key2}, 2);
1438
+is($dbi->select(table => 'table1')->fetch_hash_first->{key3}, 4);
1439
+
1440
+$dbi->delete_all(table => 'table1');
1441
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2, key3 => 3});
1442
+$dbi->update_at(
1443
+    table => 'table1',
1444
+    primary_key => 'key1',
1445
+    where => 1,
1446
+    param => {key3 => 4}
1447
+);
1448
+is($dbi->select(table => 'table1')->fetch_hash_first->{key1}, 1);
1449
+is($dbi->select(table => 'table1')->fetch_hash_first->{key2}, 2);
1450
+is($dbi->select(table => 'table1')->fetch_hash_first->{key3}, 4);
1451
+
1452
+$dbi->delete_all(table => 'table1');
1453
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2, key3 => 3});
1454
+$dbi->update_at(
1455
+    table => 'table1',
1456
+    primary_key => ['key1', 'key2'],
1457
+    param => {key1 => 1, key2 => 2, key3 => 4},
1458
+);
1459
+is($dbi->select(table => 'table1')->fetch_hash_first->{key1}, 1);
1460
+is($dbi->select(table => 'table1')->fetch_hash_first->{key2}, 2);
1461
+is($dbi->select(table => 'table1')->fetch_hash_first->{key3}, 4);
1462
+
1463
+
1464
+test 'select_at';
1465
+$dbi = DBIx::Custom->connect($NEW_ARGS->{0});
1466
+$dbi->execute($CREATE_TABLE->{1});
1467
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2, key3 => 3});
1468
+$result = $dbi->select_at(
1469
+    table => 'table1',
1470
+    primary_key => ['key1', 'key2'],
1471
+    where => [1, 2]
1472
+);
1473
+$row = $result->fetch_hash_first;
1474
+is($row->{key1}, 1);
1475
+is($row->{key2}, 2);
1476
+is($row->{key3}, 3);
1477
+
1478
+$dbi->delete_all(table => 'table1');
1479
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2, key3 => 3});
1480
+$result = $dbi->select_at(
1481
+    table => 'table1',
1482
+    primary_key => 'key1',
1483
+    where => 1,
1484
+);
1485
+$row = $result->fetch_hash_first;
1486
+is($row->{key1}, 1);
1487
+is($row->{key2}, 2);
1488
+is($row->{key3}, 3);
1489
+
1490
+$dbi->delete_all(table => 'table1');
1491
+$dbi->insert(table => 'table1', param => {key1 => 1, key2 => 2, key3 => 3});
1492
+$result = $dbi->select_at(
1493
+    table => 'table1',
1494
+    primary_key => ['key1', 'key2'],
1495
+    param => {key1 => 1, key2 => 2},
1496
+);
1497
+$row = $result->fetch_hash_first;
1498
+is($row->{key1}, 1);
1499
+is($row->{key2}, 2);
1500
+is($row->{key3}, 3);
1501
+
1502
+