Newer Older
603 lines | 14.696kb
added common test executing ...
Yuki Kimoto authored on 2011-08-07
1
=encoding utf8
2

            
3
=head1 NAME
4

            
5
DBIx::Custom::Guide - DBIx::Custom Guide
6

            
7
=head1 FEATURES
8

            
9
L<DBIx::Custom> is the wrapper class of L<DBI> to execute SQL easily.
10
This module have the following features.
11

            
12
=over 4
13

            
14
=item * Execute INSERT, UPDATE, DELETE, SELECT statement easily
15

            
16
=item * You can specify bind values by hash reference
17

            
18
=item * Filtering by data type. and you can set filter to any column
19

            
20
=item * Creating where clause and order by clause flexibly
21

            
22
=item * Support model
23

            
24
=back
25

            
26
=head1 GUIDE
27

            
28
=head2 Connect to database
29

            
30
    use DBIx::Custom;
31
    my $dbi = DBIx::Custom->connect(
32
        dsn => "dbi:mysql:database=bookshop",
33
        user => 'ken',
34
        password => '!LFKD%$&',
35
        dbi_option => {mysql_enable_utf8 => 1}
36
    );
37

            
38
You can connect to database by C<connect> method.
39
C<dsn> is data source name, C<user> is user name, C<password> is password.
40

            
41
C<dbi_option> is L<DBI> option.
42
By default, the following option is set.
43
Exeption is thrown when fatal error occur and commit mode is auto commit.
44

            
45
    {
46
        RaiseError  =>  1
47
        PrintError  =>  0
48
        AutoCommit  =>  1
49
    }
50

            
51
=head2 Execute query
52

            
53
=head3 Insert Statement : C<insert>
54

            
55
If you want to execute insert statement, use C<insert> method.
56

            
57
    $dbi->insert({title => 'Perl', author => 'Ken'}, table  => 'book');
58

            
59
First argument is insert row data, C<table>  is table name.
60

            
61
=head3 Update Statement : C<update>
62

            
63
If you want to execute update stateimuse, use C<update> method.
64

            
65
    $dbi->update(
66
        {title => 'Perl', author => 'Ken'},
67
        table  => 'book', 
68
        where  => {id => 5}
69
    );
70

            
71
First argument is update row data, C<table> is table name, C<where> is condition.
72

            
73
Note that you can't execute C<update> method without C<where>.
74
If you want to update all rows, use update_all.
75

            
76
    $dbi->update_all({title => 'Perl', author => 'Ken'}, table  => 'book');
77

            
78
=head3 Delete Statement : C<delete>
79

            
80
If you want to execute delete statement, use C<delete> method.
81

            
82
    $dbi->delete(table  => 'book', where  => {author => 'Ken'});
83

            
84
C<table> is table name, C<where> is condition.
85

            
86
Note that you can't execute C<delete> method without C<where>.
87
If you want to delete all rows, use C<delete_all> method.
88

            
89
    $dbi->delete_all(table  => 'book');
90

            
91
=head3 Select Statement : C<select>
92

            
93
If you want to execute select statement, use C<select> method.
94

            
95
    my $result = $dbi->select(table => 'book');
96

            
97
Return value is L<DBIx::Custom::Result> object.
98
You can fetch rows by C<fetch> method.
99

            
100
    while (my $row = $result->fetch) {
101
        my $title  = $row->[0];
102
        my $author = $row->[1];
103
    }
104

            
105
See also L<Fetch row/"Fetch row"> about L<DBIx::Custom::Result>.
106

            
107
You can specify column names by C<column> option
108
and condition by C<where> option.
109

            
110
    my $result = $dbi->select(
111
        table  => 'book',
112
        column => ['author',  'title'],
113
        where  => {author => 'Ken'}
114
    );
