Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[Pg] basic grammar-based tokenization of SQL

  • Loading branch information...
commit 66f1acacd39a4efef35db02a921994d5f051c502 1 parent 85a4f68
@moritz moritz authored
Showing with 65 additions and 0 deletions.
  1. +53 −0 lib/DBDish/Pg.pm6
  2. +12 −0 t/30-Pg.t
View
53 lib/DBDish/Pg.pm6
@@ -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;
@@ -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 }
View
12 t/30-Pg.t
@@ -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';
Please sign in to comment.
Something went wrong with that request. Please try again.