mirror of
https://github.com/dimitri/pgloader.git
synced 2025-08-07 06:47:00 +02:00
Implement a new “snake_case” quoting rule.
In passing, add the identifiers case option to SQLite support, which makes it easier to test here, and add a table named "TableName" to our local test database. Fix #631.
This commit is contained in:
parent
d2d4be2ed0
commit
dbadab9e9e
@ -66,7 +66,7 @@
|
|||||||
;; PostgreSQL related utils
|
;; PostgreSQL related utils
|
||||||
(:file "read-sql-files")
|
(:file "read-sql-files")
|
||||||
(:file "queries")
|
(:file "queries")
|
||||||
(:file "quoting")
|
(:file "quoting" :depends-on ("utils"))
|
||||||
(:file "catalog" :depends-on ("quoting"))
|
(:file "catalog" :depends-on ("quoting"))
|
||||||
(:file "alter-table" :depends-on ("catalog"))
|
(:file "alter-table" :depends-on ("catalog"))
|
||||||
|
|
||||||
|
@ -35,7 +35,8 @@
|
|||||||
(:export #:apply-identifier-case
|
(:export #:apply-identifier-case
|
||||||
#:build-identifier
|
#:build-identifier
|
||||||
#:quoted-p
|
#:quoted-p
|
||||||
#:ensure-unquoted))
|
#:ensure-unquoted
|
||||||
|
#:camelCase-to-colname))
|
||||||
|
|
||||||
(defpackage #:pgloader.catalog
|
(defpackage #:pgloader.catalog
|
||||||
(:use #:cl #:pgloader.params #:pgloader.quoting)
|
(:use #:cl #:pgloader.params #:pgloader.quoting)
|
||||||
|
@ -125,6 +125,7 @@
|
|||||||
(def-keyword-rule "keys")
|
(def-keyword-rule "keys")
|
||||||
(def-keyword-rule "downcase")
|
(def-keyword-rule "downcase")
|
||||||
(def-keyword-rule "quote")
|
(def-keyword-rule "quote")
|
||||||
|
(def-keyword-rule "snake_case")
|
||||||
(def-keyword-rule "identifiers")
|
(def-keyword-rule "identifiers")
|
||||||
(def-keyword-rule "including")
|
(def-keyword-rule "including")
|
||||||
(def-keyword-rule "excluding")
|
(def-keyword-rule "excluding")
|
||||||
|
@ -160,7 +160,10 @@
|
|||||||
(defrule option-on-error-stop (and kw-on kw-error kw-stop)
|
(defrule option-on-error-stop (and kw-on kw-error kw-stop)
|
||||||
(:constant (cons :on-error-stop t)))
|
(:constant (cons :on-error-stop t)))
|
||||||
|
|
||||||
(defrule option-identifiers-case (and (or kw-downcase kw-quote) kw-identifiers)
|
(defrule option-identifiers-case (and (or kw-snake_case
|
||||||
|
kw-downcase
|
||||||
|
kw-quote)
|
||||||
|
kw-identifiers)
|
||||||
(:lambda (id-case)
|
(:lambda (id-case)
|
||||||
(bind (((action _) id-case))
|
(bind (((action _) id-case))
|
||||||
(cons :identifier-case action))))
|
(cons :identifier-case action))))
|
||||||
|
@ -31,7 +31,8 @@ load database
|
|||||||
option-index-names
|
option-index-names
|
||||||
option-reset-sequences
|
option-reset-sequences
|
||||||
option-foreign-keys
|
option-foreign-keys
|
||||||
option-encoding))
|
option-encoding
|
||||||
|
option-identifiers-case))
|
||||||
|
|
||||||
(defrule sqlite-options (and kw-with
|
(defrule sqlite-options (and kw-with
|
||||||
(and sqlite-option (* (and comma sqlite-option))))
|
(and sqlite-option (* (and comma sqlite-option))))
|
||||||
@ -100,6 +101,7 @@ load database
|
|||||||
(*cast-rules* ',casts)
|
(*cast-rules* ',casts)
|
||||||
,@(pgsql-connection-bindings pg-db-conn gucs)
|
,@(pgsql-connection-bindings pg-db-conn gucs)
|
||||||
,@(batch-control-bindings options)
|
,@(batch-control-bindings options)
|
||||||
|
,@(identifier-case-binding options)
|
||||||
(source-db (with-stats-collection ("fetch" :section :pre)
|
(source-db (with-stats-collection ("fetch" :section :pre)
|
||||||
(expand (fetch-file ,sqlite-db-conn))))
|
(expand (fetch-file ,sqlite-db-conn))))
|
||||||
(source
|
(source
|
||||||
|
@ -40,12 +40,12 @@
|
|||||||
|
|
||||||
;; in other cases follow user directive
|
;; in other cases follow user directive
|
||||||
(t *identifier-case*))))
|
(t *identifier-case*))))
|
||||||
|
|
||||||
(ecase *identifier-case*
|
(ecase *identifier-case*
|
||||||
(:downcase lowercase-identifier)
|
(:snake_case (camelCase-to-colname identifier))
|
||||||
(:quote (format nil "~s"
|
(:downcase lowercase-identifier)
|
||||||
(cl-ppcre:regex-replace-all "\"" identifier "\"\"")))
|
(:quote (format nil "~s"
|
||||||
(:none identifier))))
|
(cl-ppcre:regex-replace-all "\"" identifier "\"\"")))
|
||||||
|
(:none identifier))))
|
||||||
|
|
||||||
(defun ensure-unquoted (identifier)
|
(defun ensure-unquoted (identifier)
|
||||||
(cond ((quoted-p identifier)
|
(cond ((quoted-p identifier)
|
||||||
@ -68,3 +68,23 @@
|
|||||||
(string part)
|
(string part)
|
||||||
(t (princ-to-string part))))
|
(t (princ-to-string part))))
|
||||||
:when more? :collect sep))))
|
:when more? :collect sep))))
|
||||||
|
|
||||||
|
;;;
|
||||||
|
;;; Camel Case converter
|
||||||
|
;;;
|
||||||
|
(defun camelCase-to-colname (string)
|
||||||
|
"Transform input STRING into a suitable column name.
|
||||||
|
lahmanID lahman_id
|
||||||
|
playerID player_id
|
||||||
|
birthYear birth_year"
|
||||||
|
(coerce
|
||||||
|
(loop
|
||||||
|
:for first := t :then nil
|
||||||
|
:for char :across string
|
||||||
|
:for previous-upper-p := nil :then char-upper-p
|
||||||
|
:for char-upper-p := (and (alpha-char-p char)
|
||||||
|
(eq char (char-upcase char)))
|
||||||
|
:for new-word := (and (not first) char-upper-p (not previous-upper-p))
|
||||||
|
:when (and new-word (not (char= char #\_))) :collect #\_
|
||||||
|
:collect (char-downcase char))
|
||||||
|
'string))
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
;; needed in create index specific kernels
|
;; needed in create index specific kernels
|
||||||
(*pgsql-reserved-keywords* . ',*pgsql-reserved-keywords*)
|
(*pgsql-reserved-keywords* . ',*pgsql-reserved-keywords*)
|
||||||
(*preserve-index-names* . ,*preserve-index-names*)
|
(*preserve-index-names* . ,*preserve-index-names*)
|
||||||
|
(*identifier-case* . ,*identifier-case*)
|
||||||
|
|
||||||
;; bindings updates for libs
|
;; bindings updates for libs
|
||||||
;; CFFI is used by the SQLite lib
|
;; CFFI is used by the SQLite lib
|
||||||
|
@ -3,25 +3,6 @@
|
|||||||
;;;
|
;;;
|
||||||
(in-package :pgloader.utils)
|
(in-package :pgloader.utils)
|
||||||
|
|
||||||
;;;
|
|
||||||
;;; Camel Case converter
|
|
||||||
;;;
|
|
||||||
(defun camelCase-to-colname (string)
|
|
||||||
"Transform input STRING into a suitable column name.
|
|
||||||
lahmanID lahman_id
|
|
||||||
playerID player_id
|
|
||||||
birthYear birth_year"
|
|
||||||
(coerce
|
|
||||||
(loop
|
|
||||||
for first = t then nil
|
|
||||||
for char across string
|
|
||||||
for previous-upper-p = nil then char-upper-p
|
|
||||||
for char-upper-p = (eq char (char-upcase char))
|
|
||||||
for new-word = (and (not first) char-upper-p (not previous-upper-p))
|
|
||||||
when (and new-word (not (char= char #\_))) collect #\_
|
|
||||||
collect (char-downcase char))
|
|
||||||
'string))
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Unquote SQLite default values, might be useful elsewhere
|
;;; Unquote SQLite default values, might be useful elsewhere
|
||||||
;;;
|
;;;
|
||||||
|
@ -3,6 +3,7 @@ load database
|
|||||||
into postgresql:///pgloader
|
into postgresql:///pgloader
|
||||||
|
|
||||||
-- with include drop, create tables, create indexes, reset sequences
|
-- with include drop, create tables, create indexes, reset sequences
|
||||||
|
with snake_case identifiers
|
||||||
|
|
||||||
before load do
|
before load do
|
||||||
$$ drop schema if exists sqlite cascade; $$,
|
$$ drop schema if exists sqlite cascade; $$,
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user