Fix dump of sqlite #1639
|
@ -231,6 +231,7 @@ func (db *mssql) SQLType(c *schemas.Column) string {
|
||||||
} else if strings.EqualFold(c.Default, "false") {
|
} else if strings.EqualFold(c.Default, "false") {
|
||||||
c.Default = "0"
|
c.Default = "0"
|
||||||
}
|
}
|
||||||
|
return res
|
||||||
case schemas.Serial:
|
case schemas.Serial:
|
||||||
c.IsAutoIncrement = true
|
c.IsAutoIncrement = true
|
||||||
c.IsPrimaryKey = true
|
c.IsPrimaryKey = true
|
||||||
|
@ -270,8 +271,8 @@ func (db *mssql) SQLType(c *schemas.Column) string {
|
||||||
res = t
|
res = t
|
||||||
}
|
}
|
||||||
|
|
||||||
if res == schemas.Int {
|
if res == schemas.Int || res == schemas.Bit || res == schemas.DateTime {
|
||||||
return schemas.Int
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
hasLen1 := (c.Length > 0)
|
hasLen1 := (c.Length > 0)
|
||||||
|
|
135
engine.go
135
engine.go
|
@ -412,6 +412,82 @@ func (engine *Engine) DumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
|
||||||
return engine.dumpTables(tables, w, tp...)
|
return engine.dumpTables(tables, w, tp...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func formatColumnValue(dstDialect dialects.Dialect, d interface{}, col *schemas.Column) string {
|
||||||
|
if d == nil {
|
||||||
|
return "NULL"
|
||||||
|
}
|
||||||
|
|
||||||
|
if dq, ok := d.(bool); ok && (dstDialect.URI().DBType == schemas.SQLITE ||
|
||||||
|
dstDialect.URI().DBType == schemas.MSSQL) {
|
||||||
|
if dq {
|
||||||
|
return "1"
|
||||||
|
}
|
||||||
|
return "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
if col.SQLType.IsText() {
|
||||||
|
var v = fmt.Sprintf("%s", d)
|
||||||
|
return "'" + strings.Replace(v, "'", "''", -1) + "'"
|
||||||
|
} else if col.SQLType.IsTime() {
|
||||||
|
var v = fmt.Sprintf("%s", d)
|
||||||
|
if strings.HasSuffix(v, " +0000 UTC") {
|
||||||
|
return fmt.Sprintf("'%s'", v[0:len(v)-len(" +0000 UTC")])
|
||||||
|
} else if strings.HasSuffix(v, " +0000 +0000") {
|
||||||
|
return fmt.Sprintf("'%s'", v[0:len(v)-len(" +0000 +0000")])
|
||||||
|
}
|
||||||
|
return "'" + strings.Replace(v, "'", "''", -1) + "'"
|
||||||
|
} else if col.SQLType.IsBlob() {
|
||||||
|
if reflect.TypeOf(d).Kind() == reflect.Slice {
|
||||||
|
return fmt.Sprintf("%s", dstDialect.FormatBytes(d.([]byte)))
|
||||||
|
} else if reflect.TypeOf(d).Kind() == reflect.String {
|
||||||
|
return fmt.Sprintf("'%s'", d.(string))
|
||||||
|
}
|
||||||
|
} else if col.SQLType.IsNumeric() {
|
||||||
|
switch reflect.TypeOf(d).Kind() {
|
||||||
|
case reflect.Slice:
|
||||||
|
if col.SQLType.Name == schemas.Bool {
|
||||||
|
return fmt.Sprintf("%v", strconv.FormatBool(d.([]byte)[0] != byte('0')))
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s", string(d.([]byte)))
|
||||||
|
case reflect.Int16, reflect.Int8, reflect.Int32, reflect.Int64, reflect.Int:
|
||||||
|
if col.SQLType.Name == schemas.Bool {
|
||||||
|
v := reflect.ValueOf(d).Int() > 0
|
||||||
|
if dstDialect.URI().DBType == schemas.SQLITE {
|
||||||
|
if v {
|
||||||
|
return "1"
|
||||||
|
}
|
||||||
|
return "0"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%v", strconv.FormatBool(v))
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%v", d)
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
if col.SQLType.Name == schemas.Bool {
|
||||||
|
v := reflect.ValueOf(d).Uint() > 0
|
||||||
|
if dstDialect.URI().DBType == schemas.SQLITE {
|
||||||
|
if v {
|
||||||
|
return "1"
|
||||||
|
}
|
||||||
|
return "0"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%v", strconv.FormatBool(v))
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%v", d)
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("%v", d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s := fmt.Sprintf("%v", d)
|
||||||
|
if strings.Contains(s, ":") || strings.Contains(s, "-") {
|
||||||
|
if strings.HasSuffix(s, " +0000 UTC") {
|
||||||
|
return fmt.Sprintf("'%s'", s[0:len(s)-len(" +0000 UTC")])
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("'%s'", s)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
// dumpTables dump database all table structs and data to w with specify db type
|
// dumpTables dump database all table structs and data to w with specify db type
|
||||||
func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...schemas.DBType) error {
|
func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...schemas.DBType) error {
|
||||||
var dstDialect dialects.Dialect
|
var dstDialect dialects.Dialect
|
||||||
|
@ -424,7 +500,10 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
|
||||||
}
|
}
|
||||||
|
|
||||||
uri := engine.dialect.URI()
|
uri := engine.dialect.URI()
|
||||||
destURI := *uri
|
destURI := dialects.URI{
|
||||||
|
DBType: tp[0],
|
||||||
|
DBName: uri.DBName,
|
||||||
|
}
|
||||||
dstDialect.Init(&destURI)
|
dstDialect.Init(&destURI)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,59 +574,9 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
|
||||||
if col == nil {
|
if col == nil {
|
||||||
return errors.New("unknow column error")
|
return errors.New("unknow column error")
|
||||||
}
|
}
|
||||||
|
temp += "," + formatColumnValue(dstDialect, d, col)
|
||||||
if d == nil {
|
|
||||||
temp += ", NULL"
|
|
||||||
} else if col.SQLType.IsText() || col.SQLType.IsTime() {
|
|
||||||
var v = fmt.Sprintf("%s", d)
|
|
||||||
if strings.HasSuffix(v, " +0000 UTC") {
|
|
||||||
temp += fmt.Sprintf(", '%s'", v[0:len(v)-len(" +0000 UTC")])
|
|
||||||
} else {
|
|
||||||
temp += ", '" + strings.Replace(v, "'", "''", -1) + "'"
|
|
||||||
}
|
|
||||||
} else if col.SQLType.IsBlob() {
|
|
||||||
if reflect.TypeOf(d).Kind() == reflect.Slice {
|
|
||||||
temp += fmt.Sprintf(", %s", dstDialect.FormatBytes(d.([]byte)))
|
|
||||||
} else if reflect.TypeOf(d).Kind() == reflect.String {
|
|
||||||
temp += fmt.Sprintf(", '%s'", d.(string))
|
|
||||||
}
|
|
||||||
} else if col.SQLType.IsNumeric() {
|
|
||||||
switch reflect.TypeOf(d).Kind() {
|
|
||||||
case reflect.Slice:
|
|
||||||
if col.SQLType.Name == schemas.Bool {
|
|
||||||
temp += fmt.Sprintf(", %v", strconv.FormatBool(d.([]byte)[0] != byte('0')))
|
|
||||||
} else {
|
|
||||||
temp += fmt.Sprintf(", %s", string(d.([]byte)))
|
|
||||||
}
|
|
||||||
case reflect.Int16, reflect.Int8, reflect.Int32, reflect.Int64, reflect.Int:
|
|
||||||
if col.SQLType.Name == schemas.Bool {
|
|
||||||
temp += fmt.Sprintf(", %v", strconv.FormatBool(reflect.ValueOf(d).Int() > 0))
|
|
||||||
} else {
|
|
||||||
temp += fmt.Sprintf(", %v", d)
|
|
||||||
}
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
if col.SQLType.Name == schemas.Bool {
|
|
||||||
temp += fmt.Sprintf(", %v", strconv.FormatBool(reflect.ValueOf(d).Uint() > 0))
|
|
||||||
} else {
|
|
||||||
temp += fmt.Sprintf(", %v", d)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
temp += fmt.Sprintf(", %v", d)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
s := fmt.Sprintf("%v", d)
|
|
||||||
if strings.Contains(s, ":") || strings.Contains(s, "-") {
|
|
||||||
if strings.HasSuffix(s, " +0000 UTC") {
|
|
||||||
temp += fmt.Sprintf(", '%s'", s[0:len(s)-len(" +0000 UTC")])
|
|
||||||
} else {
|
|
||||||
temp += fmt.Sprintf(", '%s'", s)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
temp += fmt.Sprintf(", %s", s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_, err = io.WriteString(w, temp[2:]+");\n")
|
_, err = io.WriteString(w, temp[1:]+");\n")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,19 +93,23 @@ func TestDump(t *testing.T) {
|
||||||
assert.NoError(t, PrepareEngine())
|
assert.NoError(t, PrepareEngine())
|
||||||
|
|
||||||
type TestDumpStruct struct {
|
type TestDumpStruct struct {
|
||||||
Id int64
|
Id int64
|
||||||
Name string
|
Name string
|
||||||
|
IsMan bool
|
||||||
|
Created time.Time `xorm:"created"`
|
||||||
}
|
}
|
||||||
|
|
||||||
assertSync(t, new(TestDumpStruct))
|
assertSync(t, new(TestDumpStruct))
|
||||||
|
|
||||||
testEngine.Insert([]TestDumpStruct{
|
cnt, err := testEngine.Insert([]TestDumpStruct{
|
||||||
{Name: "1"},
|
{Name: "1", IsMan: true},
|
||||||
{Name: "2\n"},
|
{Name: "2\n"},
|
||||||
{Name: "3;"},
|
{Name: "3;"},
|
||||||
{Name: "4\n;\n''"},
|
{Name: "4\n;\n''"},
|
||||||
{Name: "5'\n"},
|
{Name: "5'\n"},
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, 5, cnt)
|
||||||
|
|
||||||
fp := fmt.Sprintf("%v.sql", testEngine.Dialect().URI().DBType)
|
fp := fmt.Sprintf("%v.sql", testEngine.Dialect().URI().DBType)
|
||||||
os.Remove(fp)
|
os.Remove(fp)
|
||||||
|
@ -116,7 +120,7 @@ func TestDump(t *testing.T) {
|
||||||
sess := testEngine.NewSession()
|
sess := testEngine.NewSession()
|
||||||
defer sess.Close()
|
defer sess.Close()
|
||||||
assert.NoError(t, sess.Begin())
|
assert.NoError(t, sess.Begin())
|
||||||
_, err := sess.ImportFile(fp)
|
_, err = sess.ImportFile(fp)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NoError(t, sess.Commit())
|
assert.NoError(t, sess.Commit())
|
||||||
|
|
||||||
|
@ -128,6 +132,49 @@ func TestDump(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDumpTables(t *testing.T) {
|
||||||
|
assert.NoError(t, PrepareEngine())
|
||||||
|
|
||||||
|
type TestDumpTableStruct struct {
|
||||||
|
Id int64
|
||||||
|
Name string
|
||||||
|
IsMan bool
|
||||||
|
Created time.Time `xorm:"created"`
|
||||||
|
}
|
||||||
|
|
||||||
|
assertSync(t, new(TestDumpTableStruct))
|
||||||
|
|
||||||
|
testEngine.Insert([]TestDumpTableStruct{
|
||||||
|
{Name: "1", IsMan: true},
|
||||||
|
{Name: "2\n"},
|
||||||
|
{Name: "3;"},
|
||||||
|
{Name: "4\n;\n''"},
|
||||||
|
{Name: "5'\n"},
|
||||||
|
})
|
||||||
|
|
||||||
|
fp := fmt.Sprintf("%v-table.sql", testEngine.Dialect().URI().DBType)
|
||||||
|
os.Remove(fp)
|
||||||
|
tb, err := testEngine.TableInfo(new(TestDumpTableStruct))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NoError(t, testEngine.(*xorm.Engine).DumpTablesToFile([]*schemas.Table{tb}, fp))
|
||||||
|
|
||||||
|
assert.NoError(t, PrepareEngine())
|
||||||
|
|
||||||
|
sess := testEngine.NewSession()
|
||||||
|
defer sess.Close()
|
||||||
|
assert.NoError(t, sess.Begin())
|
||||||
|
_, err = sess.ImportFile(fp)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NoError(t, sess.Commit())
|
||||||
|
|
||||||
|
for _, tp := range []schemas.DBType{schemas.SQLITE, schemas.MYSQL, schemas.POSTGRES, schemas.MSSQL} {
|
||||||
|
name := fmt.Sprintf("dump_%v-table.sql", tp)
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
assert.NoError(t, testEngine.(*xorm.Engine).DumpTablesToFile([]*schemas.Table{tb}, name, tp))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSetSchema(t *testing.T) {
|
func TestSetSchema(t *testing.T) {
|
||||||
assert.NoError(t, PrepareEngine())
|
assert.NoError(t, PrepareEngine())
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user