From 7db001a7c3c8fd02c8eed5405daf83f0bec186db Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Sun, 15 Jun 2014 14:19:38 +0200 Subject: [PATCH] Allow the MySQL command parser to process clauses in any order, fix #56. Only the MySQL command is addressed in this patch, because the code level approach is not safisfying me completely. It might be easier to just bite the bullet and review all the optional clauses return values rather than add a layer as this patch does. The feature still is available for MySQL given this patch, so let's push it, get feedback, then see about how to make the approach scale and revise all the other commands. --- src/parser.lisp | 56 +++++++++++++++++++++++++++---------- test/parse/hans.goeuro.load | 8 ++++-- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/parser.lisp b/src/parser.lisp index f09a443..75b4cb6 100644 --- a/src/parser.lisp +++ b/src/parser.lisp @@ -966,23 +966,51 @@ (defrule decoding-tables-as (* decoding-table-as)) + +;;; +;;; Allow clauses to appear in any order +;;; +(defrule mysql-options-clause mysql-options + (:lambda (opts) `(:mysql-options ,@opts))) + +(defrule gucs-clause gucs (:lambda (gucs) `(:gucs ,@gucs))) +(defrule casts-clause casts (:lambda (casts) `(:casts ,@casts))) +(defrule mview-clause materialize-views (:lambda (mv) `(:views ,@mv))) +(defrule including-clause including (:lambda (inc) `(:including ,@inc))) +(defrule excluding-clause excluding (:lambda (exc) `(:excluding ,@exc))) +(defrule decoding-clause decoding-table-as (:lambda (dec) `(:decoding ,dec))) +(defrule before-clause before-load (:lambda (b) `(:before ,@b))) +(defrule after-clause after-load (:lambda (a) `(:after ,@a))) + +(defrule load-mysql-optional-clauses (+ (or mysql-options-clause + gucs-clause + casts-clause + mview-clause + including-clause + excluding-clause + decoding-clause + before-clause + after-clause)) + (:lambda (clauses-list) + (alexandria:alist-plist clauses-list))) + +(defrule load-mysql-command (and database-source target + load-mysql-optional-clauses) + (:lambda (command) + (destructuring-bind (source target clauses) command + `(,source ,target ,@clauses)))) + ;;; LOAD DATABASE FROM mysql:// -(defrule load-mysql-database (and database-source target - (? mysql-options) - (? gucs) - (? casts) - (? materialize-views) - (? including) - (? excluding) - (? decoding-tables-as) - (? before-load) - (? after-load)) +(defrule load-mysql-database load-mysql-command (:lambda (source) - (destructuring-bind (my-db-uri pg-db-uri options - gucs casts views - incl excl decoding-as - before after) + (destructuring-bind (my-db-uri pg-db-uri + &key + gucs casts views before after + ((:mysql-options options)) + ((:including incl)) + ((:excuding excl)) + ((:decoding decoding-as))) source (destructuring-bind (&key ((:dbname mydb)) table-name &allow-other-keys) diff --git a/test/parse/hans.goeuro.load b/test/parse/hans.goeuro.load index 5f4992c..094b2df 100644 --- a/test/parse/hans.goeuro.load +++ b/test/parse/hans.goeuro.load @@ -2,7 +2,9 @@ LOAD DATABASE FROM mysql://root@unix:/tmp/mysql.sock:/goeuro INTO postgresql://dim@unix:/tmp:/godollar - WITH include drop, create tables, create indexes, reset sequences + INCLUDING ONLY TABLE NAMES MATCHING ~/encoding/ + + DECODING TABLE NAMES MATCHING ~/messed/, ~/encoding/ AS utf-8 CAST type datetime to timestamptz drop default drop not null using zero-dates-to-null, type date drop not null drop default using zero-dates-to-null, @@ -24,7 +26,7 @@ LOAD DATABASE group by cast(d as date); $$ - -- INCLUDING ONLY TABLE NAMES MATCHING ~/encoding/ + WITH include drop, create tables, create indexes, reset sequences - DECODING TABLE NAMES MATCHING ~/messed/, ~/encoding/ AS utf-8; + ;