mirror of
https://github.com/ManyakRus/crud_generator.git
synced 2024-12-22 00:36:41 +02:00
96 lines
3.6 KiB
Go
96 lines
3.6 KiB
Go
package schema
|
|
|
|
import (
|
|
"database/sql"
|
|
"strings"
|
|
)
|
|
|
|
type dialect interface {
|
|
escapeIdent(ident string) string
|
|
|
|
ColumnTypes(db *sql.DB, schema, name string) ([]*sql.ColumnType, error)
|
|
PrimaryKey(db *sql.DB, schema, name string) ([]string, error)
|
|
TableNames(db *sql.DB) ([][2]string, error)
|
|
ViewNames(db *sql.DB) ([][2]string, error)
|
|
}
|
|
|
|
// driverDialect is a registry, mapping database/sql driver names to database dialects.
|
|
// This is somewhat fragile.
|
|
var driverDialect = map[string]dialect{
|
|
"*sqlite3.SQLiteDriver": sqliteDialect{}, // github.com/mattn/go-sqlite3
|
|
"*sqlite.impl": sqliteDialect{}, // github.com/gwenn/gosqlite
|
|
"sqlite3.Driver": sqliteDialect{}, // github.com/mxk/go-sqlite
|
|
"*pq.Driver": postgresDialect{}, // github.com/lib/pq
|
|
"*stdlib.Driver": postgresDialect{}, // github.com/jackc/pgx
|
|
"*pgsqldriver.postgresDriver": postgresDialect{}, // github.com/jbarham/gopgsqldriver
|
|
"*gosnowflake.SnowflakeDriver": postgresDialect{}, // github.com/snowflakedb/gosnowflake
|
|
"*mysql.MySQLDriver": mysqlDialect{}, // github.com/go-sql-driver/mysql
|
|
"*godrv.Driver": mysqlDialect{}, // github.com/ziutek/mymysql
|
|
"vitessdriver.drv": mysqlDialect{}, // github.com/vitessio/vitess
|
|
"*mssql.Driver": mssqlDialect{}, // github.com/denisenkom/go-mssqldb
|
|
"*mssql.MssqlDriver": mssqlDialect{}, // github.com/denisenkom/go-mssqldb
|
|
"*freetds.MssqlDriver": mssqlDialect{}, // github.com/minus5/gofreetds
|
|
"*goracle.drv": oracleDialect{}, // gopkg.in/goracle.v2
|
|
"*godror.drv": oracleDialect{}, // github.com/godror/godror
|
|
"*ora.Drv": oracleDialect{}, // gopkg.in/rana/ora.v4
|
|
"*oci8.OCI8DriverStruct": oracleDialect{}, // github.com/mattn/go-oci8
|
|
"*oci8.OCI8Driver": oracleDialect{}, // github.com/mattn/go-oci8
|
|
}
|
|
|
|
// TODO Should we expose a method of registering a driver string/dialect in our registry?
|
|
// -- It would allow folk to work around the fragility. e.g.
|
|
//
|
|
// func Register(driver sql.Driver, d *Dialect) {}
|
|
//
|
|
|
|
// // pack a string, normalising its whitespace.
|
|
// func pack(s string) string {
|
|
// return strings.Join(strings.Fields(s), " ")
|
|
// }
|
|
|
|
// escapeWithDoubleQuotes implements double-quote escaping of a string,
|
|
// in accordance with SQL:1999 standard.
|
|
func escapeWithDoubleQuotes(s string) string {
|
|
return escape(s, '"', '"')
|
|
}
|
|
|
|
// escapeWithBackticks implements backtick escaping of a string.
|
|
func escapeWithBackticks(s string) string {
|
|
return escape(s, '`', '`')
|
|
}
|
|
|
|
// escapeWithBrackets implements bracket escaping of a string.
|
|
func escapeWithBrackets(s string) string {
|
|
return escape(s, '[', ']')
|
|
}
|
|
|
|
// escapeWithBraces implements brace escaping of a string.
|
|
func escapeWithBraces(s string) string {
|
|
return escape(s, '{', '}')
|
|
}
|
|
|
|
// escape escapes a string identifier.
|
|
func escape(s string, escBegin, escEnd byte) string {
|
|
// It would be nice to know when not to escape,
|
|
// but a regex (e.g. "^[a-zA-Z_][a-zA-Z0-9_#@$]*$")
|
|
// doesn't solve this, because it would not catch keywords.
|
|
// Which is why we simply always escape identifiers.
|
|
|
|
// TODO(js) Correct handling of backslash escaping of identifiers needs
|
|
// further investigation: different dialects look to handle it differently
|
|
// - removed for now.
|
|
// Please file an issue if you encounter a problem regarding backslash escaping.
|
|
|
|
var b strings.Builder
|
|
b.WriteByte(escBegin)
|
|
for i := 0; i < len(s); i++ {
|
|
c := s[i]
|
|
b.WriteByte(c)
|
|
if c == escEnd { // || c == '\\' {
|
|
b.WriteByte(c)
|
|
}
|
|
}
|
|
b.WriteByte(escEnd)
|
|
return b.String()
|
|
}
|