Fix dump/import bug #1603

Merged
lunny merged 5 commits from lunny/import_bug into master 2020-03-15 02:02:41 +00:00
4 changed files with 62 additions and 12 deletions
Showing only changes of commit 8a04b78ece - Show all commits

View File

@ -6,7 +6,6 @@ package xorm
import (
"bufio"
"bytes"
"context"
"database/sql"
"errors"
@ -1174,12 +1173,18 @@ func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) {
var lastError error
scanner := bufio.NewScanner(r)
var inSingleQuote bool
semiColSpliter := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
if i := bytes.IndexByte(data, ';'); i >= 0 {
return i + 1, data[0:i], nil
for i, b := range data {
if b == '\'' {
inSingleQuote = !inSingleQuote
}
if !inSingleQuote && b == ';' {
return i + 1, data[0:i], nil
}
}
// If we're at EOF, we have a final, non-terminated line. Return it.
if atEOF {

View File

@ -7,6 +7,9 @@ package xorm
import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
"time"
@ -64,3 +67,53 @@ func TestAutoTransaction(t *testing.T) {
assert.NoError(t, err)
assert.EqualValues(t, false, has)
}
func TestDump(t *testing.T) {
assert.NoError(t, prepareEngine())
type TestDumpStruct struct {
Id int64
Name string
}
assertSync(t, new(TestDumpStruct))
testEngine.Insert([]TestDumpStruct{
{Name: "1"},
{Name: "2\n"},
{Name: "3;"},
{Name: "4"},
{Name: "5'"},
})
fp := testEngine.Dialect().URI().DBName + ".sql"
os.Remove(fp)
assert.NoError(t, testEngine.DumpAllToFile(fp))
assert.NoError(t, prepareEngine())
_, err := testEngine.ImportFile(fp)
assert.NoError(t, err)
}
func TestImport(t *testing.T) {
assert.NoError(t, prepareEngine())
var sql = "/*Generated by xorm 2020-03-13 17:13:51, from sqlite3 to SQLITE3*/" +
"CREATE TABLE IF NOT EXISTS `test_dump_struct` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NULL);" +
"INSERT INTO `test_dump_struct` (`id`, `name`) VALUES (1, '1');" +
"INSERT INTO `test_dump_struct` (`id`, `name`) VALUES (2, '2;');" +
"INSERT INTO `test_dump_struct` (`id`, `name`) VALUES (3, '3''');" +
"INSERT INTO `test_dump_struct` (`id`, `name`) VALUES (4, '4\n\n');" +
"INSERT INTO `test_dump_struct` (`id`, `name`) VALUES (5, '5\n;\n');"
f, err := ioutil.TempFile(os.TempDir(), "dump_file.sql")
assert.NoError(t, err)
_, err = f.WriteString(sql)
assert.NoError(t, err)
info, err := f.Stat()
f.Close()
assert.NoError(t, err)
_, err = testEngine.ImportFile(filepath.Join(os.TempDir(), info.Name()))
assert.NoError(t, err)
}

View File

@ -92,6 +92,7 @@ type EngineInterface interface {
GetTableMapper() names.Mapper
GetTZDatabase() *time.Location
GetTZLocation() *time.Location
ImportFile(fp string) ([]sql.Result, error)
MapCacher(interface{}, caches.Cacher) error
NewSession() *Session
NoAutoTime() *Session

View File

@ -6,7 +6,6 @@ package xorm
import (
"fmt"
"os"
"testing"
"time"
@ -210,14 +209,6 @@ func TestCustomTableName(t *testing.T) {
assert.NoError(t, testEngine.CreateTables(c))
}
func TestDump(t *testing.T) {
assert.NoError(t, prepareEngine())
fp := testEngine.Dialect().URI().DBName + ".sql"
os.Remove(fp)
assert.NoError(t, testEngine.DumpAllToFile(fp))
}
type IndexOrUnique struct {
Id int64
Index int `xorm:"index"`