sql-maker 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
-