diff --git a/dialects/oracle/oracle.go b/dialects/oracle/oracle.go index 4ddb1a3e..811c0173 100644 --- a/dialects/oracle/oracle.go +++ b/dialects/oracle/oracle.go @@ -7,6 +7,7 @@ import ( "strconv" "strings" "time" + "github.com/jinzhu/gorm" _ "github.com/mattn/go-oci8" ) @@ -38,6 +39,9 @@ func (oracle) BindVar(i int) string { } func (oracle) Quote(key string) string { + if isReserved(key) { + return fmt.Sprintf(`"%s"`, key) + } return key } @@ -68,9 +72,9 @@ func (s oracle) HasForeignKey(tableName string, foreignKeyName string) bool { foreignKeyName = strings.ToUpper(foreignKeyName) if err := s.db.QueryRow(`SELECT count(*) FROM USER_CONSTRAINTS WHERE CONSTRAINT_NAME = :1 AND constraint_type = 'R' AND table_name = :2`, foreignKeyName, tableName).Scan(&count); err == nil { - return count > 0 - } - return false + return count > 0 + } + return false } func (s oracle) HasIndex(tableName string, indexName string) bool { @@ -89,7 +93,7 @@ func (s oracle) HasTable(tableName string) bool { tableName = strings.ToUpper(tableName) if err := s.db.QueryRow("select count(*) from user_tables where table_name = :1", tableName).Scan(&count); err == nil { return count > 0 - } + } return false } diff --git a/dialects/oracle/reserved.go b/dialects/oracle/reserved.go new file mode 100644 index 00000000..f679ec34 --- /dev/null +++ b/dialects/oracle/reserved.go @@ -0,0 +1,167 @@ +package oracle + +import ( + "strings" + "sync" +) + +const reserved = `AGGREGATE +AGGREGATES +ALL +ALLOW +ANALYZE +ANCESTOR +AND +ANY +AS +ASC +AT +AVG +BETWEEN +BINARY_DOUBLE +BINARY_FLOAT +BLOB +BRANCH +BUILD +BY +BYTE +CASE +CAST +CHAR +CHILD +CLEAR +CLOB +COMMIT +COMPILE +CONSIDER +COUNT +DATATYPE +DATE +DATE_MEASURE +DAY +DECIMAL +DELETE +DESC +DESCENDANT +DIMENSION +DISALLOW +DIVISION +DML +ELSE +END +ESCAPE +EXECUTE +FIRST +FLOAT +FOR +FROM +HIERARCHIES +HIERARCHY +HOUR +IGNORE +IN +INFINITE +INSERT +INTEGER +INTERVAL +INTO +IS +LAST +LEAF_DESCENDANT +LEAVES +LEVEL +LEVELS +LIKE +LIKEC +LIKE2 +LIKE4 +LOAD +LOCAL +LOG_SPEC +LONG +MAINTAIN +MAX +MEASURE +MEASURES +MEMBER +MEMBERS +MERGE +MLSLABEL +MIN +MINUTE +MODEL +MONTH +NAN +NCHAR +NCLOB +NO +NONE +NOT +NULL +NULLS +NUMBER +NVARCHAR2 +OF +OLAP +OLAP_DML_EXPRESSION +ON +ONLY +OPERATOR +OR +ORDER +OVER +OVERFLOW +PARALLEL +PARENT +PLSQL +PRUNE +RAW +RELATIVE +ROOT_ANCESTOR +ROWID +SCN +SECOND +SELF +SERIAL +SET +SOLVE +SOME +SORT +SPEC +SUM +SYNCH +TEXT_MEASURE +THEN +TIME +TIMESTAMP +TO +UNBRANCH +UPDATE +USING +VALIDATE +VALUES +VARCHAR2 +WHEN +WHERE +WITHIN +WITH +YEAR +ZERO +ZONE` + +var setupReserved sync.Once +var reservedWords map[string]struct{} + +func isReserved(w string) bool { + setupReserved.Do( + func() { + words := strings.Split(reserved, "\n") + reservedWords = make(map[string]struct{}, len(words)) + for _, s := range words { + reservedWords[s] = struct{}{} + } + }, + ) + _, ok := reservedWords[strings.ToUpper(w)] + return ok +}