sql-maker 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -339,338 +339,3 @@ class SQL::Maker
339
339
  return stmt
340
340
  end
341
341
  end
342
-
343
- __END__
344
-
345
- =encoding utf8
346
-
347
- =head1 NAME
348
-
349
- SQL::Maker - Yet another SQL builder
350
-
351
- =head1 SYNOPSIS
352
-
353
- use SQL::Maker
354
-
355
- builder = SQL::Maker.new(
356
- :driver => 'SQLite', # or your favorite driver
357
- )
358
-
359
- # SELECT
360
- sql, bind = builder.select(table, fields, where, opt)
361
-
362
- # INSERT
363
- sql, bind = builder.insert(table, values, opt)
364
-
365
- # DELETE
366
- sql, bind = builder.delete(table, where, opt)
367
-
368
- # UPDATE
369
- sql, bind = builder.update(table, set, where)
370
- sql, bind = builder.update(table, set, where)
371
-
372
- =head1 DESCRIPTION
373
-
374
- SQL::Maker is yet another SQL builder class.
375
-
376
- =head1 METHODS
377
-
378
- =over 4
379
-
380
- =item C<< builder = SQL::Maker.new(args) >>
381
-
382
- Create new instance of SQL::Maker.
383
-
384
- Attributes are the following:
385
-
386
- =over 4
387
-
388
- =item driver: Str
389
-
390
- Driver name is required. The driver type is needed to create SQL string.
391
-
392
- =item quote_char: Str
393
-
394
- This is the character that a table or column name will be quoted with.
395
-
396
- Default: auto detect from driver.
397
-
398
- =item name_sep: Str
399
-
400
- This is the character that separates a table and column name.
401
-
402
- Default: '.'
403
-
404
- =item new_line: Str
405
-
406
- This is the character that separates a part of statements.
407
-
408
- Default: '\n'
409
-
410
- =item strict: Bool
411
-
412
- In strict mode, all the expressions must be declared by using instances of SQL::QueryMaker
413
-
414
- Default: false
415
-
416
- =back
417
-
418
- =item C<< select = builder.new_select(args) >>
419
-
420
- Create new instance of L<SQL::Maker::Select> using the settings from B<builder>.
421
-
422
- This method returns an instance of L<SQL::Maker::Select>.
423
-
424
- =item C<< sql, bind = builder.select(table|tables, fields, where, opt) >>
425
-
426
- sql, bind = builder.select('user', ['*'], {:name => 'john'}, {:order_by => 'user_id DESC'})
427
- # =>
428
- # SELECT * FROM `user` WHERE (`name` = ?) ORDER BY user_id DESC
429
- # ['john']
430
-
431
- This method returns the SQL string and bind variables for a SELECT statement.
432
-
433
- =over 4
434
-
435
- =item C<< table >>
436
-
437
- =item C<< \@tables >>
438
-
439
- Table name for the B<FROM> clause as scalar or arrayref. You can specify the instance of B<SQL::Maker::Select> for a sub-query.
440
-
441
- If you are using C<< opt.joins >> this should be I<< undef >> since it's passed via the first join.
442
-
443
- =item C<< \@fields >>
444
-
445
- This is a list for retrieving fields from database.
446
-
447
- Each element of the C<@fields> is normally a scalar or a scalar ref containing the column name.
448
- If you want to specify an alias of the field, you can use an arrayref containing a pair
449
- of column and alias names (e.g. C<< ['foo.id' => 'foo_id'] >>).
450
-
451
- =item C<< \%where >>
452
-
453
- =item C<< \@where >>
454
-
455
- =item C<< where >>
456
-
457
- where clause from hashref or arrayref via L<SQL::Maker::Condition>, or L<SQL::Maker::Condition> object.
458
-
459
- =item C<< \%opt >>
460
-
461
- These are the options for the SELECT statement
462
-
463
- =over 4
464
-
465
- =item C<< opt.prefix >>
466
-
467
- This is a prefix for the SELECT statement.
468
-
469
- For example, you can provide the 'SELECT SQL_CALC_FOUND_ROWS '. It's useful for MySQL.
470
-
471
- Default Value: 'SELECT '
472
-
473
- =item C<< opt.limit >>
474
-
475
- This option adds a 'LIMIT n' clause.
476
-
477
- =item C<< opt.offset >>
478
-
479
- This option adds an 'OFFSET n' clause.
480
-
481
- =item C<< opt.order_by >>
482
-
483
- This option adds an B<ORDER BY> clause
484
-
485
- You can write it in any of the following forms:
486
-
487
- builder.select(..., {:order_by => 'foo DESC, bar ASC'})
488
- builder.select(..., {:order_by => ['foo DESC', 'bar ASC']})
489
- builder.select(..., {:order_by => {:foo => 'DESC'}})
490
- builder.select(..., {:order_by => [{:foo => 'DESC'}, {:bar => 'ASC'}]})
491
-
492
- =item C<< opt.group_by >>
493
-
494
- This option adds a B<GROUP BY> clause
495
-
496
- You can write it in any of the following forms:
497
-
498
- builder.select(..., {:group_by => 'foo DESC, bar ASC'})
499
- builder.select(..., {:group_by => ['foo DESC', 'bar ASC']})
500
- builder.select(..., {:group_by => {:foo => 'DESC'}})
501
- builder.select(..., {:group_by => [{:foo => 'DESC'}, {:bar => 'ASC'}]})
502
-
503
- =item C<< opt.having >>
504
-
505
- This option adds a HAVING clause
506
-
507
- =item C<< opt.for_update >>
508
-
509
- This option adds a 'FOR UPDATE" clause.
510
-
511
- =item C<< opt.joins >>
512
-
513
- This option adds a 'JOIN' via L<SQL::Maker::Select>.
514
-
515
- You can write it as follows:
516
-
517
- builder.select(undef, ..., {:joins => [[:user => {:table => 'group', :condition => 'user.gid = group.gid'}], ...]})
518
-
519
- =item C<< opt.index_hint >>
520
-
521
- This option adds an INDEX HINT like as 'USE INDEX' clause for MySQL via L<SQL::Maker::Select>.
522
-
523
- You can write it as follows:
524
-
525
- builder.select(..., { :index_hint => 'foo' })
526
- builder.select(..., { :index_hint => ['foo', 'bar'] })
527
- builder.select(..., { :index_hint => { :list => 'foo' })
528
- builder.select(..., { :index_hint => { :type => 'FORCE', :list => ['foo', 'bar'] })
529
-
530
- =back
531
-
532
- =back
533
-
534
- =item C<< sql, bind = builder.insert(table, \%values|\@values, \%opt); >>
535
-
536
- sql, bind = builder.insert(:user => {:name => 'john'})
537
- # =>
538
- # INSERT INTO `user` (`name`) VALUES (?)
539
- # ['john']
540
-
541
- Generate an INSERT query.
542
-
543
- =over 4
544
-
545
- =item C<< table >>
546
-
547
- Table name in scalar.
548
-
549
- =item C<< \%values >>
550
-
551
- These are the values for the INSERT statement.
552
-
553
- =item C<< \%opt >>
554
-
555
- These are the options for the INSERT statement
556
-
557
- =over 4
558
-
559
- =item C<< opt.prefix >>
560
-
561
- This is a prefix for the INSERT statement.
562
-
563
- For example, you can provide 'INSERT IGNORE INTO' for MySQL.
564
-
565
- Default Value: 'INSERT INTO'
566
-
567
- =back
568
-
569
- =back
570
-
571
- =item C<< sql, bind = builder.delete(table, \%where|\@where|where, \%opt); >>
572
-
573
- sql, bind = builder.delete(table, \%where)
574
- # =>
575
- # DELETE FROM `user` WHERE (`name` = ?)
576
- # ['john']
577
-
578
- Generate a DELETE query.
579
-
580
- =over 4
581
-
582
- =item C<< table >>
583
-
584
- Table name in scalar.
585
-
586
- =item C<< \%where >>
587
-
588
- =item C<< \@where >>
589
-
590
- =item C<< where >>
591
-
592
- where clause from hashref or arrayref via L<SQL::Maker::Condition>, or L<SQL::Maker::Condition> object.
593
-
594
- =item C<< \%opt >>
595
-
596
- These are the options for the DELETE statement
597
-
598
- =over 4
599
-
600
- =item C<< opt.using >>
601
-
602
- This option adds a USING clause. It takes a scalar or an arrayref of table names as argument:
603
-
604
- (sql, bind) = bulder.delete(table, \%where, { :using => 'group' })
605
- # =>
606
- # DELETE FROM `user` USING `group` WHERE (`group`.`name` = ?)
607
- # ['doe']
608
- bulder.delete(..., { :using => ['bar', 'qux'] })
609
-
610
- =back
611
-
612
- =back
613
-
614
- =item C<< sql, bind = builder.update(table, \%set|@set, \%where|\@where|where); >>
615
-
616
- Generate a UPDATE query.
617
-
618
- sql, bind = builder.update('user', ['name' => 'john', :email => 'john@example.com'], {:user_id => 3})
619
- # =>
620
- # 'UPDATE `user` SET `name` = ?, `email` = ? WHERE (`user_id` = ?)'
621
- # ['john','john@example.com',3]
622
-
623
- =over 4
624
-
625
- =item table
626
-
627
- Table name in scalar.
628
-
629
- =item \%set
630
-
631
- Setting values.
632
-
633
- =item \%where
634
-
635
- =item \@where
636
-
637
- =item where
638
-
639
- where clause from a hashref or arrayref via L<SQL::Maker::Condition>, or L<SQL::Maker::Condition> object.
640
-
641
- =back
642
-
643
- =item C<< builder.new_condition() >>
644
-
645
- Create new L<SQL::Maker::Condition> object from C< builder > settings.
646
-
647
- =item C<< sql, bind = builder.where(where) >>
648
-
649
- Where clause from a hashref or arrayref via L<SQL::Maker::Condition>, or L<SQL::Maker::Condition> object.
650
-
651
- =back
652
-
653
- =head1 PLUGINS
654
-
655
- SQL::Maker features a plugin system. Write the code as follows:
656
-
657
- require 'sql/maker'
658
- SQL::Maker.load_plugin('insert_multi')
659
-
660
- =head1 FAQ
661
-
662
- =over 4
663
-
664
- =item Why don't you use Arel or ActiveRecord?
665
-
666
- I wanted a query builder rather than ORM.
667
-
668
- I wanted simpler one than Arel.
669
-
670
- =back
671
-
672
- =head1 SEE ALSO
673
-
674
- https://github.com/tokuhirom/SQL-Maker
675
-
676
- =cut
@@ -186,204 +186,3 @@ class SQL::Maker::Condition
186
186
  @auto_bind ? bind_param(sql, self.bind) : sql
187
187
  end
188
188
  end
189
-
190
- __END__
191
-
192
- =for test_synopsis
193
- my (sql, @bind)
194
-
195
- =head1 NAME
196
-
197
- SQL::Maker::Condition - condition object for SQL::Maker
198
-
199
- =head1 SYNOPSIS
200
-
201
- my condition = SQL::Maker::Condition.new(
202
- name_sep => '.',
203
- quote_char => '`',
204
- )
205
- condition.add('foo_id' => 3)
206
- condition.add('bar_id' => 4)
207
- sql = condition.as_sql() # (`foo_id`=?) AND (`bar_id`=?)
208
- @bind = condition.bind() # (3, 4)
209
-
210
- # add_raw
211
- my condition = SQL::Maker::Condition.new(
212
- name_sep => '.',
213
- quote_char => '`',
214
- )
215
- condition.add_raw('EXISTS(SELECT * FROM bar WHERE name = ?)' => ['john'])
216
- condition.add_raw('type IS NOT NULL')
217
- sql = condition.as_sql() # (EXISTS(SELECT * FROM bar WHERE name = ?)) AND (type IS NOT NULL)
218
- @bind = condition.bind() # ('john')
219
-
220
- # composite and
221
- my other = SQL::Maker::Condition.new(
222
- name_sep => '.',
223
- quote_char => '`',
224
- )
225
- other.add('name' => 'john')
226
- my $comp_and = condition & other
227
- sql = $comp_and.as_sql() # ((`foo_id`=?) AND (`bar_id`=?)) AND (`name`=?)
228
- @bind = $comp_and.bind() # (3, 4, 'john')
229
-
230
- # composite or
231
- my $comp_or = condition | other
232
- sql = $comp_and.as_sql() # ((`foo_id`=?) AND (`bar_id`=?)) OR (`name`=?)
233
- @bind = $comp_and.bind() # (3, 4, 'john')
234
-
235
-
236
- =head1 CONDITION CHEAT SHEET
237
-
238
- Here is a cheat sheet for conditions.
239
-
240
- IN: {'foo'=>'bar'}
241
- OUT QUERY: '`foo` = ?'
242
- OUT BIND: ['bar']
243
-
244
- IN: {'foo'=>['bar','baz']}
245
- OUT QUERY: '`foo` IN (?, ?)'
246
- OUT BIND: ['bar','baz']
247
-
248
- IN: {'foo'=>{'IN' => ['bar','baz']}}
249
- OUT QUERY: '`foo` IN (?, ?)'
250
- OUT BIND: ['bar','baz']
251
-
252
- IN: {'foo'=>{'not IN' => ['bar','baz']}}
253
- OUT QUERY: '`foo` NOT IN (?, ?)'
254
- OUT BIND: ['bar','baz']
255
-
256
- IN: {'foo'=>{'!=' => 'bar'}}
257
- OUT QUERY: '`foo` != ?'
258
- OUT BIND: ['bar']
259
-
260
- # IN: {'foo'=>\'IS NOT NULL'}
261
- # OUT QUERY: '`foo` IS NOT NULL'
262
- # OUT BIND: []
263
-
264
- IN: {'foo'=>{'between' => ['1','2']}}
265
- OUT QUERY: '`foo` BETWEEN ? AND ?'
266
- OUT BIND: ['1','2']
267
-
268
- IN: {'foo'=>{'like' => 'xaic%'}}
269
- OUT QUERY: '`foo` LIKE ?'
270
- OUT BIND: ['xaic%']
271
-
272
- IN: {'foo'=>[{'>' => 'bar'},{'<' => 'baz'}]}
273
- OUT QUERY: '(`foo` > ?) OR (`foo` < ?)'
274
- OUT BIND: ['bar','baz']
275
-
276
- IN: {'foo'=>{:AND => [{'>' => 'bar'},{'<' => 'baz'}]}}
277
- OUT QUERY: '(`foo` > ?) AND (`foo` < ?)'
278
- OUT BIND: ['bar','baz']
279
-
280
- IN: {'foo'=>{:AND => ['foo','bar','baz']}}
281
- OUT QUERY: '(`foo` = ?) AND (`foo` = ?) AND (`foo` = ?)'
282
- OUT BIND: ['foo','bar','baz']
283
-
284
- IN: {'foo_id'=>{'IN' => sql_raw('SELECT foo_id FROM bar WHERE t=?',44)}}
285
- OUT QUERY: '`foo_id` IN (SELECT foo_id FROM bar WHERE t=?)'
286
- OUT BIND: [44]
287
-
288
- # IN: ['foo_id',\['MATCH (col1, col2) AGAINST (?)','apples']]
289
- # OUT QUERY: '`foo_id` MATCH (col1, col2) AGAINST (?)'
290
- # OUT BIND: ['apples']
291
-
292
- IN: {'foo_id'=>nil}
293
- OUT QUERY: '`foo_id` IS NULL'
294
- OUT BIND: []
295
-
296
- IN: {'foo_id'=>{'IN' => []}}
297
- OUT QUERY: '0=1'
298
- OUT BIND: []
299
-
300
- IN: {'foo_id'=>{'NOT IN' => []}}
301
- OUT QUERY: '1=1'
302
- OUT BIND: []
303
-
304
- # IN: ['foo_id', [123,sql_type(\3, SQL_INTEGER)]]
305
- # OUT QUERY: '`foo_id` IN (?, ?)'
306
- # OUT BIND: (123, sql_type(\3, SQL_INTEGER))
307
- #
308
- # IN: ['foo_id', sql_type(\3, SQL_INTEGER)]
309
- # OUT QUERY: '`foo_id` = ?'
310
- # OUT BIND: sql_type(\3, SQL_INTEGER)
311
- #
312
- # IN: ['created_on', { '>', \'DATE_SUB(NOW(), INTERVAL 1 DAY)' }]
313
- # OUT QUERY: '`created_on` > DATE_SUB(NOW(), INTERVAL 1 DAY)'
314
- # OUT BIND:
315
-
316
- It is also possible to use the functions exported by C<SQL::QueryMaker> to define the conditions.
317
-
318
- IN: {'foo' => sql_in(['bar','baz'])}
319
- OUT QUERY: '`foo` IN (?,?)'
320
- OUT BIND: ['bar','baz']
321
-
322
- IN: {'foo' => sql_lt(3)}
323
- OUT QUERY: '`foo` < ?'
324
- OUT BIND: [3]
325
-
326
- IN: {'foo' => sql_not_in(['bar','baz'])}
327
- OUT QUERY: '`foo` NOT IN (?,?)'
328
- OUT BIND: ['bar','baz']
329
-
330
- IN: {'foo' => sql_ne('bar')}
331
- OUT QUERY: '`foo` != ?'
332
- OUT BIND: ['bar']
333
-
334
- IN: {'foo' => sql_is_not_null()}
335
- OUT QUERY: '`foo` IS NOT NULL'
336
- OUT BIND: []
337
-
338
- IN: {'foo' => sql_between('1','2')}
339
- OUT QUERY: '`foo` BETWEEN ? AND ?'
340
- OUT BIND: ['1','2']
341
-
342
- IN: {'foo' => sql_like('xaic%')}
343
- OUT QUERY: '`foo` LIKE ?'
344
- OUT BIND: ['xaic%']
345
-
346
- IN: {'foo' => sql_or([sql_gt('bar'), sql_lt('baz')])}
347
- OUT QUERY: '(`foo` > ?) OR (`foo` < ?)'
348
- OUT BIND: ['bar','baz']
349
-
350
- IN: {'foo' => sql_and([sql_gt('bar'), sql_lt('baz')])}
351
- OUT QUERY: '(`foo` > ?) AND (`foo` < ?)'
352
- OUT BIND: ['bar','baz']
353
-
354
- IN: {'foo_id' => sql_op('IN (SELECT foo_id FROM bar WHERE t=?)',[44])}
355
- OUT QUERY: '`foo_id` IN (SELECT foo_id FROM bar WHERE t=?)'
356
- OUT BIND: [44]
357
-
358
- IN: {'foo_id' => sql_in([sql_raw('SELECT foo_id FROM bar WHERE t=?',44)])}
359
- OUT QUERY: '`foo_id` IN ((SELECT foo_id FROM bar WHERE t=?))'
360
- OUT BIND: [44]
361
-
362
- IN: {'foo_id' => sql_op('MATCH (@) AGAINST (?)',['apples'])}
363
- OUT QUERY: 'MATCH (`foo_id`) AGAINST (?)'
364
- OUT BIND: ['apples']
365
-
366
- IN: {'foo_id'=>sql_in([])}
367
- OUT QUERY: '0=1'
368
- OUT BIND: []
369
-
370
- IN: {'foo_id'=>sql_not_in([])}
371
- OUT QUERY: '1=1'
372
- OUT BIND: []
373
-
374
- # IN: ['foo_id', sql_type(\3, SQL_INTEGER)]
375
- # OUT QUERY: '`foo_id` = ?'
376
- # OUT BIND: sql_type(\3, SQL_INTEGER)
377
- #
378
- # IN: ['foo_id', sql_in([sql_type(\3, SQL_INTEGER)])]
379
- # OUT QUERY: '`foo_id` IN (?)'
380
- # OUT BIND: sql_type(\3, SQL_INTEGER)
381
- #
382
- # IN: ['created_on', sql_gt(sql_raw('DATE_SUB(NOW(), INTERVAL 1 DAY)')) ]
383
- # OUT QUERY: '`created_on` > DATE_SUB(NOW(), INTERVAL 1 DAY)'
384
- # OUT BIND:
385
-
386
- =head1 SEE ALSO
387
-
388
- L<SQL::Maker>
389
-