diff --git a/circle.yml b/circle.yml index adfd2a16..c5885d41 100644 --- a/circle.yml +++ b/circle.yml @@ -33,7 +33,12 @@ test: - go test -v -race -db="postgres" -conn_str="dbname=xorm_test sslmode=disable" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic - go test -v -race -db="postgres" -conn_str="dbname=xorm_test sslmode=disable" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic - go test -v -race -db="postgres" -conn_str="dbname=xorm_test sslmode=disable" -schema=xorm -cache=true -coverprofile=coverage5-2.txt -covermode=atomic - - gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt > coverage.txt + - wget -qO- https://binaries.cockroachdb.com/cockroach-v2.0.0.linux-amd64.tgz | tar xvz + - ./cockroach-v2.0.0.linux-amd64/cockroach start --insecure --background --host=localhost + - sleep 5 + - ./cockroach-v2.0.0.linux-amd64/cockroach sql --insecure --execute="create database xorm_test" + - go test -v -race -db="postgres" -conn_str="postgresql://root@localhost:26257/xorm_test?sslmode=disable" -coverprofile=coverage6-1.txt -covermode=atomic + - gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt> coverage.txt - cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./sqlite3.sh - cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./mysql.sh - cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./postgres.sh diff --git a/dialect_postgres.go b/dialect_postgres.go index 1f74bd31..dd101375 100644 --- a/dialect_postgres.go +++ b/dialect_postgres.go @@ -952,7 +952,13 @@ func (db *postgres) IsColumnExist(tableName, colName string) (bool, error) { func (db *postgres) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { args := []interface{}{tableName} - s := `SELECT column_name, column_default, is_nullable, data_type, character_maximum_length, numeric_precision, numeric_precision_radix , + s := `SELECT column_name, column_default, is_nullable, replace(data_type,'STRING','VARCHAR'), + character_maximum_length, numeric_precision, + CASE + WHEN numeric_precision IS NOT NULL AND lower(data_type) = 'decimal' THEN 10 + WHEN numeric_precision IS NOT NULL AND lower(data_type) != 'decimal' THEN 2 + ELSE NULL + END AS numeric_precision_radix, CASE WHEN p.contype = 'p' THEN true ELSE false END AS primarykey, CASE WHEN p.contype = 'u' THEN true ELSE false END AS uniquekey FROM pg_attribute f @@ -987,14 +993,14 @@ WHERE c.relkind = 'r'::char AND c.relname = $1%s AND f.attnum > 0 ORDER BY f.att col.Indexes = make(map[string]int) var colName, isNullable, dataType string - var maxLenStr, colDefault, numPrecision, numRadix *string + var maxLenStr, colDefault, numPrecision *string var isPK, isUnique bool - err = rows.Scan(&colName, &colDefault, &isNullable, &dataType, &maxLenStr, &numPrecision, &numRadix, &isPK, &isUnique) + err = rows.Scan(&colName, &colDefault, &isNullable, &dataType, &maxLenStr, &numPrecision, &isPK, &isUnique) if err != nil { return nil, nil, err } - //fmt.Println(args, colName, isNullable, dataType, maxLenStr, colDefault, numPrecision, numRadix, isPK, isUnique) + //fmt.Println(args, colName, isNullable, dataType, maxLenStr, colDefault, numPrecision, isPK, isUnique) var maxLen int if maxLenStr != nil { maxLen, err = strconv.Atoi(*maxLenStr) @@ -1019,7 +1025,7 @@ WHERE c.relkind = 'r'::char AND c.relname = $1%s AND f.attnum > 0 ORDER BY f.att col.Nullable = (isNullable == "YES") - switch dataType { + switch strings.ToLower(dataType) { case "character varying", "character": col.SQLType = core.SQLType{Name: core.Varchar, DefaultLength: 0, DefaultLength2: 0} case "timestamp without time zone": @@ -1032,10 +1038,19 @@ WHERE c.relkind = 'r'::char AND c.relname = $1%s AND f.attnum > 0 ORDER BY f.att col.SQLType = core.SQLType{Name: core.Bool, DefaultLength: 0, DefaultLength2: 0} case "time without time zone": col.SQLType = core.SQLType{Name: core.Time, DefaultLength: 0, DefaultLength2: 0} + case "bytes": + col.SQLType = core.SQLType{Name: core.Binary, DefaultLength: 0, DefaultLength2: 0} case "oid": col.SQLType = core.SQLType{Name: core.BigInt, DefaultLength: 0, DefaultLength2: 0} default: - col.SQLType = core.SQLType{Name: strings.ToUpper(dataType), DefaultLength: 0, DefaultLength2: 0} + startIdx := strings.Index(strings.ToLower(dataType), "varchar(") + if startIdx != -1 && strings.HasSuffix(dataType, ")") { + length := dataType[startIdx+8 : len(dataType)-1] + l, _ := strconv.Atoi(length) + col.SQLType = core.SQLType{Name: "varchar", DefaultLength: l, DefaultLength2: 0} + } else { + col.SQLType = core.SQLType{Name: strings.ToUpper(dataType), DefaultLength: 0, DefaultLength2: 0} + } } if _, ok := core.SqlTypes[col.SQLType.Name]; !ok { return nil, nil, fmt.Errorf("Unknown colType: %v", dataType) @@ -1113,6 +1128,10 @@ func (db *postgres) GetIndexes(tableName string) (map[string]*core.Index, error) if err != nil { return nil, err } + + if indexName == "primary" { + continue + } indexName = strings.Trim(indexName, `" `) if strings.HasSuffix(indexName, "_pkey") { continue @@ -1124,6 +1143,7 @@ func (db *postgres) GetIndexes(tableName string) (map[string]*core.Index, error) } cs := strings.Split(indexdef, "(") colNames = strings.Split(cs[1][0:len(cs[1])-1], ",") + var isRegular bool if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) { newIdxName := indexName[5+len(tableName):] @@ -1135,7 +1155,7 @@ func (db *postgres) GetIndexes(tableName string) (map[string]*core.Index, error) index := &core.Index{Name: indexName, Type: indexType, Cols: make([]string, 0)} for _, colName := range colNames { - index.Cols = append(index.Cols, strings.Trim(colName, `" `)) + index.Cols = append(index.Cols, strings.TrimSpace(strings.Replace(colName, `"`, "", -1))) } index.IsRegular = isRegular indexes[index.Name] = index diff --git a/engine.go b/engine.go index 08e2ace5..3f7df242 100644 --- a/engine.go +++ b/engine.go @@ -380,12 +380,19 @@ func (engine *Engine) DBMetas() ([]*core.Table, error) { } table.Indexes = indexes + var seq int for _, index := range indexes { for _, name := range index.Cols { - if col := table.GetColumn(name); col != nil { + parts := strings.Split(name, " ") + if len(parts) > 1 { + if parts[1] == "DESC" { + seq = 1 + } + } + if col := table.GetColumn(parts[0]); col != nil { col.Indexes[index.Name] = index.Type } else { - return nil, fmt.Errorf("Unknown col %s in index %v of table %v, columns %v", name, index.Name, table.Name, table.ColumnsSeq()) + return nil, fmt.Errorf("Unknown col %s seq %d, in index %v of table %v, columns %v", name, seq, index.Name, table.Name, table.ColumnsSeq()) } } } diff --git a/test_cockroach.sh b/test_cockroach.sh new file mode 100755 index 00000000..ea6a844b --- /dev/null +++ b/test_cockroach.sh @@ -0,0 +1 @@ +go test -db=postgres -conn_str="postgresql://root@localhost:26257/xorm_test?sslmode=disable" \ No newline at end of file