Skip to content

Commit 9c01e0c

Browse files
authored
Merge pull request #22 from oracle/issue-21
Issue 21
2 parents d7639ba + aceb598 commit 9c01e0c

File tree

13 files changed

+1087
-1036
lines changed

13 files changed

+1087
-1036
lines changed

.vscode/launch.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"type": "node",
6+
"request": "launch",
7+
"name": "Launch Program",
8+
"skipFiles": [
9+
"<node_internals>/**"
10+
],
11+
"program": "${file}"
12+
}
13+
]
14+
}

dist/quick-erd.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ class de {
739739
e.rearrangeDiagram(3, !1), this.paperScroller.centerContent();
740740
}
741741
}
742-
const ue = "1.1.4", fe = {
742+
const ue = "1.1.5", fe = {
743743
Diagram: de,
744744
version: ue
745745
};

dist/quick-erd.umd.cjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dist/quick-sql.js

Lines changed: 806 additions & 794 deletions
Large diffs are not rendered by default.

dist/quick-sql.umd.cjs

Lines changed: 119 additions & 119 deletions
Large diffs are not rendered by default.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@oracle/quicksql",
3-
"version": "1.1.4",
3+
"version": "1.1.5",
44
"description": "Quick SQL to DDL and ERD translator",
55
"main": "./dist/quick-sql.umd.cjs",
66
"module": "./dist/quick-sql.js",

src/ddl.js

Lines changed: 5 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import tree from './tree.js';
88
import lexer from './lexer.js';
99
import json2qsql from './json2qsql.js'
1010
import errorMsgs from './errorMsgs.js'
11+
import {canonicalObjectName} from './naming.js'
1112

1213
const ddl = (function () {
1314
function DDL() {
@@ -51,6 +52,9 @@ const ddl = (function () {
5152
this.options = JSON.parse(JSON.stringify(this.defaultOptions));
5253
this.forest = null;
5354

55+
this
56+
57+
5458
this.normalize = function( iNput ) {
5559
if( iNput == null )
5660
return null;
@@ -143,86 +147,13 @@ const ddl = (function () {
143147
var descendants = this.forest[i].descendants();
144148
for( var j = 0; j < descendants.length; j++ ) {
145149
var node = descendants[j];
146-
if( node.parseName() == this.canonicalObjectName(name) )
150+
if( node.parseName() == canonicalObjectName(name) )
147151
return node;
148152
}
149153
}
150154
return null;
151155
};
152156

153-
this.canonicalObjectName = function( nAme ) {
154-
if( nAme == null )
155-
return null;
156-
if( nAme.indexOf('"') == 0 )
157-
return nAme;
158-
let possiblyQuoted = this.quoteIdentifier(nAme);
159-
if( possiblyQuoted.indexOf('"') == 0 )
160-
return possiblyQuoted;
161-
possiblyQuoted = possiblyQuoted.replace(/ /g,"_");
162-
return possiblyQuoted;
163-
};
164-
/**
165-
* Ported from dbtools-common Service.quoteIdentifier() and AMENDED for QSQL usage
166-
* Diffs: 1. Space separator does not warrant double quote
167-
* 2. Lower case letters do not warrant double quote
168-
*
169-
* Quotes an identifier based on the following:
170-
* 1) Any lower/mixed case identifier is quoted
171-
* 2) Any identifier starting with the quote string is NOT quoted. If it is currently quoted (first/last characters
172-
* are the quote character) then no quoting is needed, and if it not quoted but contains a quote character, the name is
173-
* invalid.
174-
* 3) The string is checked for invalid characters; any invalid characters require the string be quoted. A valid identifier
175-
* starts with a letter and contains only letters, digits, or one of _$#. Note that the database allows any valid character
176-
* in the database character set. We by policy use the basic ASCII character set to determine letters.
177-
*
178-
* Conflicting requirements:
179-
* - SYS.DBMS_SQLTUNE.ACCEPT_ALL_SQL_PROFILES composite object names shouldn't be quoted
180-
* - Bug 20667620: weird column name "NO." should
181-
* @param s
182-
* @param quoteChar
183-
* @return
184-
*/
185-
this.quoteIdentifier = function(/*String*/ s, /*char*/ quoteChar ) {
186-
let quoteString = '"'; //String.valueOf(quoteChar);
187-
if( s == null ) // to be able to safely wrap any string value
188-
return null;
189-
190-
// We want to check 3 things here:
191-
// 1) The string is a valid identifier (starts with a letter, contains only valid characters,--!!!-- don't care if a reserved word
192-
// 2) The string is all upper case. By policy, we will quote any lower or mixed cased strings
193-
// 3) the string is not currently quoted. We will only check the first character for a quote. A quote appearing anywhere
194-
// else or a starting quote w/o an ending quote is going to make the string invalid no matter what (quotes cannot
195-
// be escaped in Oracle identifiers).
196-
let quote = false;
197-
// Bug 9215024 column name can have "_" so we can't exclude them.
198-
// ^^^^^^^^^^
199-
// Edit Wars: the loop below iterates through list of characters, and as soon
200-
// it encounters illegitimate symbol, it sets the "need quotation" flag
201-
const legitimateChars = "$#_ "; // !NO ".": see this function JavaDoc above
202-
if ( !s.startsWith(quoteString) && !quote ) {
203-
const chars = s; //new char[s.length()];
204-
//s.getChars(0, chars.length, chars, 0);
205-
if( chars.length > 0 && '0' <= chars[0] && chars[0] <= '9' )
206-
quote = true;
207-
else for ( let i in chars ) {
208-
const c = chars[i];
209-
if( legitimateChars.indexOf(c) < 0 && (
210-
c < '0' || '9' < c && c < 'A' || 'Z' < c && c < 'a' || 'z' < c
211-
)) {
212-
quote = true;
213-
break;
214-
}
215-
// wierd case with double quote inside
216-
// ...
217-
}
218-
}
219-
if( s.startsWith("_") || s.startsWith("$") || s.startsWith("#") )
220-
quote = true;
221-
if( !quote )
222-
quoteString = '';
223-
return quoteString+s+quoteString;
224-
}
225-
226157

227158
/**
228159
* @param {*} input

src/json2qsql.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import singular from './singular.js';
1+
import {singular} from './naming.js';
22
import ddl from "../src/ddl.js";
33

44

src/naming.js

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
export function singular( name ) {
2+
// ddl.options["Duality View"].value != 'yes'
3+
// identity columns in JSON document are singular
4+
if( name == null )
5+
return name;
6+
if( name.toUpperCase().endsWith('IES') )
7+
return name.substring(0,name.length-3)+'y';
8+
if( name.toUpperCase().endsWith('ES') )
9+
return name.substring(0,name.length-1);
10+
if( name.toUpperCase().endsWith('S') )
11+
return name.substring(0,name.length-1);
12+
return name;
13+
}
14+
15+
/**
16+
* Ported from dbtools-common Service.quoteIdentifier() and AMENDED for QSQL usage
17+
* Diffs: 1. Space separator does not warrant double quote
18+
* 2. Lower case letters do not warrant double quote
19+
*
20+
* Quotes an identifier based on the following:
21+
* 1) Any lower/mixed case identifier is quoted
22+
* 2) Any identifier starting with the quote string is NOT quoted. If it is currently quoted (first/last characters
23+
* are the quote character) then no quoting is needed, and if it not quoted but contains a quote character, the name is
24+
* invalid.
25+
* 3) The string is checked for invalid characters; any invalid characters require the string be quoted. A valid identifier
26+
* starts with a letter and contains only letters, digits, or one of _$#. Note that the database allows any valid character
27+
* in the database character set. We by policy use the basic ASCII character set to determine letters.
28+
*
29+
* Conflicting requirements:
30+
* - SYS.DBMS_SQLTUNE.ACCEPT_ALL_SQL_PROFILES composite object names shouldn't be quoted
31+
* - Bug 20667620: weird column name "NO." should
32+
* @param s
33+
* @param quoteChar
34+
* @return
35+
*/
36+
function quoteIdentifier(/*String*/ s, /*char*/ quoteChar ) {
37+
let quoteString = '"'; //String.valueOf(quoteChar);
38+
if( s == null ) // to be able to safely wrap any string value
39+
return null;
40+
41+
// We want to check 3 things here:
42+
// 1) The string is a valid identifier (starts with a letter, contains only valid characters,--!!!-- don't care if a reserved word
43+
// 2) The string is all upper case. By policy, we will quote any lower or mixed cased strings
44+
// 3) the string is not currently quoted. We will only check the first character for a quote. A quote appearing anywhere
45+
// else or a starting quote w/o an ending quote is going to make the string invalid no matter what (quotes cannot
46+
// be escaped in Oracle identifiers).
47+
let quote = false;
48+
// Bug 9215024 column name can have "_" so we can't exclude them.
49+
// ^^^^^^^^^^
50+
// Edit Wars: the loop below iterates through list of characters, and as soon
51+
// it encounters illegitimate symbol, it sets the "need quotation" flag
52+
const legitimateChars = "$#_ "; // !NO ".": see this function JavaDoc above
53+
if ( !s.startsWith(quoteString) && !quote ) {
54+
const chars = s; //new char[s.length()];
55+
//s.getChars(0, chars.length, chars, 0);
56+
if( chars.length > 0 && '0' <= chars[0] && chars[0] <= '9' )
57+
quote = true;
58+
else for ( let i in chars ) {
59+
const c = chars[i];
60+
if( legitimateChars.indexOf(c) < 0 && (
61+
c < '0' || '9' < c && c < 'A' || 'Z' < c && c < 'a' || 'z' < c
62+
)) {
63+
quote = true;
64+
break;
65+
}
66+
// wierd case with double quote inside
67+
// ...
68+
}
69+
}
70+
if( s.startsWith("_") || s.startsWith("$") || s.startsWith("#") )
71+
quote = true;
72+
if( !quote )
73+
quoteString = '';
74+
return quoteString+s+quoteString;
75+
}
76+
77+
export function canonicalObjectName( nAme ) {
78+
if( nAme == null )
79+
return null;
80+
if( nAme.indexOf('"') == 0 )
81+
return nAme;
82+
let possiblyQuoted = quoteIdentifier(nAme);
83+
if( possiblyQuoted.indexOf('"') == 0 )
84+
return possiblyQuoted;
85+
possiblyQuoted = possiblyQuoted.replace(/ /g,"_");
86+
return possiblyQuoted;
87+
};
88+
89+
90+
export function concatNames(chunk1, chunk2, chunk3) {
91+
let quote = false;
92+
if( chunk3 == null )
93+
chunk3 = '';
94+
if( 0 == chunk1.indexOf('"') ) {
95+
quote = true;
96+
chunk1 = chunk1.substring(1,chunk1.length-1);
97+
}
98+
if( 0 == chunk2.indexOf('"') ) {
99+
quote = true;
100+
chunk2 = chunk2.substring(1,chunk2.length-1);
101+
}
102+
if( 0 == chunk3.indexOf('"') ) {
103+
quote = true;
104+
chunk3 = chunk3.substring(1,chunk3.length-1);
105+
}
106+
let ret = chunk1+chunk2+chunk3;
107+
if( quote )
108+
ret = '"'+ret+'"';
109+
else
110+
ret = ret.toLowerCase();
111+
112+
return ret;
113+
}
114+
115+
116+
export default {singular, canonicalObjectName, concatNames};

src/singular.js

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)