Skip to content

Commit

Permalink
[Pg] basic grammar-based tokenization of SQL
Browse files Browse the repository at this point in the history
  • Loading branch information
moritz committed May 4, 2012
1 parent 85a4f68 commit 66f1aca
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
53 changes: 53 additions & 0 deletions lib/DBDish/Pg.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,54 @@ constant PGRES_COPY_IN = 4;

#-----------------------------------------------------------------------

my grammar PgTokenizer {
token double_quote_normal { <-[\\"]>+ }
token double_quote_escape { [\\ . ]+ }
token double_quote {
\"
[
| <.double_quote_normal>
| <.double_quote_escape>
]*
\"
}
token single_quote_normal { <-['\\]>+ }
token single_quote_escape { [ \'\' || \\ . ]+ }
token single_quote {
\'
[
| <.single_quote_normal>
| <.single_quote_escape>
]*
\'
}
token placeholder { '?' }
token normal { <-[?"']>+ }

token TOP {
^
(
| <normal>
| <placeholder>
| <single_quote>
| <double_quote>
)*
$
}
}

my class PgTokenizer::Actions {
has $.counter = 0;
method single_quote($/) { make $/.Str }
method double_quote($/) { make $/.Str }
method placeholder($/) { make '$' ~ ++$!counter }
method normal($/) { make $/.Str }
method TOP($/) {
make $0.map(*.values[0].ast).join;
}
}


class DBDish::Pg::StatementHandle does DBDish::StatementHandle {
has $!pg_conn;
has Str $!statement_name;
Expand Down Expand Up @@ -385,6 +433,11 @@ class DBDish::Pg::Connection does DBDish::Connection {

class DBDish::Pg:auth<mberends>:ver<0.0.1> {

sub pg-replace-placeholder(Str $query) is export {
PgTokenizer.parse($query, :actions(PgTokenizer::Actions.new))
and $/.ast;
}

has $.Version = 0.01;
has $!errstr;
method !errstr() is rw { $!errstr }
Expand Down
12 changes: 12 additions & 0 deletions t/30-Pg.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use v6;
use Test;
plan 2;
use DBDish::Pg;

is pg-replace-placeholder(q[INSERT INTO "foo?" VALUES('?', ?, ?)]),
q[INSERT INTO "foo?" VALUES('?', $1, $2)],
'basic tokenization';

is pg-replace-placeholder(q['a\.b''cd?', "\"?", ?]),
q['a\.b''cd?', "\"?", $1],
'backslash escapes and doubled single quote';

0 comments on commit 66f1aca

Please sign in to comment.