Skip to content

Commit

Permalink
Correctly handle table and column names containing whitespace and pun…
Browse files Browse the repository at this point in the history
…ctuation
  • Loading branch information
Stefano Da Ros committed Jun 20, 2019
1 parent c53b77f commit 7568c07
Show file tree
Hide file tree
Showing 9 changed files with 314 additions and 143 deletions.
11 changes: 11 additions & 0 deletions build/migrate-to-mysql.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ CREATE TABLE IF NOT EXISTS one_rows (
INSERT INTO one_rows (name)
VALUES
("TESTNAME");
CREATE TABLE IF NOT EXISTS \`funny column names\` (
id INT NOT NULL AUTO_INCREMENT,
jack_bob text,
\`cup smith\` text,
\`bent.ski;\` text,
\`utf8 string ڣ\` text,
primary key (id)
);
INSERT INTO \`funny column names\` (\`cup smith\`, \`bent.ski;\`, \`utf8 string ڣ\`)
VALUES
("foo", "bar", "baz");
CREATE TABLE IF NOT EXISTS equipment (
id INT NOT NULL AUTO_INCREMENT,
name text,
Expand Down
93 changes: 54 additions & 39 deletions build/migrate-to-oracle.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#!/usr/bin/env sh
# Refer to https://github.com/oracle/docker-images/tree/master/OracleDatabase/SingleInstance
# for instructions on how to setup the a test oracle DB in a docker container
set -x

ORACLE_HOST=${ORACLE_HOST:=localhost}
Expand All @@ -16,13 +18,14 @@ then
fi
cat << __EOF__ | sqlplus ${ORACLE_USER}/${ORACLE_PASSWORD}@${ORACLE_HOST}/${ORACLE_DATABASE}
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE zero_rows';
EXECUTE IMMEDIATE 'DROP TABLE one_rows';
EXECUTE IMMEDIATE 'DROP TABLE ingredient_recipe';
EXECUTE IMMEDIATE 'DROP TABLE inventory';
EXECUTE IMMEDIATE 'DROP TABLE ingredients';
EXECUTE IMMEDIATE 'DROP TABLE recipes';
EXECUTE IMMEDIATE 'DROP TABLE equipment';
EXECUTE IMMEDIATE 'DROP TABLE "zero_rows" CASCADE CONSTRAINTS';
EXECUTE IMMEDIATE 'DROP TABLE "one_rows" CASCADE CONSTRAINTS';
EXECUTE IMMEDIATE 'DROP TABLE "funny column names" CASCADE CONSTRAINTS';
EXECUTE IMMEDIATE 'DROP TABLE "ingredient_recipe" CASCADE CONSTRAINTS';
EXECUTE IMMEDIATE 'DROP TABLE "inventory" CASCADE CONSTRAINTS';
EXECUTE IMMEDIATE 'DROP TABLE "ingredients" CASCADE CONSTRAINTS';
EXECUTE IMMEDIATE 'DROP TABLE "recipes" CASCADE CONSTRAINTS';
EXECUTE IMMEDIATE 'DROP TABLE "equipment" CASCADE CONSTRAINTS';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
Expand All @@ -31,102 +34,114 @@ END IF;
END;
/
CREATE TABLE zero_rows (
CREATE TABLE "zero_rows" (
"id" integer generated by default as identity,
"name" nvarchar2(256),
primary key ("id")
);
CREATE TABLE one_rows (
CREATE TABLE "one_rows" (
"id" integer generated by default as identity,
"name" nvarchar2(256),
primary key ("id")
);
INSERT INTO one_rows ("name")
INSERT INTO "one_rows" ("name")
VALUES
('TESTNAME');
CREATE TABLE equipment (
CREATE TABLE "funny column names" (
"id" integer generated by default as identity,
"jack_bob" nvarchar2(256),
"cup smith" nvarchar2(256),
"bent.ski;" nvarchar2(256),
"utf8 string ڣ" nvarchar2(256),
primary key ("id")
);
INSERT INTO "funny column names" ("cup smith", "bent.ski;", "utf8 string ڣ")
VALUES
('foo', 'bar', 'baz');
CREATE TABLE "equipment" (
"id" integer generated by default as identity,
"name" nvarchar2(256),
"acquisition_cost" number(10,5),
"purchase_date" timestamp(3) with time zone,
primary key ("id")
);
INSERT INTO equipment ("name", "acquisition_cost", "purchase_date")
INSERT INTO "equipment" ("name", "acquisition_cost", "purchase_date")
VALUES ('Bialetti Moka Express 6 cup',25.95,to_timestamp_tz('2017-12-11T12:00:00.123+00:00', 'YYYY-MM-DD"T"HH24:MI:SSXFFTZH:TZM'));
INSERT INTO equipment ("name", "acquisition_cost", "purchase_date")
INSERT INTO "equipment" ("name", "acquisition_cost", "purchase_date")
VALUES ('Sanremo Café Racer',8477.85,to_timestamp_tz('2017-12-12T12:00:00.123000+00:00', 'YYYY-MM-DD"T"HH24:MI:SSXFFTZH:TZM'));
INSERT INTO equipment ("name", "acquisition_cost", "purchase_date")
INSERT INTO "equipment" ("name", "acquisition_cost", "purchase_date")
VALUES ('Buntfink SteelKettle',39.95,to_timestamp_tz('2017-12-12T12:00:00.000+00:00', 'YYYY-MM-DD"T"HH24:MI:SSXFFTZH:TZM'));
INSERT INTO equipment ("name", "acquisition_cost", "purchase_date")
INSERT INTO "equipment" ("name", "acquisition_cost", "purchase_date")
VALUES ('Copper Coffee Pot Cezve',49.95,to_timestamp_tz('2017-12-12T12:00:00.000+00:00', 'YYYY-MM-DD"T"HH24:MI:SSXFFTZH:TZM'));
CREATE TABLE ingredients (
CREATE TABLE "ingredients" (
"id" integer generated by default as identity,
"name" nvarchar2(1024),
"description" nvarchar2(1024),
primary key ("id")
);
INSERT INTO ingredients ("name","description")
INSERT INTO "ingredients" ("name","description")
VALUES ('V60 paper filter', 'The best paper filter on the market');
INSERT INTO ingredients ("name","description")
INSERT INTO "ingredients" ("name","description")
VALUES ('Caffé Borbone Beans - Miscela Blu', 'Excellent beans for espresso');
INSERT INTO ingredients ("name","description")
INSERT INTO "ingredients" ("name","description")
VALUES ('Caffé Borbone Beans - Miscela Oro', 'Well balanced beans');
INSERT INTO ingredients ("name","description")
INSERT INTO "ingredients" ("name","description")
VALUES ('Filtered Water', 'Contains the perfect water hardness for espresso');
CREATE TABLE inventory (
CREATE TABLE "inventory" (
"ingredient_id" number,
"quantity" number,
"unit_of_measure" nvarchar2(256),
foreign key ("ingredient_id") references ingredients("id"),
foreign key ("ingredient_id") references "ingredients"("id"),
primary key ("ingredient_id")
);
INSERT INTO inventory ("ingredient_id", "quantity", "unit_of_measure")
INSERT INTO "inventory" ("ingredient_id", "quantity", "unit_of_measure")
VALUES (1, 100, 'Each');
INSERT INTO inventory ("ingredient_id", "quantity", "unit_of_measure")
INSERT INTO "inventory" ("ingredient_id", "quantity", "unit_of_measure")
VALUES (2, 10000, 'Gram');
INSERT INTO inventory ("ingredient_id", "quantity", "unit_of_measure")
INSERT INTO "inventory" ("ingredient_id", "quantity", "unit_of_measure")
VALUES (3, 5000, 'Gram');
INSERT INTO inventory ("ingredient_id", "quantity", "unit_of_measure")
INSERT INTO "inventory" ("ingredient_id", "quantity", "unit_of_measure")
VALUES (4, 100, 'Liter');
CREATE TABLE recipes (
CREATE TABLE "recipes" (
"id" integer generated by default as identity,
"equipment_id" number,
"name" nvarchar2(1024),
"instructions" nvarchar2(1024),
"creation_date" timestamp(3),
"last_accessed" date,
"last_modified" timestamp(6) with time zone,
foreign key ("equipment_id") references equipment("id"),
foreign key ("equipment_id") references "equipment"("id"),
primary key ("id")
);
INSERT INTO recipes ("name", "instructions", "equipment_id", "creation_date", "last_accessed", "last_modified")
INSERT INTO "recipes" ("name", "instructions", "equipment_id", "creation_date", "last_accessed", "last_modified")
VALUES ('Espresso single shot','do this', 2, to_timestamp('2017-12-13T00:00:00.000', 'YYYY-MM-DD"T"HH24:MI:SSXFF3'), to_date('00:00:01', 'HH24:MI:SS'), to_timestamp_tz('2017-12-14T00:00:00.123+00:00', 'YYYY-MM-DD"T"HH24:MI:SSXFFTZH:TZM'));
INSERT INTO recipes ("name", "instructions", "equipment_id", "creation_date", "last_accessed", "last_modified")
INSERT INTO "recipes" ("name", "instructions", "equipment_id", "creation_date", "last_accessed", "last_modified")
VALUES ('Ibrik (turkish) coffee', 'do that', 4, to_timestamp('2017-12-13T00:00:00.000', 'YYYY-MM-DD"T"HH24:MI:SSXFF3'), to_date('00:00:02', 'HH24:MI:SS'), to_timestamp_tz('2017-12-14T00:00:00.123456+00:00', 'YYYY-MM-DD"T"HH24:MI:SSXFFTZH:TZM'));
INSERT INTO recipes ("name", "instructions", "equipment_id", "creation_date", "last_accessed", "last_modified")
INSERT INTO "recipes" ("name", "instructions", "equipment_id", "creation_date", "last_accessed", "last_modified")
VALUES ('Filter coffee', 'do bar', 3, to_timestamp('2017-12-13T00:00:00.000', 'YYYY-MM-DD"T"HH24:MI:SSXFF3'), to_date('12:00:00', 'HH24:MI:SS'), to_timestamp_tz('2017-12-14T00:00:00.000+00:00', 'YYYY-MM-DD"T"HH24:MI:SSXFFTZH:TZM'));
CREATE TABLE ingredient_recipe (
CREATE TABLE "ingredient_recipe" (
"id" integer generated by default as identity,
"ingredient_id" number not null,
"recipe_id" number not null,
"quantity" number,
"unit_of_measure" nvarchar2(1024),
foreign key ("ingredient_id") references ingredients("id"),
foreign key ("recipe_id") references recipes("id"),
foreign key ("ingredient_id") references "ingredients"("id"),
foreign key ("recipe_id") references "recipes"("id"),
primary key ("ingredient_id", "recipe_id")
);
INSERT INTO ingredient_recipe ("id", "ingredient_id", "recipe_id", "quantity", "unit_of_measure")
INSERT INTO "ingredient_recipe" ("id", "ingredient_id", "recipe_id", "quantity", "unit_of_measure")
VALUES (1, 2, 3, 30, 'Gram');
INSERT INTO ingredient_recipe ("id", "ingredient_id", "recipe_id", "quantity", "unit_of_measure")
INSERT INTO "ingredient_recipe" ("id", "ingredient_id", "recipe_id", "quantity", "unit_of_measure")
VALUES (2, 1, 3, 1, 'Each');
INSERT INTO ingredient_recipe ("id", "ingredient_id", "recipe_id", "quantity", "unit_of_measure")
INSERT INTO "ingredient_recipe" ("id", "ingredient_id", "recipe_id", "quantity", "unit_of_measure")
VALUES (3, 4, 3, 0.5, 'Liter');
INSERT INTO ingredient_recipe ("id", "ingredient_id", "recipe_id", "quantity", "unit_of_measure")
INSERT INTO "ingredient_recipe" ("id", "ingredient_id", "recipe_id", "quantity", "unit_of_measure")
VALUES (4, 3, 2, 20, 'Gram');
INSERT INTO ingredient_recipe ("id", "ingredient_id", "recipe_id", "quantity", "unit_of_measure")
INSERT INTO "ingredient_recipe" ("id", "ingredient_id", "recipe_id", "quantity", "unit_of_measure")
VALUES (5, 4, 2, 0.15, 'Liter');
__EOF__
15 changes: 13 additions & 2 deletions build/migrate-to-postgres.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ SET timezone='CET';
SET ROLE ${POSTGRES_USER};
DROP TABLE IF EXISTS zero_rows;
DROP TABLE IF EXISTS one_rows;
DROP TABLE IF EXISTS "funny column names";
DROP TABLE IF EXISTS ingredient_recipe;
DROP TABLE IF EXISTS inventory;
DROP TABLE IF EXISTS ingredients;
Expand All @@ -52,7 +53,17 @@ CREATE TABLE IF NOT EXISTS one_rows (
INSERT INTO one_rows (name)
VALUES
('TESTNAME');
CREATE TABLE IF NOT EXISTS "funny column names" (
id serial,
jack_bob text,
"cup smith" text,
"bent.ski;" text,
"utf8 string ڣ" text,
primary key (id)
);
INSERT INTO "funny column names" ("cup smith", "bent.ski;", "utf8 string ڣ")
VALUES
('foo', 'bar', 'baz');
CREATE TABLE IF NOT EXISTS equipment (
id serial,
name text,
Expand All @@ -65,7 +76,7 @@ CREATE TABLE IF NOT EXISTS equipment (
id serial,
name text,
acquisition_cost decimal(10,5),
purchase_date timestamp(3),
purchase_date timestamp(3) null,
primary key (id)
);
INSERT INTO equipment (name, acquisition_cost, purchase_date)
Expand Down
53 changes: 53 additions & 0 deletions config/descriptor.json
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,59 @@
],
"optionsAvailable" : true,
"fetchOneAvailable" : true
},
{
"key" : "funnyColumnNames",
"name" : "Table containing strange column names",
"tableName": "funny column names",
"columnAsOptionName": "cup smith",
"uniqueIdColumn": "id",
"recordType": "value",
"parameters": [],
"fields" : [
{
"key" : "id",
"name" : "ID",
"fromColumn" : "id",
"type" : {
"name" : "text"
}
},
{
"key" : "jackBob",
"name" : "jackBob",
"fromColumn" : "jack_bob",
"type" : {
"name" : "text"
}
},
{
"key" : "cupSmith",
"name" : "cup smith",
"fromColumn" : "cup smith",
"type" : {
"name" : "text"
}
},
{
"key" : "bentSki",
"name" : "bent ski",
"fromColumn" : "bent.ski;",
"type" : {
"name" : "text"
}
},
{
"key" : "utf8String",
"name" : "utf8 string ڣ",
"fromColumn" : "utf8 string ڣ",
"type" : {
"name" : "text"
}
}
],
"optionsAvailable" : true,
"fetchOneAvailable" : true
}
],
"version": 1,
Expand Down
3 changes: 3 additions & 0 deletions internal/app/backend/createSingle.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ func (b *Backend) CreateSingle(rw http.ResponseWriter, req *http.Request) {
http.Error(rw, msg.Error(), http.StatusBadRequest)
return
}
log.When(config.Options.Logging).Infoln(queryString)

log.When(config.Options.Logging).Infoln("[handler -> db] get query results")
result, err := b.ExecContext(req.Context(), queryString, args...)
if err != nil {
msg := &util.ResponseMessage{
Expand Down
64 changes: 32 additions & 32 deletions internal/pkg/sql/mysql/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,46 +17,46 @@ const (
var (
QueryTemplates = map[string]string{
"GetSingle": "SELECT * " +
"FROM {{.TableName}} AS _{{.TableName}}" +
"FROM `{{.TableName}}` AS `_{{.TableName}}`" +
"{{range .Relations}}" +
" LEFT JOIN {{.Relationship.WithTable}}" +
" ON {{.Relationship.WithTable}}.{{.Relationship.ForeignTableUniqueIDColumn}}" +
" = _{{$.TableName}}.{{.Relationship.LocalTableUniqueIDColumn}}" +
" LEFT JOIN `{{.Relationship.WithTable}}`" +
" ON `{{.Relationship.WithTable}}`.`{{.Relationship.ForeignTableUniqueIDColumn}}`" +
" = `_{{$.TableName}}`.`{{.Relationship.LocalTableUniqueIDColumn}}`" +
"{{end}}" +
" WHERE _{{$.TableName}}.{{.UniqueIDColumn}} = ?",
"GetSingleAsOption": "SELECT {{.UniqueIDColumn}}, {{.ColumnAsOptionName}} " +
"FROM {{.TableName}} " +
"WHERE {{.UniqueIDColumn}} = ?",
" WHERE `_{{$.TableName}}`.`{{.UniqueIDColumn}}` = ?",
"GetSingleAsOption": "SELECT `{{.UniqueIDColumn}}`, `{{.ColumnAsOptionName}}` " +
"FROM `{{.TableName}}` " +
"WHERE `{{.UniqueIDColumn}}` = ?",
"GetCollection": "SELECT * " +
"FROM {{.TableName}}",
"FROM `{{.TableName}}`",
"GetCollectionFilterable": "SELECT * " +
"FROM {{.TableName}} " +
"WHERE {{.FilterOnColumn}} {{.Operator}} ?",
"GetCollectionAsOptions": "SELECT {{.UniqueIDColumn}}, {{.ColumnAsOptionName}} " +
"FROM {{.TableName}}",
"GetCollectionAsOptionsFilterable": "SELECT {{.UniqueIDColumn}}, {{.ColumnAsOptionName}} " +
"FROM {{.TableName}} " +
"WHERE {{.ColumnAsOptionName}} LIKE ?",
"GetCollectionAsOptionsWithParams": "SELECT {{.UniqueIDColumn}}, {{.ColumnAsOptionName}} " +
"FROM {{.TableName}} " +
"WHERE {{.ColumnAsOptionName}} LIKE ? " +
`{{range $index, $element := .ColumnNames}}` +
`AND {{$element}} = ? ` +
`{{end}}`,
"UpdateSingle": "UPDATE {{.TableName}} SET {{.ColumnNames | head}}" +
" = ?{{range .ColumnNames | tail}}, {{.}} = ?{{end}} WHERE {{.UniqueIDColumn}} = ?",
"CreateSingle": "INSERT INTO {{.TableName}}({{.ColumnNames | head}}" +
"{{range .ColumnNames | tail}}, {{.}}{{end}}) " +
"FROM `{{.TableName}}` " +
"WHERE `{{.FilterOnColumn}}` {{.Operator}} ?",
"GetCollectionAsOptions": "SELECT `{{.UniqueIDColumn}}`, `{{.ColumnAsOptionName}}` " +
"FROM `{{.TableName}}`",
"GetCollectionAsOptionsFilterable": "SELECT `{{.UniqueIDColumn}}`, `{{.ColumnAsOptionName}}` " +
"FROM `{{.TableName}}` " +
"WHERE `{{.ColumnAsOptionName}}` LIKE ?",
"GetCollectionAsOptionsWithParams": "SELECT `{{.UniqueIDColumn}}`, `{{.ColumnAsOptionName}}` " +
"FROM `{{.TableName}}` " +
"WHERE `{{.ColumnAsOptionName}}` LIKE ? " +
"{{range $index, $element := .ColumnNames}}" +
"AND `{{$element}}` = ? " +
"{{end}}",
"UpdateSingle": "UPDATE `{{.TableName}}` SET `{{.ColumnNames | head}}`" +
" = ?{{range .ColumnNames | tail}}, `{{.}}` = ?{{end}} WHERE `{{.UniqueIDColumn}}` = ?",
"CreateSingle": "INSERT INTO `{{.TableName}}`(`{{.ColumnNames | head}}`" +
"{{range .ColumnNames | tail}}, `{{.}}`{{end}}) " +
"VALUES(?{{range .ColumnNames | tail}}, ?{{end}})",
"DeleteSingle": "DELETE FROM {{.TableName}} WHERE {{.UniqueIDColumn}} = ?",
"DeleteSingle": "DELETE FROM `{{.TableName}}` WHERE `{{.UniqueIDColumn}}` = ?",
"GetTableSchema": "SELECT * " +
"FROM {{.TableName}} " +
"FROM `{{.TableName}}` " +
"LIMIT 1",
"GetTableWithRelationshipsSchema": "SELECT * FROM {{.TableName}} AS _{{.TableName}}" +
"GetTableWithRelationshipsSchema": "SELECT * FROM `{{.TableName}}` AS `_{{.TableName}}`" +
"{{range .Relations}}" +
" LEFT JOIN {{.Relationship.WithTable}}" +
" ON {{.Relationship.WithTable}}.{{.Relationship.ForeignTableUniqueIDColumn}}" +
" = _{{$.TableName}}.{{.Relationship.LocalTableUniqueIDColumn}}{{end}} LIMIT 1",
" LEFT JOIN `{{.Relationship.WithTable}}`" +
" ON `{{.Relationship.WithTable}}`.`{{.Relationship.ForeignTableUniqueIDColumn}}`" +
" = `_{{$.TableName}}`.`{{.Relationship.LocalTableUniqueIDColumn}}`{{end}} LIMIT 1",
}
integer = []string{
"BIGINT",
Expand Down
Loading

0 comments on commit 7568c07

Please sign in to comment.