115

            
116
You can specify join clause by C<join> option.
117

            
118
    my $result = $dbi->select(
119
        table  => 'book',
120
        column => ['company.name as company_name']
121
        where  => {'book.name' => 'Perl'},
122
        join   => ['left outer join company on book.company_id = company.id]
123
    );
124

            
125
Note that join clause is joined only when C<where> or C<column> option contains table name,
126
such as book.name.
127

            
128
You can append statement to the end of whole statement by C<append> option.
129

            
130
    my $result = $dbi->select(
131
        table  => 'book',
132
        where  => {author => 'Ken'},
133
        append => 'for update',
134
    );
135

            
136
=head3 C<execute>
137

            
138
If you want to execute SQL, use C<execute> method.
139

            
140
    $dbi->execute("select * from book;");
141

            
142
You can specify named placeholder.
143

            
144
    $dbi->execute(
145
        "select * from book title = :title and author = :author;"
146
        {title => 'Perl', author => 'Ken'}
147
    );
148

            
149
:title and :author is named placeholder, which is replaced to placeholers.
150

            
151
    select * from book title = ? and author = ?;
152

            
153
=head3 C<dbh>
154

            
155
    my $dbh = $dbi->dbh;
156

            
157
Get get database handle object of L<DBI>.
158

            
159
=head3 C<DBI> methods
160

            
161
    $dbi->do(...);
162
    $dbi->begin_work;
163

            
164
You can call all methods of L<DBI> from L<DBIx::Custom> object.
165

            
166
=head2 Fetch Rows
167

            
168
C<select> method return value is L<DBIx::Custom::Result> object.
169
You can fetch a row or rows by various methods.
170

            
171
=head3 Fetch a row (array) : C<fetch>
172

            
173
    my $row = $result->fetch;
174

            
175
C<fetch> method fetch a row and put it into array reference.
176
You can continue to fetch 
177

            
178
    while (my $row = $result->fetch) {
179
        my $title  = $row->[0];
180
        my $author = $row->[1];
181
    }
182

            
183
=head3 Fetch only first row (array) : C<fetch_first>
184

            
185
    my $row = $result->fetch_first;
186

            
187
C<fetch_first> fetch a only first row and finish statment handle,
188
and put it into array refrence.
189

            
190
=head3 Fetch all rows (array) : C<fetch_all>
191

            
192
    my $rows = $result->fetch_all;
193

            
194
C<fetch_all> fetch all rows and put them into array of array reference.
195

            
196
=head3 Fetch a row (hash) : C<fetch_hash>
197

            
198
    my $row = $result->fetch_hash;
199

            
200
C<fetch_hash> fetch a row and put it into hash reference.
201
You can fetch a row while row exists.
202

            
203
    while (my $row = $result->fetch_hash) {
204
        my $title  = $row->{title};
205
        my $author = $row->{author};
206
    }
207

            
208
=head3 Fetch only a first row (hash) : C<fetch_hash_first>
209

            
210
    my $row = $result->fetch_hash_first;
211

            
212
C<fetch_hash_first> fetch only a first row and finish statement handle,
213
and put them into hash refrence.
214

            
215
C<one> is C<fetch_hash_first> synonym to save word typing.
216

            
217
    my $row = $result->one;
218

            
219
=head3 Fetch all rows (hash) : C<fetch_hash_all>
220

            
221
    my $rows = $result->fetch_hash_all;
222

            
223
C<fetch_hash_all> fetch all rows and put them into array of hash reference.
224

            
225
=head3 Statement Handle : C<sth>
226

            
227
    my $sth = $result->sth;
228

            
229
If you want to get statment handle, use <sth> method.
230

            
231
=head2 Named placeholder
232

            
233
=head3 Basic of Parameter
234

            
235
You can embedd named placeholder into SQL.
236

            
237
    select * from book where title = :title and author like :author;
238

            
239
:title and :author is named placeholder
240

            
241
Named placeholder is replaced by place holder.
242

            
243
    select * from book where title = ? and author like ?;
244

            
245
use C<execute> to execute SQL.
246

            
247
    my $sql = "select * from book where title = :title and author like :author;"
248
    $dbi->execute($sql, {title => 'Perl', author => '%Ken%'});
249

            
250
You can specify C<filter> at C<execute>.
251

            
252
    $dbi->execute($sql, {title => 'Perl', author => '%Ken%'}
253
                  filter => {title => 'to_something');
254

            
255
=head3 Manipulate same name's columns
256

            
257
It is ok if there are same name's columns.
258
Let's think two date comparison.
259

            
260
    my $sql = "select * from table where date > :date and date < :date;";
261

            
262
In this case, You specify parameter values as array reference.
263

            
264
    my $dbi->execute($sql, {date => ['2010-10-01', '2012-02-10']});
265

            
266
=head2 Create where clause
267

            
268
=head3 Dinamically create where clause : where
269

            
270
You want to search multiple conditions in many times.
271
Let's think the following three cases.
272

            
273
Case1: Search only C<title>
274

            
275
    where title = :title
276

            
277
Case2: Search only C<author>
278

            
279
    where author = :author
280

            
281
Case3: Search C<title> and C<author>
282

            
283
    where title = :title and author = :author
284

            
285
L<DBIx::Custom> support dinamic where clause creating.
286
At first, create L<DBIx::Custom::Where> object by C<where>.
287

            
288
    my $where = $dbi->where;
289

            
290
Set clause by C<clause>
291

            
292
    $where->clause(
293
        ['and', 'title = :title, 'author = :author']
294
    );
295

            
296
C<clause> is the following format.
297

            
298
    ['or' or 'and', PART1, PART1, PART1]
299

            
300
First argument is 'or' or 'and'.
301
Later than first argument are part which contains named placeholder.
302

            
303
You can write more complex format.
304

            
305
    ['and', 
306
      'title = :title', 
307
      ['or', 'author = :author', 'date like :date']
308
    ]
309

            
310
This mean "title = :title and ( author = :author or date like :date )".
311

            
312
After setting C<clause>, set C<param>.
313
    
314
    $where->param({title => 'Perl'});
315

            
316
In this example, parameter contains only title.
317

            
318
If you execute C<string_to>, you can get where clause
319
which contain only named placeholder.
320

            
321
    my $where_clause = $where->to_string;
322

            
323
Parameter name is only title, the following where clause is created.
324

            
325
    where title = :title
326

            
327
You can also create where clause by stringification.
328

            
329
    my $where_clause = "$where";
330

            
331
This is useful to embbed it into SQL. 
332

            
333
=head3 In case where clause contains same name columns
334

            
335
Even if same name parameters exists, you can create where clause.
336
Let's think that there are starting date and ending date.
337

            
338
    my $param = {start_date => '2010-11-15', end_date => '2011-11-21'};
339

            
340
In this case, you set parameter value as array reference.
341

            
342
    my $p = {date => ['2010-11-15', '2011-11-21']};
343

            
344
You can embbed these values into same name parameters.
345

            
346
    $where->clause(
347
        ['and', 'date > :date', 'date < :date']
348
    );
349
    $where->param($p);
350

            
351
If starting date isn't exists, create the following parameter.
352

            
353
    my $p = {date => [$dbi->not_exists, '2011-11-21']};
354

            
355
You can get DBIx::Custom::NotExists object by C<not_exists>
356
This mean correnspondinf value isn't exists.
357

            
358
If ending date isn't exists, create the following parameter.
359

            
360
    my $p = {date => ['2010-11-15']};
361

            
362
If both date isn't exists, create the following parameter.
363

            
364
    my $p = {date => []};
365

            
366
This logic is a little difficut. See the following ones.
367

            
368
    my @date;
369
    push @date, exists $param->{start_date} ? $param->{start_date}
370
                                            : $dbi->not_exists;
371
    push @date, $param->{end_date} if exists $param->{end_date};
372
    my $p = {date => \@date};
373

            
374
=head3 With C<select>
375

            
376
You can pass L<DBIx::Custom::Where> object to C<where> of C<select>.
377
    
378
    my $where = $dbi->where;
379
    $where->clause(['and', 'title = :title', 'author = :author']);
380
    $where->param({title => 'Perl'});
381
    my $result = $dbi->select(table => 'book', where => $where);
382

            
383
You can also pass it to C<where> of C<update>AC<delete>
384

            
385
=head3 With C<execute>
386

            
387
L<DBIx::Custom::Where> object is embedded into SQL.
388

            
389
    my $where = $dbi->where;
390
    $where->clause(['and', 'title = :title', 'author = :author']);
391
    $where->param({title => 'Perl'});
392

            
393
    my $sql = <<"EOS";
394
    select * from book;
395
    $where
396
    EOS
397

            
398
    $dbi->execute($sql, $param, table => 'book');
399

            
400
=head2 Filtering
401

            
402
=head3 Register filter : C<register_filter>
403

            
404
If you want to register filter, use C<register_filter>.
405

            
406
    $dbi->register_filter(
407
        # Time::Piece object to DATE format
408
        tp_to_date => sub {
409
            my $date = shift;
410
            return $tp->strftime('%Y-%m-%d');
411
        },
412
        
413
        # DATE to Time::Piece object
414
        date_to_tp => sub {
415
            my $date = shift;
416
            return Time::Piece->strptime($date, '%Y-%m-%d');
417
        },
418
    );
419

            
420
=head3 Filter before sending data into database : C<filter> option
421

            
422
If you filter sending data, use C<filter> option.
423

            
424
    $dbi->execute(
425
        'insert into book (date) values (:date)',
426
        {date => $tp},
427
        filter => {date => 'tp_to_date'}
428
    );
429

            
430
You can use C<filter> option in C<insert>, C<update>, C<delete>, C<select> method.
431

            
432
    $dbi->insert(
433
        {date => $tp},
434
        table => 'book',
435
        filter => {date => 'tp_to_date'}
436
    );
437

            
438
=head3 Filter after fetching data from database.
439

            
440
If you filter fetch data, use L<DBIx::Custom::Result>'s C<filter> method.
441

            
442
    my $result = $dbi->select(column => 'date', table => 'book');
443
    $result->filter(date => 'date_to_tp');
444
    my $row = $result->one;
445

            
446
=head2 7. Model
447

            
448
=head3 Model
449

            
450
you can define model extending L<DBIx::Custom::Model>
451
to improve source code view.
452

            
453
At first, you create basic model class extending <DBIx::Custom::Model>.
454
Each L<DBIx::Custom> class inherit L<Object::Simple>.
455
so you can inherit the following way.
456

            
457
    package MyModel;
458
    use DBIx::Custom::Model -base;
459

            
460
Next, you create each model classes.
461

            
462
MyModel::book
463

            
464
    package MyModel::book;
465
    use MyModel -base;
466
    
467
    sub insert { ... }
468
    sub list { ... }
469

            
470
MyModel::company
471

            
472
    package MyModel::company;
473
    use MyModel -base;
474
    
475
    sub insert { ... }
476
    sub list { ... }
477

            
478
The follwoing modules location is needed.
479

            
480
    MyModel.pm
481
    MyModel / book.pm
482
            / company.pm
483

            
484
You can include these models by C<include_model>
485

            
486
    $dbi->include_model('MyModel');
487

            
488
First argument is name space of model.
489

            
490
You can use model like this.
491

            
492
    my $result = $dbi->model('book')->list;
493

            
494
In mode, You can use such as methods,
495
C<insert>, C<update>, C<update_all>,
496
C<delete>, C<delete_all>, C<select>
497
without C<table> option.
498

            
499
    $dbi->model('book')->insert($param);
500

            
501
Model is L<DBIx::Custom::Model>.
502

            
503
If you need table nameAyou can get it by C<table>.
504

            
505
    my $table = $model->table;
506

            
507
You can get L<DBIx::Custom>.
508

            
509
    my $dbi = $model->dbi;
510

            
511
You can also call all methods of L<DBIx::Custom> and L<DBI>. 
512

            
513
    # DBIx::Custom method
514
    $model->execute($sql);
515
    
516
    # DBI method
517
    $model->begin_work;
518
    $model->commit;
519

            
520
If you want to get all models, you can get them by keys of C<models>.
521

            
522
    my @models = keys %{$self->models};
523

            
524
You can set primary key to model.
525

            
526
   $model->primary_key(['id', 'number_id']);
527

            
528
Primary key is used by C<insert>, C<update>, C<delete>,
529
and C<select> methods.
530

            
531
You can set column names
532

            
533
    $model->columns(['id', 'number_id']);
534

            
535
Column names is automarically set by C<setup_model>.
536
This method is needed to be call after C<include_model>.
537

            
538
    $dbi->setup_model;
539

            
540
You can set C<join>
541

            
542
    $model->join(['left outer join company on book.company_id = company.id']);
543

            
544
C<join> is used by C<select> method.
545

            
546
=head2 Create column clause automatically : mycolumn, column
547

            
548
To create column clause automatically, use C<mycolumn>.
549
Valude of C<table> and C<columns> is used.
550

            
551
    my $mycolumns = $model->mycolumn;
552

            
553
If C<table> is 'book'AC<column> is ['id', 'name'],
554
the following clause is created.
555

            
556
    book.id as id, book.name as name
557

            
558
These column name is for removing column name ambiguities.
559

            
560
You can create column clause from columns of other table.
561

            
562
    my $columns = $model->column('company');
563

            
564
If C<table> is "company", C<column> return ['id', 'name'],
565
the following clause is created.
566

            
567
    company.id as "company.id", company.name as "company.name"
568

            
569
=head2 Model Examples
570

            
571
Model examples
572

            
573
    package MyDBI;
574
    use DBIx::Custom -base;
575
    
576
    sub connect {
577
        my $self = shift->SUPER::connect(@_);
578
        
579
        $self->include_model(
580
            MyModel => [
581
                'book',
582
                'company'
583
            ]
584
        );
585
    }
586
    
587
    package MyModel::book;
588
    use DBIx::Custom::Model -base;
589
    
590
    has primary_key => sub { ['id'] };
591
    
592
    sub insert { ... }
593
    sub list { ... }
594
    
595
    package MyModel::company;
596
    use DBIx::Custom::Model -base;
597

            
598
    has primary_key => sub { ['id'] };
599
    
600
    sub insert { ... }
601
    sub list { ... }
602

            
603
=cut