You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

902 lines
28 KiB

  1. // Copyright 2015 The Xorm Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package xorm
  5. import (
  6. "errors"
  7. "fmt"
  8. "regexp"
  9. "strconv"
  10. "strings"
  11. "xorm.io/core"
  12. )
  13. var (
  14. oracleReservedWords = map[string]bool{
  15. "ACCESS": true,
  16. "ACCOUNT": true,
  17. "ACTIVATE": true,
  18. "ADD": true,
  19. "ADMIN": true,
  20. "ADVISE": true,
  21. "AFTER": true,
  22. "ALL": true,
  23. "ALL_ROWS": true,
  24. "ALLOCATE": true,
  25. "ALTER": true,
  26. "ANALYZE": true,
  27. "AND": true,
  28. "ANY": true,
  29. "ARCHIVE": true,
  30. "ARCHIVELOG": true,
  31. "ARRAY": true,
  32. "AS": true,
  33. "ASC": true,
  34. "AT": true,
  35. "AUDIT": true,
  36. "AUTHENTICATED": true,
  37. "AUTHORIZATION": true,
  38. "AUTOEXTEND": true,
  39. "AUTOMATIC": true,
  40. "BACKUP": true,
  41. "BECOME": true,
  42. "BEFORE": true,
  43. "BEGIN": true,
  44. "BETWEEN": true,
  45. "BFILE": true,
  46. "BITMAP": true,
  47. "BLOB": true,
  48. "BLOCK": true,
  49. "BODY": true,
  50. "BY": true,
  51. "CACHE": true,
  52. "CACHE_INSTANCES": true,
  53. "CANCEL": true,
  54. "CASCADE": true,
  55. "CAST": true,
  56. "CFILE": true,
  57. "CHAINED": true,
  58. "CHANGE": true,
  59. "CHAR": true,
  60. "CHAR_CS": true,
  61. "CHARACTER": true,
  62. "CHECK": true,
  63. "CHECKPOINT": true,
  64. "CHOOSE": true,
  65. "CHUNK": true,
  66. "CLEAR": true,
  67. "CLOB": true,
  68. "CLONE": true,
  69. "CLOSE": true,
  70. "CLOSE_CACHED_OPEN_CURSORS": true,
  71. "CLUSTER": true,
  72. "COALESCE": true,
  73. "COLUMN": true,
  74. "COLUMNS": true,
  75. "COMMENT": true,
  76. "COMMIT": true,
  77. "COMMITTED": true,
  78. "COMPATIBILITY": true,
  79. "COMPILE": true,
  80. "COMPLETE": true,
  81. "COMPOSITE_LIMIT": true,
  82. "COMPRESS": true,
  83. "COMPUTE": true,
  84. "CONNECT": true,
  85. "CONNECT_TIME": true,
  86. "CONSTRAINT": true,
  87. "CONSTRAINTS": true,
  88. "CONTENTS": true,
  89. "CONTINUE": true,
  90. "CONTROLFILE": true,
  91. "CONVERT": true,
  92. "COST": true,
  93. "CPU_PER_CALL": true,
  94. "CPU_PER_SESSION": true,
  95. "CREATE": true,
  96. "CURRENT": true,
  97. "CURRENT_SCHEMA": true,
  98. "CURREN_USER": true,
  99. "CURSOR": true,
  100. "CYCLE": true,
  101. "DANGLING": true,
  102. "DATABASE": true,
  103. "DATAFILE": true,
  104. "DATAFILES": true,
  105. "DATAOBJNO": true,
  106. "DATE": true,
  107. "DBA": true,
  108. "DBHIGH": true,
  109. "DBLOW": true,
  110. "DBMAC": true,
  111. "DEALLOCATE": true,
  112. "DEBUG": true,
  113. "DEC": true,
  114. "DECIMAL": true,
  115. "DECLARE": true,
  116. "DEFAULT": true,
  117. "DEFERRABLE": true,
  118. "DEFERRED": true,
  119. "DEGREE": true,
  120. "DELETE": true,
  121. "DEREF": true,
  122. "DESC": true,
  123. "DIRECTORY": true,
  124. "DISABLE": true,
  125. "DISCONNECT": true,
  126. "DISMOUNT": true,
  127. "DISTINCT": true,
  128. "DISTRIBUTED": true,
  129. "DML": true,
  130. "DOUBLE": true,
  131. "DROP": true,
  132. "DUMP": true,
  133. "EACH": true,
  134. "ELSE": true,
  135. "ENABLE": true,
  136. "END": true,
  137. "ENFORCE": true,
  138. "ENTRY": true,
  139. "ESCAPE": true,
  140. "EXCEPT": true,
  141. "EXCEPTIONS": true,
  142. "EXCHANGE": true,
  143. "EXCLUDING": true,
  144. "EXCLUSIVE": true,
  145. "EXECUTE": true,
  146. "EXISTS": true,
  147. "EXPIRE": true,
  148. "EXPLAIN": true,
  149. "EXTENT": true,
  150. "EXTENTS": true,
  151. "EXTERNALLY": true,
  152. "FAILED_LOGIN_ATTEMPTS": true,
  153. "FALSE": true,
  154. "FAST": true,
  155. "FILE": true,
  156. "FIRST_ROWS": true,
  157. "FLAGGER": true,
  158. "FLOAT": true,
  159. "FLOB": true,
  160. "FLUSH": true,
  161. "FOR": true,
  162. "FORCE": true,
  163. "FOREIGN": true,
  164. "FREELIST": true,
  165. "FREELISTS": true,
  166. "FROM": true,
  167. "FULL": true,
  168. "FUNCTION": true,
  169. "GLOBAL": true,
  170. "GLOBALLY": true,
  171. "GLOBAL_NAME": true,
  172. "GRANT": true,
  173. "GROUP": true,
  174. "GROUPS": true,
  175. "HASH": true,
  176. "HASHKEYS": true,
  177. "HAVING": true,
  178. "HEADER": true,
  179. "HEAP": true,
  180. "IDENTIFIED": true,
  181. "IDGENERATORS": true,
  182. "IDLE_TIME": true,
  183. "IF": true,
  184. "IMMEDIATE": true,
  185. "IN": true,
  186. "INCLUDING": true,
  187. "INCREMENT": true,
  188. "INDEX": true,
  189. "INDEXED": true,
  190. "INDEXES": true,
  191. "INDICATOR": true,
  192. "IND_PARTITION": true,
  193. "INITIAL": true,
  194. "INITIALLY": true,
  195. "INITRANS": true,
  196. "INSERT": true,
  197. "INSTANCE": true,
  198. "INSTANCES": true,
  199. "INSTEAD": true,
  200. "INT": true,
  201. "INTEGER": true,
  202. "INTERMEDIATE": true,
  203. "INTERSECT": true,
  204. "INTO": true,
  205. "IS": true,
  206. "ISOLATION": true,
  207. "ISOLATION_LEVEL": true,
  208. "KEEP": true,
  209. "KEY": true,
  210. "KILL": true,
  211. "LABEL": true,
  212. "LAYER": true,
  213. "LESS": true,
  214. "LEVEL": true,
  215. "LIBRARY": true,
  216. "LIKE": true,
  217. "LIMIT": true,
  218. "LINK": true,
  219. "LIST": true,
  220. "LOB": true,
  221. "LOCAL": true,
  222. "LOCK": true,
  223. "LOCKED": true,
  224. "LOG": true,
  225. "LOGFILE": true,
  226. "LOGGING": true,
  227. "LOGICAL_READS_PER_CALL": true,
  228. "LOGICAL_READS_PER_SESSION": true,
  229. "LONG": true,
  230. "MANAGE": true,
  231. "MASTER": true,
  232. "MAX": true,
  233. "MAXARCHLOGS": true,
  234. "MAXDATAFILES": true,
  235. "MAXEXTENTS": true,
  236. "MAXINSTANCES": true,
  237. "MAXLOGFILES": true,
  238. "MAXLOGHISTORY": true,
  239. "MAXLOGMEMBERS": true,
  240. "MAXSIZE": true,
  241. "MAXTRANS": true,
  242. "MAXVALUE": true,
  243. "MIN": true,
  244. "MEMBER": true,
  245. "MINIMUM": true,
  246. "MINEXTENTS": true,
  247. "MINUS": true,
  248. "MINVALUE": true,
  249. "MLSLABEL": true,
  250. "MLS_LABEL_FORMAT": true,
  251. "MODE": true,
  252. "MODIFY": true,
  253. "MOUNT": true,
  254. "MOVE": true,
  255. "MTS_DISPATCHERS": true,
  256. "MULTISET": true,
  257. "NATIONAL": true,
  258. "NCHAR": true,
  259. "NCHAR_CS": true,
  260. "NCLOB": true,
  261. "NEEDED": true,
  262. "NESTED": true,
  263. "NETWORK": true,
  264. "NEW": true,
  265. "NEXT": true,
  266. "NOARCHIVELOG": true,
  267. "NOAUDIT": true,
  268. "NOCACHE": true,
  269. "NOCOMPRESS": true,
  270. "NOCYCLE": true,
  271. "NOFORCE": true,
  272. "NOLOGGING": true,
  273. "NOMAXVALUE": true,
  274. "NOMINVALUE": true,
  275. "NONE": true,
  276. "NOORDER": true,
  277. "NOOVERRIDE": true,
  278. "NOPARALLEL": true,
  279. "NOREVERSE": true,
  280. "NORMAL": true,
  281. "NOSORT": true,
  282. "NOT": true,
  283. "NOTHING": true,
  284. "NOWAIT": true,
  285. "NULL": true,
  286. "NUMBER": true,
  287. "NUMERIC": true,
  288. "NVARCHAR2": true,
  289. "OBJECT": true,
  290. "OBJNO": true,
  291. "OBJNO_REUSE": true,
  292. "OF": true,
  293. "OFF": true,
  294. "OFFLINE": true,
  295. "OID": true,
  296. "OIDINDEX": true,
  297. "OLD": true,
  298. "ON": true,
  299. "ONLINE": true,
  300. "ONLY": true,
  301. "OPCODE": true,
  302. "OPEN": true,
  303. "OPTIMAL": true,
  304. "OPTIMIZER_GOAL": true,
  305. "OPTION": true,
  306. "OR": true,
  307. "ORDER": true,
  308. "ORGANIZATION": true,
  309. "OSLABEL": true,
  310. "OVERFLOW": true,
  311. "OWN": true,
  312. "PACKAGE": true,
  313. "PARALLEL": true,
  314. "PARTITION": true,
  315. "PASSWORD": true,
  316. "PASSWORD_GRACE_TIME": true,
  317. "PASSWORD_LIFE_TIME": true,
  318. "PASSWORD_LOCK_TIME": true,
  319. "PASSWORD_REUSE_MAX": true,
  320. "PASSWORD_REUSE_TIME": true,
  321. "PASSWORD_VERIFY_FUNCTION": true,
  322. "PCTFREE": true,
  323. "PCTINCREASE": true,
  324. "PCTTHRESHOLD": true,
  325. "PCTUSED": true,
  326. "PCTVERSION": true,
  327. "PERCENT": true,
  328. "PERMANENT": true,
  329. "PLAN": true,
  330. "PLSQL_DEBUG": true,
  331. "POST_TRANSACTION": true,
  332. "PRECISION": true,
  333. "PRESERVE": true,
  334. "PRIMARY": true,
  335. "PRIOR": true,
  336. "PRIVATE": true,
  337. "PRIVATE_SGA": true,
  338. "PRIVILEGE": true,
  339. "PRIVILEGES": true,
  340. "PROCEDURE": true,
  341. "PROFILE": true,
  342. "PUBLIC": true,
  343. "PURGE": true,
  344. "QUEUE": true,
  345. "QUOTA": true,
  346. "RANGE": true,
  347. "RAW": true,
  348. "RBA": true,
  349. "READ": true,
  350. "READUP": true,
  351. "REAL": true,
  352. "REBUILD": true,
  353. "RECOVER": true,
  354. "RECOVERABLE": true,
  355. "RECOVERY": true,
  356. "REF": true,
  357. "REFERENCES": true,
  358. "REFERENCING": true,
  359. "REFRESH": true,
  360. "RENAME": true,
  361. "REPLACE": true,
  362. "RESET": true,
  363. "RESETLOGS": true,
  364. "RESIZE": true,
  365. "RESOURCE": true,
  366. "RESTRICTED": true,
  367. "RETURN": true,
  368. "RETURNING": true,
  369. "REUSE": true,
  370. "REVERSE": true,
  371. "REVOKE": true,
  372. "ROLE": true,
  373. "ROLES": true,
  374. "ROLLBACK": true,
  375. "ROW": true,
  376. "ROWID": true,
  377. "ROWNUM": true,
  378. "ROWS": true,
  379. "RULE": true,
  380. "SAMPLE": true,
  381. "SAVEPOINT": true,
  382. "SB4": true,
  383. "SCAN_INSTANCES": true,
  384. "SCHEMA": true,
  385. "SCN": true,
  386. "SCOPE": true,
  387. "SD_ALL": true,
  388. "SD_INHIBIT": true,
  389. "SD_SHOW": true,
  390. "SEGMENT": true,
  391. "SEG_BLOCK": true,
  392. "SEG_FILE": true,
  393. "SELECT": true,
  394. "SEQUENCE": true,
  395. "SERIALIZABLE": true,
  396. "SESSION": true,
  397. "SESSION_CACHED_CURSORS": true,
  398. "SESSIONS_PER_USER": true,
  399. "SET": true,
  400. "SHARE": true,
  401. "SHARED": true,
  402. "SHARED_POOL": true,
  403. "SHRINK": true,
  404. "SIZE": true,
  405. "SKIP": true,
  406. "SKIP_UNUSABLE_INDEXES": true,
  407. "SMALLINT": true,
  408. "SNAPSHOT": true,
  409. "SOME": true,
  410. "SORT": true,
  411. "SPECIFICATION": true,
  412. "SPLIT": true,
  413. "SQL_TRACE": true,
  414. "STANDBY": true,
  415. "START": true,
  416. "STATEMENT_ID": true,
  417. "STATISTICS": true,
  418. "STOP": true,
  419. "STORAGE": true,
  420. "STORE": true,
  421. "STRUCTURE": true,
  422. "SUCCESSFUL": true,
  423. "SWITCH": true,
  424. "SYS_OP_ENFORCE_NOT_NULL$": true,
  425. "SYS_OP_NTCIMG$": true,
  426. "SYNONYM": true,
  427. "SYSDATE": true,
  428. "SYSDBA": true,
  429. "SYSOPER": true,
  430. "SYSTEM": true,
  431. "TABLE": true,
  432. "TABLES": true,
  433. "TABLESPACE": true,
  434. "TABLESPACE_NO": true,
  435. "TABNO": true,
  436. "TEMPORARY": true,
  437. "THAN": true,
  438. "THE": true,
  439. "THEN": true,
  440. "THREAD": true,
  441. "TIMESTAMP": true,
  442. "TIME": true,
  443. "TO": true,
  444. "TOPLEVEL": true,
  445. "TRACE": true,
  446. "TRACING": true,
  447. "TRANSACTION": true,
  448. "TRANSITIONAL": true,
  449. "TRIGGER": true,
  450. "TRIGGERS": true,
  451. "TRUE": true,
  452. "TRUNCATE": true,
  453. "TX": true,
  454. "TYPE": true,
  455. "UB2": true,
  456. "UBA": true,
  457. "UID": true,
  458. "UNARCHIVED": true,
  459. "UNDO": true,
  460. "UNION": true,
  461. "UNIQUE": true,
  462. "UNLIMITED": true,
  463. "UNLOCK": true,
  464. "UNRECOVERABLE": true,
  465. "UNTIL": true,
  466. "UNUSABLE": true,
  467. "UNUSED": true,
  468. "UPDATABLE": true,
  469. "UPDATE": true,
  470. "USAGE": true,
  471. "USE": true,
  472. "USER": true,
  473. "USING": true,
  474. "VALIDATE": true,
  475. "VALIDATION": true,
  476. "VALUE": true,
  477. "VALUES": true,
  478. "VARCHAR": true,
  479. "VARCHAR2": true,
  480. "VARYING": true,
  481. "VIEW": true,
  482. "WHEN": true,
  483. "WHENEVER": true,
  484. "WHERE": true,
  485. "WITH": true,
  486. "WITHOUT": true,
  487. "WORK": true,
  488. "WRITE": true,
  489. "WRITEDOWN": true,
  490. "WRITEUP": true,
  491. "XID": true,
  492. "YEAR": true,
  493. "ZONE": true,
  494. }
  495. )
  496. type oracle struct {
  497. core.Base
  498. }
  499. func (db *oracle) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error {
  500. return db.Base.Init(d, db, uri, drivername, dataSourceName)
  501. }
  502. func (db *oracle) SqlType(c *core.Column) string {
  503. var res string
  504. switch t := c.SQLType.Name; t {
  505. case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.BigInt, core.Bool, core.Serial, core.BigSerial:
  506. res = "NUMBER"
  507. case core.Binary, core.VarBinary, core.Blob, core.TinyBlob, core.MediumBlob, core.LongBlob, core.Bytea:
  508. return core.Blob
  509. case core.Time, core.DateTime, core.TimeStamp:
  510. res = core.TimeStamp
  511. case core.TimeStampz:
  512. res = "TIMESTAMP WITH TIME ZONE"
  513. case core.Float, core.Double, core.Numeric, core.Decimal:
  514. res = "NUMBER"
  515. case core.Text, core.MediumText, core.LongText, core.Json:
  516. res = "CLOB"
  517. case core.Char, core.Varchar, core.TinyText:
  518. res = "VARCHAR2"
  519. default:
  520. res = t
  521. }
  522. hasLen1 := (c.Length > 0)
  523. hasLen2 := (c.Length2 > 0)
  524. if hasLen2 {
  525. res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")"
  526. } else if hasLen1 {
  527. res += "(" + strconv.Itoa(c.Length) + ")"
  528. }
  529. return res
  530. }
  531. func (db *oracle) AutoIncrStr() string {
  532. return "AUTO_INCREMENT"
  533. }
  534. func (db *oracle) SupportInsertMany() bool {
  535. return true
  536. }
  537. func (db *oracle) IsReserved(name string) bool {
  538. _, ok := oracleReservedWords[name]
  539. return ok
  540. }
  541. func (db *oracle) Quote(name string) string {
  542. return "[" + name + "]"
  543. }
  544. func (db *oracle) SupportEngine() bool {
  545. return false
  546. }
  547. func (db *oracle) SupportCharset() bool {
  548. return false
  549. }
  550. func (db *oracle) SupportDropIfExists() bool {
  551. return false
  552. }
  553. func (db *oracle) IndexOnTable() bool {
  554. return false
  555. }
  556. func (db *oracle) DropTableSql(tableName string) string {
  557. return fmt.Sprintf("DROP TABLE `%s`", tableName)
  558. }
  559. func (db *oracle) CreateTableSql(table *core.Table, tableName, storeEngine, charset string) string {
  560. var sql string
  561. sql = "CREATE TABLE "
  562. if tableName == "" {
  563. tableName = table.Name
  564. }
  565. sql += db.Quote(tableName) + " ("
  566. pkList := table.PrimaryKeys
  567. for _, colName := range table.ColumnsSeq() {
  568. col := table.GetColumn(colName)
  569. /*if col.IsPrimaryKey && len(pkList) == 1 {
  570. sql += col.String(b.dialect)
  571. } else {*/
  572. sql += col.StringNoPk(db)
  573. // }
  574. sql = strings.TrimSpace(sql)
  575. sql += ", "
  576. }
  577. if len(pkList) > 0 {
  578. sql += "PRIMARY KEY ( "
  579. sql += db.Quote(strings.Join(pkList, db.Quote(",")))
  580. sql += " ), "
  581. }
  582. sql = sql[:len(sql)-2] + ")"
  583. if db.SupportEngine() && storeEngine != "" {
  584. sql += " ENGINE=" + storeEngine
  585. }
  586. if db.SupportCharset() {
  587. if len(charset) == 0 {
  588. charset = db.URI().Charset
  589. }
  590. if len(charset) > 0 {
  591. sql += " DEFAULT CHARSET " + charset
  592. }
  593. }
  594. return sql
  595. }
  596. func (db *oracle) IndexCheckSql(tableName, idxName string) (string, []interface{}) {
  597. args := []interface{}{tableName, idxName}
  598. return `SELECT INDEX_NAME FROM USER_INDEXES ` +
  599. `WHERE TABLE_NAME = :1 AND INDEX_NAME = :2`, args
  600. }
  601. func (db *oracle) TableCheckSql(tableName string) (string, []interface{}) {
  602. args := []interface{}{tableName}
  603. return `SELECT table_name FROM user_tables WHERE table_name = :1`, args
  604. }
  605. func (db *oracle) MustDropTable(tableName string) error {
  606. sql, args := db.TableCheckSql(tableName)
  607. db.LogSQL(sql, args)
  608. rows, err := db.DB().Query(sql, args...)
  609. if err != nil {
  610. return err
  611. }
  612. defer rows.Close()
  613. if !rows.Next() {
  614. return nil
  615. }
  616. sql = "Drop Table \"" + tableName + "\""
  617. db.LogSQL(sql, args)
  618. _, err = db.DB().Exec(sql)
  619. return err
  620. }
  621. /*func (db *oracle) ColumnCheckSql(tableName, colName string) (string, []interface{}) {
  622. args := []interface{}{strings.ToUpper(tableName), strings.ToUpper(colName)}
  623. return "SELECT column_name FROM USER_TAB_COLUMNS WHERE table_name = ?" +
  624. " AND column_name = ?", args
  625. }*/
  626. func (db *oracle) IsColumnExist(tableName, colName string) (bool, error) {
  627. args := []interface{}{tableName, colName}
  628. query := "SELECT column_name FROM USER_TAB_COLUMNS WHERE table_name = :1" +
  629. " AND column_name = :2"
  630. db.LogSQL(query, args)
  631. rows, err := db.DB().Query(query, args...)
  632. if err != nil {
  633. return false, err
  634. }
  635. defer rows.Close()
  636. if rows.Next() {
  637. return true, nil
  638. }
  639. return false, nil
  640. }
  641. func (db *oracle) GetColumns(tableName string) ([]string, map[string]*core.Column, error) {
  642. args := []interface{}{tableName}
  643. s := "SELECT column_name,data_default,data_type,data_length,data_precision,data_scale," +
  644. "nullable FROM USER_TAB_COLUMNS WHERE table_name = :1"
  645. db.LogSQL(s, args)
  646. rows, err := db.DB().Query(s, args...)
  647. if err != nil {
  648. return nil, nil, err
  649. }
  650. defer rows.Close()
  651. cols := make(map[string]*core.Column)
  652. colSeq := make([]string, 0)
  653. for rows.Next() {
  654. col := new(core.Column)
  655. col.Indexes = make(map[string]int)
  656. var colName, colDefault, nullable, dataType, dataPrecision, dataScale *string
  657. var dataLen int
  658. err = rows.Scan(&colName, &colDefault, &dataType, &dataLen, &dataPrecision,
  659. &dataScale, &nullable)
  660. if err != nil {
  661. return nil, nil, err
  662. }
  663. col.Name = strings.Trim(*colName, `" `)
  664. if colDefault != nil {
  665. col.Default = *colDefault
  666. col.DefaultIsEmpty = false
  667. }
  668. if *nullable == "Y" {
  669. col.Nullable = true
  670. } else {
  671. col.Nullable = false
  672. }
  673. var ignore bool
  674. var dt string
  675. var len1, len2 int
  676. dts := strings.Split(*dataType, "(")
  677. dt = dts[0]
  678. if len(dts) > 1 {
  679. lens := strings.Split(dts[1][:len(dts[1])-1], ",")
  680. if len(lens) > 1 {
  681. len1, _ = strconv.Atoi(lens[0])
  682. len2, _ = strconv.Atoi(lens[1])
  683. } else {
  684. len1, _ = strconv.Atoi(lens[0])
  685. }
  686. }
  687. switch dt {
  688. case "VARCHAR2":
  689. col.SQLType = core.SQLType{Name: core.Varchar, DefaultLength: len1, DefaultLength2: len2}
  690. case "NVARCHAR2":
  691. col.SQLType = core.SQLType{Name: core.NVarchar, DefaultLength: len1, DefaultLength2: len2}
  692. case "TIMESTAMP WITH TIME ZONE":
  693. col.SQLType = core.SQLType{Name: core.TimeStampz, DefaultLength: 0, DefaultLength2: 0}
  694. case "NUMBER":
  695. col.SQLType = core.SQLType{Name: core.Double, DefaultLength: len1, DefaultLength2: len2}
  696. case "LONG", "LONG RAW":
  697. col.SQLType = core.SQLType{Name: core.Text, DefaultLength: 0, DefaultLength2: 0}
  698. case "RAW":
  699. col.SQLType = core.SQLType{Name: core.Binary, DefaultLength: 0, DefaultLength2: 0}
  700. case "ROWID":
  701. col.SQLType = core.SQLType{Name: core.Varchar, DefaultLength: 18, DefaultLength2: 0}
  702. case "AQ$_SUBSCRIBERS":
  703. ignore = true
  704. default:
  705. col.SQLType = core.SQLType{Name: strings.ToUpper(dt), DefaultLength: len1, DefaultLength2: len2}
  706. }
  707. if ignore {
  708. continue
  709. }
  710. if _, ok := core.SqlTypes[col.SQLType.Name]; !ok {
  711. return nil, nil, fmt.Errorf("Unknown colType %v %v", *dataType, col.SQLType)
  712. }
  713. col.Length = dataLen
  714. if col.SQLType.IsText() || col.SQLType.IsTime() {
  715. if !col.DefaultIsEmpty {
  716. col.Default = "'" + col.Default + "'"
  717. }
  718. }
  719. cols[col.Name] = col
  720. colSeq = append(colSeq, col.Name)
  721. }
  722. return colSeq, cols, nil
  723. }
  724. func (db *oracle) GetTables() ([]*core.Table, error) {
  725. args := []interface{}{}
  726. s := "SELECT table_name FROM user_tables"
  727. db.LogSQL(s, args)
  728. rows, err := db.DB().Query(s, args...)
  729. if err != nil {
  730. return nil, err
  731. }
  732. defer rows.Close()
  733. tables := make([]*core.Table, 0)
  734. for rows.Next() {
  735. table := core.NewEmptyTable()
  736. err = rows.Scan(&table.Name)
  737. if err != nil {
  738. return nil, err
  739. }
  740. tables = append(tables, table)
  741. }
  742. return tables, nil
  743. }
  744. func (db *oracle) GetIndexes(tableName string) (map[string]*core.Index, error) {
  745. args := []interface{}{tableName}
  746. s := "SELECT t.column_name,i.uniqueness,i.index_name FROM user_ind_columns t,user_indexes i " +
  747. "WHERE t.index_name = i.index_name and t.table_name = i.table_name and t.table_name =:1"
  748. db.LogSQL(s, args)
  749. rows, err := db.DB().Query(s, args...)
  750. if err != nil {
  751. return nil, err
  752. }
  753. defer rows.Close()
  754. indexes := make(map[string]*core.Index, 0)
  755. for rows.Next() {
  756. var indexType int
  757. var indexName, colName, uniqueness string
  758. err = rows.Scan(&colName, &uniqueness, &indexName)
  759. if err != nil {
  760. return nil, err
  761. }
  762. indexName = strings.Trim(indexName, `" `)
  763. var isRegular bool
  764. if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) {
  765. indexName = indexName[5+len(tableName):]
  766. isRegular = true
  767. }
  768. if uniqueness == "UNIQUE" {
  769. indexType = core.UniqueType
  770. } else {
  771. indexType = core.IndexType
  772. }
  773. var index *core.Index
  774. var ok bool
  775. if index, ok = indexes[indexName]; !ok {
  776. index = new(core.Index)
  777. index.Type = indexType
  778. index.Name = indexName
  779. index.IsRegular = isRegular
  780. indexes[indexName] = index
  781. }
  782. index.AddColumn(colName)
  783. }
  784. return indexes, nil
  785. }
  786. func (db *oracle) Filters() []core.Filter {
  787. return []core.Filter{&core.QuoteFilter{}, &core.SeqFilter{Prefix: ":", Start: 1}, &core.IdFilter{}}
  788. }
  789. type goracleDriver struct {
  790. }
  791. func (cfg *goracleDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
  792. db := &core.Uri{DbType: core.ORACLE}
  793. dsnPattern := regexp.MustCompile(
  794. `^(?:(?P<user>.*?)(?::(?P<passwd>.*))?@)?` + // [user[:password]@]
  795. `(?:(?P<net>[^\(]*)(?:\((?P<addr>[^\)]*)\))?)?` + // [net[(addr)]]
  796. `\/(?P<dbname>.*?)` + // /dbname
  797. `(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1&paramN=valueN]
  798. matches := dsnPattern.FindStringSubmatch(dataSourceName)
  799. // tlsConfigRegister := make(map[string]*tls.Config)
  800. names := dsnPattern.SubexpNames()
  801. for i, match := range matches {
  802. switch names[i] {
  803. case "dbname":
  804. db.DbName = match
  805. }
  806. }
  807. if db.DbName == "" {
  808. return nil, errors.New("dbname is empty")
  809. }
  810. return db, nil
  811. }
  812. type oci8Driver struct {
  813. }
  814. // dataSourceName=user/password@ipv4:port/dbname
  815. // dataSourceName=user/password@[ipv6]:port/dbname
  816. func (p *oci8Driver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
  817. db := &core.Uri{DbType: core.ORACLE}
  818. dsnPattern := regexp.MustCompile(
  819. `^(?P<user>.*)\/(?P<password>.*)@` + // user:password@
  820. `(?P<net>.*)` + // ip:port
  821. `\/(?P<dbname>.*)`) // dbname
  822. matches := dsnPattern.FindStringSubmatch(dataSourceName)
  823. names := dsnPattern.SubexpNames()
  824. for i, match := range matches {
  825. switch names[i] {
  826. case "dbname":
  827. db.DbName = match
  828. }
  829. }
  830. if db.DbName == "" {
  831. return nil, errors.New("dbname is empty")
  832. }
  833. return db, nil
  834. }