mysql OK, partially tested
This commit is contained in:
parent
31690925c1
commit
5ce4f94524
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,3 +14,4 @@
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
__debug_bin
|
||||
gen/
|
153
db.go
153
db.go
@ -9,6 +9,7 @@ import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -79,7 +80,7 @@ func (db *Db) QueryAssociativeArray(query string) (Rows, error) {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
// get rows
|
||||
results := Rows{}
|
||||
cols, err := rows.Columns()
|
||||
if err != nil {
|
||||
@ -87,6 +88,16 @@ func (db *Db) QueryAssociativeArray(query string) (Rows, error) {
|
||||
log.Println(query)
|
||||
return nil, err
|
||||
}
|
||||
// make types map
|
||||
columnTypes, err := rows.ColumnTypes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
columnType := make(map[string]string)
|
||||
for _, colType := range columnTypes {
|
||||
columnType[colType.Name()] = colType.DatabaseTypeName()
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
// Create a slice of interface{}'s to represent each column,
|
||||
// and a second slice to contain pointers to each item in the columns slice.
|
||||
@ -97,19 +108,69 @@ func (db *Db) QueryAssociativeArray(query string) (Rows, error) {
|
||||
}
|
||||
|
||||
// Scan the result into the column pointers...
|
||||
if err := rows.Scan(columnPointers...); err != nil {
|
||||
|
||||
err = rows.Scan(columnPointers...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create our map, and retrieve the value for each column from the pointers slice,
|
||||
// storing it in the map with the name of the column as the key.
|
||||
m := make(AssRow)
|
||||
for i, colName := range cols {
|
||||
//fmt.Println(colName)
|
||||
val := columnPointers[i].(*interface{})
|
||||
m[colName] = fmt.Sprintf("%v", *val)
|
||||
if db.Driver == "mysql" {
|
||||
if (*val) == nil {
|
||||
m[colName] = nil
|
||||
} else {
|
||||
switch columnType[colName] {
|
||||
case "INT", "BIGINT":
|
||||
i, err := strconv.ParseInt(fmt.Sprintf("%s", *val), 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m[colName] = i
|
||||
case "UNSIGNED BIGINT":
|
||||
u, err := strconv.ParseUint(fmt.Sprintf("%s", *val), 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m[colName] = u
|
||||
case "FLOAT":
|
||||
f, err := strconv.ParseFloat(fmt.Sprintf("%s", *val), 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m[colName] = f
|
||||
case "TINYINT":
|
||||
i, err := strconv.ParseInt(fmt.Sprintf("%s", *val), 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if i == 1 {
|
||||
m[colName] = true
|
||||
} else {
|
||||
m[colName] = false
|
||||
}
|
||||
|
||||
case "VARCHAR", "TEXT", "TIMESTAMP":
|
||||
m[colName] = fmt.Sprintf("%s", *val)
|
||||
default:
|
||||
if reflect.ValueOf(val).IsNil() {
|
||||
m[colName] = nil
|
||||
} else {
|
||||
fmt.Printf("Unknow type : %s", columnType[colName])
|
||||
m[colName] = fmt.Sprintf("%v", *val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if db.Driver == "postgres" {
|
||||
m[colName] = *val
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
results = append(results, m)
|
||||
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
@ -117,7 +178,7 @@ func (db *Db) QueryAssociativeArray(query string) (Rows, error) {
|
||||
// GetSchema : Provide table schema as an associative array
|
||||
func (t *TableInfo) GetSchema() (*TableInfo, error) {
|
||||
pgSchema := "SELECT column_name :: varchar as name, REPLACE(REPLACE(data_type,'character varying','varchar'),'character','char') || COALESCE('(' || character_maximum_length || ')', '') as type, col_description('public." + t.Name + "'::regclass, ordinal_position) as comment from INFORMATION_SCHEMA.COLUMNS where table_name ='" + t.Name + "';"
|
||||
mySchema := "SELECT COLUMN_NAME as name, DATA_TYPE || CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + t.Name + "';"
|
||||
mySchema := "SELECT COLUMN_NAME as name, CONCAT(DATA_TYPE, COALESCE(CONCAT('(' , CHARACTER_MAXIMUM_LENGTH, ')'), '')) as type FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + t.Name + "';"
|
||||
var schemaQuery string
|
||||
var ti TableInfo
|
||||
ti.Name = t.Name
|
||||
@ -138,13 +199,13 @@ func (t *TableInfo) GetSchema() (*TableInfo, error) {
|
||||
var name, rowtype, comment string
|
||||
for key, element := range row {
|
||||
if key == "name" {
|
||||
name = fmt.Sprintf("%v", element)
|
||||
name = fmt.Sprintf("%s", element)
|
||||
}
|
||||
if key == "type" {
|
||||
rowtype = fmt.Sprintf("%v", element)
|
||||
rowtype = fmt.Sprintf("%s", element)
|
||||
}
|
||||
if key == "comment" {
|
||||
comment = fmt.Sprintf("%v", element)
|
||||
comment = fmt.Sprintf("%s", element)
|
||||
}
|
||||
}
|
||||
ti.Columns[name] = rowtype
|
||||
@ -200,6 +261,16 @@ func (db *Db) myListTables() (Rows, error) {
|
||||
}
|
||||
|
||||
func (db *Db) CreateTable(t TableInfo) error {
|
||||
if db.Driver == "postgres" {
|
||||
return db.pgCreateTable(t)
|
||||
}
|
||||
if db.Driver == "mysql" {
|
||||
return db.myCreateTable(t)
|
||||
}
|
||||
return errors.New("no driver")
|
||||
}
|
||||
|
||||
func (db *Db) pgCreateTable(t TableInfo) error {
|
||||
t.db = db
|
||||
query := "create table " + t.Name + " ( "
|
||||
columns := ""
|
||||
@ -234,6 +305,32 @@ func (db *Db) CreateTable(t TableInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Db) myCreateTable(t TableInfo) error {
|
||||
t.db = db
|
||||
query := "create table " + t.Name + " ( "
|
||||
columns := ""
|
||||
for name, rowtype := range t.Columns {
|
||||
if fmt.Sprintf("%v", name) == "id" {
|
||||
columns += fmt.Sprintf("%v", name) + " " + "SERIAL PRIMARY KEY,"
|
||||
} else {
|
||||
desc := strings.Split(fmt.Sprintf("%v", rowtype), "|")
|
||||
columns += fmt.Sprintf("%v", name) + " " + desc[0]
|
||||
if len(desc) > 1 {
|
||||
columns += " COMMENT " + pq.QuoteLiteral(desc[1])
|
||||
}
|
||||
columns += ","
|
||||
}
|
||||
}
|
||||
query += columns
|
||||
query = query[:len(query)-1] + " )"
|
||||
_, err := t.db.conn.Query(query)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TableInfo) DeleteTable() error {
|
||||
query := "drop table " + t.Name
|
||||
_, err := t.db.conn.Query(query)
|
||||
@ -251,6 +348,16 @@ func (t *TableInfo) DeleteTable() error {
|
||||
}
|
||||
|
||||
func (t *TableInfo) AddColumn(name string, sqltype string, comment string) error {
|
||||
if t.db.Driver == "postgres" {
|
||||
return t.pgAddColumn(name, sqltype, comment)
|
||||
}
|
||||
if t.db.Driver == "mysql" {
|
||||
return t.myAddColumn(name, sqltype, comment)
|
||||
}
|
||||
return errors.New("no driver")
|
||||
}
|
||||
|
||||
func (t *TableInfo) pgAddColumn(name string, sqltype string, comment string) error {
|
||||
query := "alter table " + t.Name + " add " + name + " " + sqltype
|
||||
rows, err := t.db.conn.Query(query)
|
||||
if err != nil {
|
||||
@ -269,6 +376,20 @@ func (t *TableInfo) AddColumn(name string, sqltype string, comment string) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TableInfo) myAddColumn(name string, sqltype string, comment string) error {
|
||||
query := "alter table " + t.Name + " add " + name + " " + sqltype
|
||||
if strings.TrimSpace(comment) != "" {
|
||||
query += " COMMENT " + pq.QuoteLiteral(comment)
|
||||
}
|
||||
rows, err := t.db.conn.Query(query)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TableInfo) DeleteColumn(name string) error {
|
||||
query := "alter table " + t.Name + " drop " + name
|
||||
rows, err := t.db.conn.Query(query)
|
||||
@ -355,8 +476,16 @@ func (t *TableInfo) Insert(record AssRow) (int, error) {
|
||||
columns += key + ","
|
||||
values += FormatForSQL(t.Columns[key], element) + ","
|
||||
}
|
||||
|
||||
err = t.db.conn.QueryRow("INSERT INTO " + t.Name + "(" + removeLastChar(columns) + ") VALUES (" + removeLastChar(values) + ") RETURNING id").Scan(&id)
|
||||
if t.db.Driver == "postgres" {
|
||||
err = t.db.conn.QueryRow("INSERT INTO " + t.Name + "(" + removeLastChar(columns) + ") VALUES (" + removeLastChar(values) + ") RETURNING id").Scan(&id)
|
||||
}
|
||||
if t.db.Driver == "mysql" {
|
||||
_, err = t.db.conn.Query("INSERT INTO " + t.Name + "(" + removeLastChar(columns) + ") VALUES (" + removeLastChar(values) + ")")
|
||||
if err != nil {
|
||||
return id, err
|
||||
}
|
||||
err = t.db.conn.QueryRow("LAST_INSERT_ID();").Scan(&id)
|
||||
}
|
||||
return id, err
|
||||
}
|
||||
|
||||
|
9
go.mod
9
go.mod
@ -3,6 +3,13 @@ module forge.redroom.link/yves/sqldb
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/go-sql-driver/mysql v1.7.1
|
||||
github.com/lib/pq v1.10.4
|
||||
gorm.io/driver/mysql v1.5.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/go-sql-driver/mysql v1.7.1 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
gorm.io/gorm v1.25.1 // indirect
|
||||
)
|
||||
|
9
go.sum
9
go.sum
@ -1,4 +1,13 @@
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
|
||||
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
|
||||
gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
|
||||
gorm.io/gorm v1.25.1 h1:nsSALe5Pr+cM3V1qwwQ7rOkw+6UeLrX5O4v3llhHa64=
|
||||
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
|
29
my_test.go
29
my_test.go
@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
func TestMyCreateTable(t *testing.T) {
|
||||
db := Open("mysql", "test:test@tcp(127.0.0.1:3306)/test")
|
||||
db := Open("mysql", "test:test@tcp(127.0.0.1:3306)/test?parseTime=true")
|
||||
defer db.Close()
|
||||
|
||||
jsonFile, err := os.Open("test_table.json")
|
||||
@ -39,7 +39,7 @@ func TestMyCreateTable(t *testing.T) {
|
||||
|
||||
func TestMyAddColumn(t *testing.T) {
|
||||
|
||||
db := Open("postgres", "host=127.0.0.1 port=5432 user=test password=test dbname=test sslmode=disable")
|
||||
db := Open("mysql", "test:test@tcp(127.0.0.1:3306)/test?parseTime=true")
|
||||
defer db.Close()
|
||||
|
||||
old, err := db.Table("test").GetSchema()
|
||||
@ -59,12 +59,15 @@ func TestMyAddColumn(t *testing.T) {
|
||||
|
||||
func TestMyInsert(t *testing.T) {
|
||||
|
||||
db := Open("postgres", "host=127.0.0.1 port=5432 user=test password=test dbname=test sslmode=disable")
|
||||
db := Open("mysql", "test:test@tcp(127.0.0.1:3306)/test?parseTime=true")
|
||||
defer db.Close()
|
||||
|
||||
vl := make(AssRow)
|
||||
vl["name"] = "toto"
|
||||
vl["description"] = "tata"
|
||||
vl["longitude"] = 1.38
|
||||
vl["enddate"] = "2022-09-01"
|
||||
vl["boolvalue"] = "true"
|
||||
|
||||
old, err := db.Table("test").GetAssociativeArray([]string{"*"}, "", []string{}, "")
|
||||
if err != nil {
|
||||
@ -94,7 +97,7 @@ func TestMyInsert(t *testing.T) {
|
||||
|
||||
func TestMyUpdate(t *testing.T) {
|
||||
|
||||
db := Open("postgres", "host=127.0.0.1 port=5432 user=test password=test dbname=test sslmode=disable")
|
||||
db := Open("mysql", "test:test@tcp(127.0.0.1:3306)/test?parseTime=true")
|
||||
defer db.Close()
|
||||
|
||||
vl := make(AssRow)
|
||||
@ -126,7 +129,7 @@ func TestMyUpdate(t *testing.T) {
|
||||
|
||||
func TestMyDelete(t *testing.T) {
|
||||
|
||||
db := Open("postgres", "host=127.0.0.1 port=5432 user=test password=test dbname=test sslmode=disable")
|
||||
db := Open("mysql", "test:test@tcp(127.0.0.1:3306)/test?parseTime=true")
|
||||
defer db.Close()
|
||||
|
||||
vl := make(AssRow)
|
||||
@ -155,7 +158,7 @@ func TestMyDelete(t *testing.T) {
|
||||
|
||||
func TestMyDeleteColumn(t *testing.T) {
|
||||
|
||||
db := Open("postgres", "host=127.0.0.1 port=5432 user=test password=test dbname=test sslmode=disable")
|
||||
db := Open("mysql", "test:test@tcp(127.0.0.1:3306)/test?parseTime=true")
|
||||
defer db.Close()
|
||||
|
||||
old, err := db.Table("test").GetSchema()
|
||||
@ -174,26 +177,26 @@ func TestMyDeleteColumn(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMyDeleteTable(t *testing.T) {
|
||||
db := Open("postgres", "host=127.0.0.1 port=5432 user=test password=test dbname=test sslmode=disable")
|
||||
db := Open("mysql", "test:test@tcp(127.0.0.1:3306)/test?parseTime=true")
|
||||
defer db.Close()
|
||||
db.Table("test").DeleteTable()
|
||||
|
||||
}
|
||||
|
||||
func TestMyImportSchema(t *testing.T) {
|
||||
db := Open("postgres", "host=127.0.0.1 port=5432 user=test password=test dbname=test sslmode=disable")
|
||||
db := Open("mysql", "test:test@tcp(127.0.0.1:3306)/test?parseTime=true")
|
||||
defer db.Close()
|
||||
db.ImportSchema("pfn.json")
|
||||
}
|
||||
|
||||
func TestMyClearImportSchema(t *testing.T) {
|
||||
db := Open("postgres", "host=127.0.0.1 port=5432 user=test password=test dbname=test sslmode=disable")
|
||||
db := Open("mysql", "test:test@tcp(127.0.0.1:3306)/test?parseTime=true")
|
||||
defer db.Close()
|
||||
db.ClearImportSchema("pfn.json")
|
||||
}
|
||||
|
||||
func TestMyGetSchema(t *testing.T) {
|
||||
db := Open("postgres", "host=127.0.0.1 port=5432 user=test password=test dbname=test sslmode=disable")
|
||||
db := Open("mysql", "test:test@tcp(127.0.0.1:3306)/test?parseTime=true?charset=utf8mb4&collation=utf8mb4_unicode_ci")
|
||||
defer db.Close()
|
||||
data, err := db.GetSchema()
|
||||
if err != nil {
|
||||
@ -204,7 +207,7 @@ func TestMyGetSchema(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMySaveSchema(t *testing.T) {
|
||||
db := Open("postgres", "host=127.0.0.1 port=5432 user=test password=test dbname=test sslmode=disable")
|
||||
db := Open("mysql", "test:test@tcp(127.0.0.1:3306)/test?parseTime=true")
|
||||
defer db.Close()
|
||||
err := db.SaveSchema("schema.json")
|
||||
if err != nil {
|
||||
@ -212,7 +215,7 @@ func TestMySaveSchema(t *testing.T) {
|
||||
}
|
||||
}
|
||||
func TestMyGenerateTemplate(t *testing.T) {
|
||||
db := Open("postgres", "host=127.0.0.1 port=5432 user=test password=test dbname=test sslmode=disable")
|
||||
db := Open("mysql", "test:test@tcp(127.0.0.1:3306)/test?parseTime=true")
|
||||
defer db.Close()
|
||||
err := db.GenerateTemplate("plantuml.tmpl", "schema.puml")
|
||||
if err != nil {
|
||||
@ -221,7 +224,7 @@ func TestMyGenerateTemplate(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMyGenerateTableTemplate(t *testing.T) {
|
||||
db := Open("postgres", "host=127.0.0.1 port=5432 user=test password=test dbname=test sslmode=disable")
|
||||
db := Open("mysql", "test:test@tcp(127.0.0.1:3306)/test?parseTime=true")
|
||||
defer db.Close()
|
||||
err := db.GenerateTableTemplates("table.tmpl", "gen", "html")
|
||||
if err != nil {
|
||||
|
@ -65,6 +65,9 @@ func TestPgInsert(t *testing.T) {
|
||||
vl := make(AssRow)
|
||||
vl["name"] = "toto"
|
||||
vl["description"] = "tata"
|
||||
vl["longitude"] = 1.38
|
||||
vl["enddate"] = "2022-09-01"
|
||||
vl["boolvalue"] = "true"
|
||||
|
||||
old, err := db.Table("test").GetAssociativeArray([]string{"*"}, "", []string{}, "")
|
||||
if err != nil {
|
||||
|
@ -12,6 +12,7 @@
|
||||
"intvalue":"integer",
|
||||
"floatvalue":"float",
|
||||
"price":"float",
|
||||
"testtype_id":"integer"
|
||||
"testtype_id":"integer",
|
||||
"boolvalue":"boolean"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user