4 Komitmen 82437b97fc ... 94d127c7b3

Pembuat SHA1 Pesan Tanggal
  GTong 94d127c7b3 feat: 添加多结果集 8 bulan lalu
  cyj 7ffaab4e78 删除打印信息 8 bulan lalu
  cyj 420a1d52db 增加测试框架与测试用例 8 bulan lalu
  GTong a40aeada6f fix: 修改解析D协议多余buf.idx代码 9 bulan lalu
47 mengubah file dengan 2037 tambahan dan 2672 penghapusan
  1. 1 0
      .gitignore
  2. 2 10
      go.mod
  3. 22 0
      go_unit/unittest/Db/BeginTx_test.go
  4. 21 0
      go_unit/unittest/Db/Begin_test.go
  5. 24 0
      go_unit/unittest/Db/Close_test.go
  6. 22 0
      go_unit/unittest/Db/Conn_test.go
  7. 21 0
      go_unit/unittest/Db/Driver_test.go
  8. 70 0
      go_unit/unittest/Db/Exec/Exec_Insert_Binary_test.go
  9. 104 0
      go_unit/unittest/Db/Exec/Exec_Insert_Blob_test.go
  10. 183 0
      go_unit/unittest/Db/Exec/Exec_Insert_Char_test.go
  11. 140 0
      go_unit/unittest/Db/Exec/Exec_Insert_Clob_test.go
  12. 129 0
      go_unit/unittest/Db/Exec/Exec_Insert_Date_test.go
  13. 207 0
      go_unit/unittest/Db/Exec/Exec_Insert_Float_test.go
  14. 45 0
      go_unit/unittest/Db/Exec/Exec_Insert_Guid_test.go
  15. 132 0
      go_unit/unittest/Db/Exec/Exec_Insert_Int_test.go
  16. 98 0
      go_unit/unittest/Db/Exec/Exec_Insert_Interval1_test.go
  17. 101 0
      go_unit/unittest/Db/Exec/Exec_Insert_Interval2_test.go
  18. 188 0
      go_unit/unittest/Db/Exec/Exec_Insert_Json_test.go
  19. 134 0
      go_unit/unittest/Db/Exec/Exec_Insert_Xml_test.go
  20. 35 0
      go_unit/unittest/Db/Ping_test.go
  21. 18 0
      go_unit/unittest/Db/Prepare_test.go
  22. 215 0
      go_unit/unittest/Init.go
  23. 0 276
      main.go
  24. 0 1
      test/create_table_test.go
  25. 1 1
      xugu/xugu/xugu_buffer.go
  26. 2 1
      xugu/xugu/xugu_conn.go
  27. 12 11
      xugu/xugu/xugu_model.go
  28. 59 58
      xugu/xugu/xugu_parse.go
  29. 4 4
      xugu/xugu/xugu_result.go
  30. 40 7
      xugu/xugu/xugu_rows.go
  31. 3 1
      xugu/xugu/xugu_sock.go
  32. 4 4
      xugu/xugu/xugu_utils.go
  33. 0 92
      xugu/xugu_buffer.go
  34. 0 388
      xugu/xugu_conn.go
  35. 0 64
      xugu/xugu_connector.go
  36. 0 32
      xugu/xugu_define.go
  37. 0 50
      xugu/xugu_driver.go
  38. 0 229
      xugu/xugu_fields.go
  39. 0 82
      xugu/xugu_model.go
  40. 0 513
      xugu/xugu_parse.go
  41. 0 156
      xugu/xugu_parse_time.go
  42. 0 28
      xugu/xugu_result.go
  43. 0 166
      xugu/xugu_rows.go
  44. 0 130
      xugu/xugu_sock.go
  45. 0 143
      xugu/xugu_stmt.go
  46. 0 36
      xugu/xugu_tranx.go
  47. 0 189
      xugu/xugu_utils.go

+ 1 - 0
.gitignore

@@ -7,3 +7,4 @@ xugu_zhushi/
 协议.ini
 .vscode/
 xugu_bak/
+/.vs

+ 2 - 10
go.mod

@@ -1,11 +1,3 @@
-module xugu_go_driver
+module xugugodriver
 
-go 1.22.2
-
-require gorm.io/gorm v1.25.11
-
-require (
-	github.com/jinzhu/inflection v1.0.0 // indirect
-	github.com/jinzhu/now v1.1.5 // indirect
-	golang.org/x/text v0.14.0 // indirect
-)
+go 1.23.0

+ 22 - 0
go_unit/unittest/Db/BeginTx_test.go

@@ -0,0 +1,22 @@
+package unittest
+
+import (
+	"context"
+	"database/sql"
+	"fmt"
+	"testing"
+	"xugugodriver/go_unit/unittest"
+)
+
+func TestDbBeginTx(t *testing.T) {
+
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	_, begin_err := testdb.BeginTx(context.Background(), nil)
+	if begin_err != nil {
+		t.Errorf("TestDbBeginTx FAIL.")
+	}
+	testdb.Close()
+}

+ 21 - 0
go_unit/unittest/Db/Begin_test.go

@@ -0,0 +1,21 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"testing"
+	"xugugodriver/go_unit/unittest"
+)
+
+func TestDbBegin(t *testing.T) {
+
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	_, begin_err := testdb.Begin()
+	if begin_err != nil {
+		t.Errorf("TestDbBegin FAIL.")
+	}
+	testdb.Close()
+}

+ 24 - 0
go_unit/unittest/Db/Close_test.go

@@ -0,0 +1,24 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"testing"
+	"xugugodriver/go_unit/unittest"
+)
+
+func TestDbClose(t *testing.T) {
+
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	close_err := testdb.Close()
+	if close_err != nil {
+		t.Errorf("TestDbClose FAIL.")
+	}
+	_, beginerr := testdb.Begin()
+	if beginerr == nil {
+		t.Errorf("TestDbClose FAIL.")
+	}
+}

+ 22 - 0
go_unit/unittest/Db/Conn_test.go

@@ -0,0 +1,22 @@
+package unittest
+
+import (
+	"context"
+	"database/sql"
+	"fmt"
+	"testing"
+	"xugugodriver/go_unit/unittest"
+)
+
+func TestDbConn(t *testing.T) {
+
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	_, connerr := testdb.Conn(context.Background())
+	if connerr != nil {
+		t.Errorf("TestDbConn FAIL.")
+	}
+	testdb.Close()
+}

+ 21 - 0
go_unit/unittest/Db/Driver_test.go

@@ -0,0 +1,21 @@
+package unittest
+
+import (
+	"database/sql"
+	"testing"
+	"xugugodriver/go_unit/unittest"
+)
+
+func TestDbDriver(t *testing.T) {
+
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		t.Errorf("TestDbDriver FAIL.")
+	}
+	driver := testdb.Driver()
+	_, openerr := driver.Open(unittest.Dsn)
+	if openerr != nil {
+		t.Errorf("TestDbDriver FAIL.")
+	}
+	testdb.Close()
+}

+ 70 - 0
go_unit/unittest/Db/Exec/Exec_Insert_Binary_test.go

@@ -0,0 +1,70 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"testing"
+	"xugugodriver/go_unit/unittest"
+)
+
+func TestDbExec_Insert_Binary_NULL(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1001
+	testdb.Exec("delete GO_UNIT_BINARY_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_BINARY_DEAL VALUES(?,?,?,?)", rowid, nil, nil, nil)
+	var equalsql = fmt.Sprintf("select count(*) from GO_UNIT_BINARY_DEAL where id = %d and B1 IS NULL and B2 IS NULL and B3 IS NULL;", rowid)
+	var equalrow = testdb.QueryRow(equalsql)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Binary_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+// 可以插入不可以查询, b1导致了不能查询。
+func TestDbExec_Insert_Binary_0(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1002
+	b1 := []byte{0}
+	b2 := []byte{0}
+	b3 := []byte{0}
+
+	testdb.Exec("delete GO_UNIT_BINARY_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_BINARY_DEAL VALUES(?,?,?,?)", rowid, b1, b2, b3)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_BINARY_DEAL where id = ? and B1 = ? and B2 = ? and B3 = ?;", rowid, b1, b2, b3)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Binary_0 FAIL.")
+	}
+	testdb.Close()
+}
+
+// 可以插入不可以查询, b1导致了不能查询。
+func TestDbExec_Insert_Binary_byte(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1003
+	b1 := []byte{1}
+	b2 := []byte{0, 0, 1, 1, 0, 1, 1}
+	b3 := []byte{1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1}
+
+	testdb.Exec("delete GO_UNIT_BINARY_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_BINARY_DEAL VALUES(?,?,?,?)", rowid, b1, b2, b3)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_BINARY_DEAL where id = ? and B1 = ? and B2 = ? and B3 = ?;", rowid, b1, b2, b3)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Blob_0 FAIL.")
+	}
+	testdb.Close()
+}

+ 104 - 0
go_unit/unittest/Db/Exec/Exec_Insert_Blob_test.go

@@ -0,0 +1,104 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"testing"
+	"xugugodriver/go_unit/unittest"
+
+)
+
+func TestDbExec_Insert_Blob_NULL(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1001
+	testdb.Exec("delete GO_UNIT_BLOB_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_BLOB_DEAL VALUES(?,?)", rowid, nil)
+	var equalsql = fmt.Sprintf("select count(*) from GO_UNIT_BLOB_DEAL where id = %d and B1 IS NULL;", rowid)
+	var equalrow = testdb.QueryRow(equalsql)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Blob_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+// database/sql defaultCheckNamedValue 会把byte转int64 造成类型不符合
+func TestDbExec_Insert_Blob_0(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1002
+	b1 := []byte{0}
+	testdb.Exec("delete GO_UNIT_BLOB_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_BLOB_DEAL VALUES(?,?)", rowid, b1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_BLOB_DEAL where id = ? and B1 = ?;", rowid, b1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Blob_0 FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Blob_number(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1003
+	b1 := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}
+	testdb.Exec("delete GO_UNIT_BLOB_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_BLOB_DEAL VALUES(?,?)", rowid, b1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_BLOB_DEAL where id = ? and B1 = ?;", rowid, b1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Blob_0 FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Blob_char(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1004
+	b1 := []byte{'A', 'B', 'C', 'D', 'E', 'F', 'A', 'B', 'C', 'D', 'E', 'F'}
+	testdb.Exec("delete GO_UNIT_BLOB_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_BLOB_DEAL VALUES(?,?)", rowid, b1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_BLOB_DEAL where id = ? and B1 = ?;", rowid, b1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Blob_char FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Blob_big(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1005
+	var blob_size = 1024 * 1024 * 50
+	b1 := make([]byte, blob_size)
+	for i := 0; i < blob_size; i += 1 {
+		b1[i] = byte(i)
+	}
+	testdb.Exec("delete GO_UNIT_BLOB_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_BLOB_DEAL VALUES(?,?)", rowid, b1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_BLOB_DEAL where id = ? and B1 = ?;", rowid, b1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Blob_0 FAIL.")
+	}
+	testdb.Close()
+}

+ 183 - 0
go_unit/unittest/Db/Exec/Exec_Insert_Char_test.go

@@ -0,0 +1,183 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"strings"
+	"testing"
+	"xugugodriver/go_unit/unittest"
+)
+
+func TestDbExec_Insert_Char_NULL(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1001
+	testdb.Exec("delete GO_UNIT_CHAR_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_CHAR_DEAL VALUES(?,?,?,?)", rowid, nil, nil, nil)
+	var equalsql = fmt.Sprintf("select count(*) from GO_UNIT_CHAR_DEAL where id = %d and CH IS NULL AND CHN IS NULL AND VAR IS NULL;", rowid)
+	var equalrow = testdb.QueryRow(equalsql)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Char_EmptyString(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1002
+	var ch = ""
+	var chn = ""
+	var varch = ""
+	testdb.Exec("delete GO_UNIT_CHAR_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_CHAR_DEAL VALUES(?,?,?,?)", rowid, ch, chn, varch)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_CHAR_DEAL where id = ? and CH = ? AND CHN = ? AND VAR = ?;", rowid, ch, chn, varch)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Char_Blank(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1003
+	var ch = " "
+	var chn = " "
+	var varch = " "
+	testdb.Exec("delete GO_UNIT_CHAR_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_CHAR_DEAL VALUES(?,?,?,?)", rowid, ch, chn, varch)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_CHAR_DEAL where id = ? and CH = ? AND CHN = ? AND VAR = ?;", rowid, ch, chn, varch)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Char_English(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1004
+	var ch = "A"
+	var chn = "ABC"
+	var varch = "ABC"
+	testdb.Exec("delete GO_UNIT_CHAR_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_CHAR_DEAL VALUES(?,?,?,?)", rowid, ch, chn, varch)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_CHAR_DEAL where id = ? and CH = ? AND CHN = ? AND VAR = ?;", rowid, ch, chn, varch)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Char_Symbol(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1005
+	var ch = "\""
+	var chn = "\"!@#$%^&*()_+~"
+	var varch = "\"!@#$%^&*()_+~');"
+	testdb.Exec("delete GO_UNIT_CHAR_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_CHAR_DEAL VALUES(?,?,?,?)", rowid, ch, chn, varch)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_CHAR_DEAL where id = ? and CH = ? AND CHN = ? AND VAR = ?;", rowid, ch, chn, varch)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Char_Chinese(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1006
+	var ch = "中"
+	var chn = "中文"
+	var varch = "中文数据"
+	testdb.Exec("delete GO_UNIT_CHAR_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_CHAR_DEAL VALUES(?,?,?,?)", rowid, ch, chn, varch)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_CHAR_DEAL where id = ? and CH = ? AND CHN = ? AND VAR = ?;", rowid, ch, chn, varch)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Char_LongEnglish(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1007
+	var ch = "1"
+	var builder strings.Builder
+	for i := 0; i < 3; i++ {
+		builder.WriteString("0123456789")
+	}
+	var chn = builder.String()
+	builder.Reset()
+	for i := 0; i < 500; i++ {
+		builder.WriteString("0123456789")
+	}
+	var varch = builder.String()
+	testdb.Exec("delete GO_UNIT_CHAR_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_CHAR_DEAL VALUES(?,?,?,?)", rowid, ch, chn, varch)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_CHAR_DEAL where id = ? and CH = ? AND CHN = ? AND VAR = ?;", rowid, ch, chn, varch)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Char_LongChinese(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1007
+	var ch = "1"
+	var builder strings.Builder
+	for i := 0; i < 3; i++ {
+		builder.WriteString("零一二三四五六七八九")
+	}
+	var chn = builder.String()
+	builder.Reset()
+	for i := 0; i < 500; i++ {
+		builder.WriteString("零一二三四五六七八九")
+	}
+	var varch = builder.String()
+	testdb.Exec("delete GO_UNIT_CHAR_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_CHAR_DEAL VALUES(?,?,?,?)", rowid, ch, chn, varch)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_CHAR_DEAL where id = ? and CH = ? AND CHN = ? AND VAR = ?;", rowid, ch, chn, varch)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}

+ 140 - 0
go_unit/unittest/Db/Exec/Exec_Insert_Clob_test.go

@@ -0,0 +1,140 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"xugugodriver/go_unit/unittest"
+
+	"strings"
+	"testing"
+)
+
+func TestDbExec_Insert_Clob_NULL(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1001
+	testdb.Exec("delete GO_UNIT_CLOB_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_CLOB_DEAL VALUES(?,?)", rowid, nil, nil, nil)
+	var equalsql = fmt.Sprintf("select count(*) from GO_UNIT_CLOB_DEAL where id = %d and C1 IS NULL;", rowid)
+	var equalrow = testdb.QueryRow(equalsql)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Clob_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Clob_0(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1002
+	var c1 = ""
+	testdb.Exec("delete GO_UNIT_CLOB_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_CLOB_DEAL VALUES(?,?)", rowid, c1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_CLOB_DEAL where id = ? and C1 = ?;", rowid, c1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Clob_0 FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Clob_number(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1003
+	var c1 = "123456789"
+	testdb.Exec("delete GO_UNIT_CLOB_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_CLOB_DEAL VALUES(?,?)", rowid, c1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_CLOB_DEAL where id = ? and C1 = ?;", rowid, c1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Clob_number FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Clob_char(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1004
+	var c1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+	testdb.Exec("delete GO_UNIT_CLOB_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_CLOB_DEAL VALUES(?,?)", rowid, c1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_CLOB_DEAL where id = ? and C1 = ?;", rowid, c1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Clob_char FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Clob_symbol(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1005
+	var c1 = "!@#$%^&*()_+-={}[]''\""
+	testdb.Exec("delete GO_UNIT_CLOB_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_CLOB_DEAL VALUES(?,?)", rowid, c1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_CLOB_DEAL where id = ? and C1 = ?;", rowid, c1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Clob_symbol FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Clob_chinese(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1006
+	var c1 = "中文数据测试一二三四五六七八九十"
+	testdb.Exec("delete GO_UNIT_CLOB_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_CLOB_DEAL VALUES(?,?)", rowid, c1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_CLOB_DEAL where id = ? and C1 = ?;", rowid, c1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Clob_symbol FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Clob_bigchar(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1007
+	var builder strings.Builder
+	for i := 0; i < 5000; i++ {
+		builder.WriteString("中文数据测试一二三四五六七八九十")
+	}
+	var c1 = builder.String()
+	testdb.Exec("delete GO_UNIT_CLOB_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_CLOB_DEAL VALUES(?,?)", rowid, c1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_CLOB_DEAL where id = ? and C1 = ?;", rowid, c1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Clob_symbol FAIL.")
+	}
+	testdb.Close()
+}

+ 129 - 0
go_unit/unittest/Db/Exec/Exec_Insert_Date_test.go

@@ -0,0 +1,129 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"xugugodriver/go_unit/unittest"
+
+	"testing"
+	"time"
+)
+
+func TestDbExec_Insert_Date_NULL(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1001
+	testdb.Exec("delete GO_UNIT_DATE_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_DATE_DEAL VALUES(?,?,?,?,?,?,?,?)", rowid, nil, nil, nil, nil, nil, nil, nil)
+	var equalsql = fmt.Sprintf("select count(*) from GO_UNIT_DATE_DEAL where id = %d and DT IS NULL AND TM IS NULL AND TMZ IS NULL AND DTTM IS NULL AND DTTMZ IS NULL AND TS IS NULL AND TSZ IS NULL;", rowid)
+	var equalrow = testdb.QueryRow(equalsql)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Date_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+// 驱动time.Time 只会组装成YYYY-MM-DD HH:MM:SS的格式,DATE,time类型插入不进去。 需测试mysql
+func TestDbExec_Insert_Date_TimeMin(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1002
+	var dt, _ = time.Parse("2006-01-02", "0001-01-01")
+	var tm, _ = time.Parse("15:04:05", "00:00:00")
+	var tmz, _ = time.Parse("15:04:05", "00:00:00")
+	var date, _ = time.Parse("2006-01-02 15:04:05", "0001-01-01 00:00:00")
+	var datez, _ = time.Parse("2006-01-02 15:04:05", "0001-01-01 00:00:00")
+	var ts, _ = time.Parse("2006-01-02 15:04:05", "0001-01-01 00:00:00")
+	var tsz, _ = time.Parse("2006-01-02 15:04:05", "0001-01-01 00:00:00")
+	testdb.Exec("delete GO_UNIT_DATE_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_DATE_DEAL VALUES(?,?,?,?,?,?,?,?)", rowid, dt, tm, tmz, date, datez, ts, tsz)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_DATE_DEAL where id = ? and DT = ? AND TM = ? AND TMZ = ? AND DTTM = ? AND DTTMZ = ? AND TS = ? AND TSZ = ?;",
+		rowid, dt, tm, tmz, date, datez, ts, tsz)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Date_TimeMin FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Date_TimeMax(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1003
+	var dt, _ = time.Parse("2006-01-02 15:04:05", "9999-12-31 23:59:59.999")
+	var tm, _ = time.Parse("2006-01-02 15:04:05", "9999-12-31 23:59:59.999")
+	var tmz, _ = time.Parse("2006-01-02 15:04:05", "9999-12-31 23:59:59.999")
+	var date, _ = time.Parse("2006-01-02 15:04:05", "9999-12-31 23:59:59.999")
+	var datez, _ = time.Parse("2006-01-02 15:04:05", "9999-12-31 23:59:59.999")
+	var ts, _ = time.Parse("2006-01-02 15:04:05", "9999-12-31 23:59:59.999")
+	var tsz, _ = time.Parse("2006-01-02 15:04:05", "9999-12-31 23:59:59.999")
+	testdb.Exec("delete GO_UNIT_DATE_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_DATE_DEAL VALUES(?,?,?,?,?,?,?,?)", rowid, dt, tm, tmz, date, datez, ts, tsz)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_DATE_DEAL where id = ? and DT = ? AND TM = ? AND TMZ = ? AND DTTM = ? AND DTTMZ = ? AND TS = ? AND TSZ = ?;",
+		rowid, dt, tm, tmz, date, datez, ts, tsz)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Date_TimeMax FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Date_CharMin(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1004
+	var dt = "0001-01-01"
+	var tm = "00:00:00"
+	var tmz = "00:00:00"
+	var date = "0001-01-01 00:00:00"
+	var datez = "0001-01-01 00:00:00"
+	var ts = "0001-01-01 00:00:00"
+	var tsz = "0001-01-01 00:00:00"
+	testdb.Exec("delete GO_UNIT_DATE_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_DATE_DEAL VALUES(?,?,?,?,?,?,?,?)", rowid, dt, tm, tmz, date, datez, ts, tsz)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_DATE_DEAL where id = ? and DT = ? AND TM = ? AND TMZ = ? AND DTTM = ? AND DTTMZ = ? AND TS = ? AND TSZ = ?;",
+		rowid, dt, tm, tmz, date, datez, ts, tsz)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Date_CharMin FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Date_CharMax(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1005
+	var dt = "9999-12-31"
+	var tm = "23:59:59.999"
+	var tmz = "23:59:59.999"
+	var date = "9999-12-31 23:59:59.999"
+	var datez = "9999-12-31 23:59:59.999"
+	var ts = "9999-12-31 23:59:59.999"
+	var tsz = "9999-12-31 23:59:59.999"
+	testdb.Exec("delete GO_UNIT_DATE_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_DATE_DEAL VALUES(?,?,?,?,?,?,?,?)", rowid, dt, tm, tmz, date, datez, ts, tsz)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_DATE_DEAL where id = ? and DT = ? AND TM = ? AND TMZ = ? AND DTTM = ? AND DTTMZ = ? AND TS = ? AND TSZ = ?;",
+		rowid, dt, tm, tmz, date, datez, ts, tsz)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Date_CharMax FAIL.")
+	}
+	testdb.Close()
+}

+ 207 - 0
go_unit/unittest/Db/Exec/Exec_Insert_Float_test.go

@@ -0,0 +1,207 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"xugugodriver/go_unit/unittest"
+
+	"testing"
+)
+
+func TestDbExec_Insert_Float_NULL(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1001
+	testdb.Exec("delete GO_UNIT_FLOAT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_FLOAT_DEAL VALUES(?,?,?,?)", rowid, nil, nil, nil)
+	var equalsql = fmt.Sprintf("select count(*) from GO_UNIT_FLOAT_DEAL where id = %d and F1 IS NULL AND D1 IS NULL AND NUM IS NULL;", rowid)
+	var equalrow = testdb.QueryRow(equalsql)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Float_0(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1002
+	var f1 = 0.0
+	var d1 = 0.0
+	var num = 0.0
+	testdb.Exec("delete GO_UNIT_FLOAT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_FLOAT_DEAL VALUES(?,?,?,?)", rowid, f1, d1, num)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_FLOAT_DEAL where id = ? and f1 = ? AND d1 = ? AND num = ?;", rowid, f1, d1, num)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Float_1(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1003
+	var f1 = 1.0
+	var d1 = 1.0
+	var num = 1.0
+	testdb.Exec("delete GO_UNIT_FLOAT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_FLOAT_DEAL VALUES(?,?,?,?)", rowid, f1, d1, num)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_FLOAT_DEAL where id = ? and f1 = ? AND d1 = ? AND num = ?;", rowid, f1, d1, num)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Float_integerMax(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1004
+	var f1 = 999999.0
+	var d1 = 999999999999999.0
+	var num = 999999.0
+	testdb.Exec("delete GO_UNIT_FLOAT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_FLOAT_DEAL VALUES(?,?,?,?)", rowid, f1, d1, num)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_FLOAT_DEAL where id = ? and f1 = ? AND d1 = ? AND num = ?;", rowid, f1, d1, num)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Float_decimalMin(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1005
+	var f1 = 0.0000000001
+	var d1 = 0.0000000001
+	var num = 0.000001
+	testdb.Exec("delete GO_UNIT_FLOAT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_FLOAT_DEAL VALUES(?,?,?,?)", rowid, f1, d1, num)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_FLOAT_DEAL where id = ? and f1 = ? AND d1 = ? AND num = ?;", rowid, f1, d1, num)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Float_decimalMax(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1006
+	var f1 = 0.99999
+	var d1 = 0.9999999999
+	var num = 0.999999
+	testdb.Exec("delete GO_UNIT_FLOAT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_FLOAT_DEAL VALUES(?,?,?,?)", rowid, f1, d1, num)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_FLOAT_DEAL where id = ? and f1 = ? AND d1 = ? AND num = ?;", rowid, f1, d1, num)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Float_Minus1(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1007
+	var f1 = -1.0
+	var d1 = -1.0
+	var num = -1.0
+	testdb.Exec("delete GO_UNIT_FLOAT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_FLOAT_DEAL VALUES(?,?,?,?)", rowid, f1, d1, num)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_FLOAT_DEAL where id = ? and f1 = ? AND d1 = ? AND num = ?;", rowid, f1, d1, num)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Float_integerMin(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1008
+	var f1 = -999999.0
+	var d1 = -999999999999999.0
+	var num = -999999.0
+	testdb.Exec("delete GO_UNIT_FLOAT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_FLOAT_DEAL VALUES(?,?,?,?)", rowid, f1, d1, num)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_FLOAT_DEAL where id = ? and f1 = ? AND d1 = ? AND num = ?;", rowid, f1, d1, num)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Float_MinusDecimalMax(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1009
+	var f1 = -0.0000000001
+	var d1 = -0.0000000001
+	var num = -0.000001
+	testdb.Exec("delete GO_UNIT_FLOAT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_FLOAT_DEAL VALUES(?,?,?,?)", rowid, f1, d1, num)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_FLOAT_DEAL where id = ? and f1 = ? AND d1 = ? AND num = ?;", rowid, f1, d1, num)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Float_MinusDecimalMin(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1010
+	var f1 = -0.99999
+	var d1 = -0.9999999999
+	var num = -0.999999
+	testdb.Exec("delete GO_UNIT_FLOAT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_FLOAT_DEAL VALUES(?,?,?,?)", rowid, f1, d1, num)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_FLOAT_DEAL where id = ? and f1 = ? AND d1 = ? AND num = ?;", rowid, f1, d1, num)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}

+ 45 - 0
go_unit/unittest/Db/Exec/Exec_Insert_Guid_test.go

@@ -0,0 +1,45 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"xugugodriver/go_unit/unittest"
+
+	"testing"
+)
+
+func TestDbExec_Insert_Guid_NULL(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1001
+	testdb.Exec("delete GO_UNIT_GUID_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_GUID_DEAL VALUES(?,?)", rowid, nil)
+	var equalsql = fmt.Sprintf("select count(*) from GO_UNIT_GUID_DEAL where id = %d and G1 IS NULL;", rowid)
+	var equalrow = testdb.QueryRow(equalsql)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Guid_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Guid_char(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1002
+	var g1 = "0941BCBD12CF4DF18EB27AEF709B3624"
+	testdb.Exec("delete GO_UNIT_GUID_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_GUID_DEAL VALUES(?,?)", rowid, g1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_GUID_DEAL where id = ? and g1 = ?;", rowid, g1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Guid_char FAIL.")
+	}
+	testdb.Close()
+}

+ 132 - 0
go_unit/unittest/Db/Exec/Exec_Insert_Int_test.go

@@ -0,0 +1,132 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"testing"
+	"xugugodriver/go_unit/unittest"
+)
+
+func TestDbExec_Insert_Int_NULL(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1001
+	testdb.Exec("delete GO_UNIT_INT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_INT_DEAL VALUES(?,?,?,?,?)", rowid, nil, nil, nil, nil)
+	var equalsql = fmt.Sprintf("select count(*) from GO_UNIT_INT_DEAL where id = %d and TINY IS NULL AND SMALL IS NULL AND INTE IS NULL AND BIG IS NULL;", rowid)
+	var equalrow = testdb.QueryRow(equalsql)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Int_0(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1002
+	var tiny = 0
+	var small = 0
+	var inte = 0
+	var big = 0
+	testdb.Exec("delete GO_UNIT_INT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_INT_DEAL VALUES(?,?,?,?,?)", rowid, tiny, small, inte, big)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_INT_DEAL where id = ? and TINY = ? AND SMALL = ? AND INTE = ? and BIG = ?;", rowid, tiny, small, inte, big)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Int_1(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1003
+	var tiny = 1
+	var small = 1
+	var inte = 1
+	var big = 1
+	testdb.Exec("delete GO_UNIT_INT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_INT_DEAL VALUES(?,?,?,?,?)", rowid, tiny, small, inte, big)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_INT_DEAL where id = ? and TINY = ? AND SMALL = ? AND INTE = ? and BIG = ?;", rowid, tiny, small, inte, big)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Int_Minus1(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1004
+	var tiny = -1
+	var small = -1
+	var inte = -1
+	var big = -1
+	testdb.Exec("delete GO_UNIT_INT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_INT_DEAL VALUES(?,?,?,?,?)", rowid, tiny, small, inte, big)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_INT_DEAL where id = ? and TINY = ? AND SMALL = ? AND INTE = ? and BIG = ?;", rowid, tiny, small, inte, big)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Int_Max(t *testing.T) {
+
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1005
+	var tiny = 127
+	var small = 32767
+	var inte = 2147483647
+	var big = 9223372036854775807
+	testdb.Exec("delete GO_UNIT_INT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_INT_DEAL VALUES(?,?,?,?,?)", rowid, tiny, small, inte, big)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_INT_DEAL where id = ? and TINY = ? AND SMALL = ? AND INTE = ? and BIG = ?;", rowid, tiny, small, inte, big)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Int_Min(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1006
+	var tiny = -128
+	var small = -32768
+	var inte = -2147483648
+	var big = -9223372036854775808
+	testdb.Exec("delete GO_UNIT_INT_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_INT_DEAL VALUES(?,?,?,?,?)", rowid, tiny, small, inte, big)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_INT_DEAL where id = ? and TINY = ? AND SMALL = ? AND INTE = ? and BIG = ?;", rowid, tiny, small, inte, big)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Int_NULL FAIL.")
+	}
+	testdb.Close()
+}

+ 98 - 0
go_unit/unittest/Db/Exec/Exec_Insert_Interval1_test.go

@@ -0,0 +1,98 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"testing"
+	"xugugodriver/go_unit/unittest"
+)
+
+func TestDbExec_Insert_Interval1_NULL(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1001
+	testdb.Exec("delete GO_UNIT_INTERVAL1_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_INTERVAL1_DEAL VALUES(?,?,?,?,?,?,?)", rowid, nil, nil, nil, nil, nil, nil)
+	var equalsql = fmt.Sprintf("select count(*) from GO_UNIT_INTERVAL1_DEAL where id = %d and IY IS NULL AND IM IS NULL AND ITD IS NULL AND IH IS NULL AND IMIN IS NULL AND ITS IS NULL ;", rowid)
+	var equalrow = testdb.QueryRow(equalsql)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Interval1_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Interval1_0(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1002
+	var iy = 0
+	var im = 0
+	var itd = 0
+	var ih = 0
+	var imin = 0
+	var its = 0
+	testdb.Exec("delete GO_UNIT_INTERVAL1_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_INTERVAL1_DEAL VALUES(?,?,?,?,?,?,?)", rowid, iy, im, itd, ih, imin, its)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_INTERVAL1_DEAL where id = ? and iy = ? AND im = ? AND itd = ? AND ih = ? AND imin = ? AND iTS = ?;",
+		rowid, iy, im, itd, ih, imin, its)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Interval1_0 FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Interval1_Max(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1003
+	var iy = 9999
+	var im = 99999
+	var itd = 999999
+	var ih = 9999999
+	var imin = 99999999
+	var its = 999999999
+	testdb.Exec("delete GO_UNIT_INTERVAL1_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_INTERVAL1_DEAL VALUES(?,?,?,?,?,?,?)", rowid, iy, im, itd, ih, imin, its)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_INTERVAL1_DEAL where id = ? and iy = ? AND im = ? AND itd = ? AND ih = ? AND imin = ? AND iTS = ?;",
+		rowid, iy, im, itd, ih, imin, its)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Interval1_0 FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Interval1_Min(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1004
+	var iy = -9999
+	var im = -99999
+	var itd = -999999
+	var ih = -9999999
+	var imin = -99999999
+	var its = -999999999
+	testdb.Exec("delete GO_UNIT_INTERVAL1_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_INTERVAL1_DEAL VALUES(?,?,?,?,?,?,?)", rowid, iy, im, itd, ih, imin, its)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_INTERVAL1_DEAL where id = ? and iy = ? AND im = ? AND itd = ? AND ih = ? AND imin = ? AND iTS = ?;",
+		rowid, iy, im, itd, ih, imin, its)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Interval1_0 FAIL.")
+	}
+	testdb.Close()
+}

+ 101 - 0
go_unit/unittest/Db/Exec/Exec_Insert_Interval2_test.go

@@ -0,0 +1,101 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"testing"
+	"xugugodriver/go_unit/unittest"
+)
+
+func TestDbExec_Insert_Interval2_NULL(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1001
+	testdb.Exec("delete GO_UNIT_INTERVAL2_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_INTERVAL2_DEAL VALUES(?,?,?,?,?,?,?,?)", rowid, nil, nil, nil, nil, nil, nil, nil)
+	var equalsql = fmt.Sprintf("select count(*) from GO_UNIT_INTERVAL2_DEAL where id = %d and IY2M IS NULL AND ID2H IS NULL AND ID2M IS NULL AND ID2S IS NULL AND IH2M IS NULL AND IH2S IS NULL AND IM2S IS NULL;", rowid)
+	var equalrow = testdb.QueryRow(equalsql)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Interval1_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Interval2_0(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1002
+	var iytm = "0-0"
+	var id2h = "0 0"
+	var id2m = "0 0:0"
+	var id2s = "0 0:0:0"
+	var ihtm = "0:0"
+	var ihts = "0:0:0"
+	var imts = "0:0"
+	testdb.Exec("delete GO_UNIT_INTERVAL2_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_INTERVAL2_DEAL VALUES(?,?,?,?,?,?,?,?)", rowid, iytm, id2h, id2m, id2s, ihtm, ihts, imts)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_INTERVAL2_DEAL where id = ? and iy2m = ? AND id2h = ? AND id2m = ? AND id2s = ? AND ih2m = ? AND ih2s = ? AND im2s = ?;",
+		rowid, iytm, id2h, id2m, id2s, ihtm, ihts, imts)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Interval2_0 FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Interval2_Max(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1003
+	var iytm = "9999-11"
+	var id2h = "99999 23"
+	var id2m = "99999 23:59"
+	var id2s = "99999 23:59:59.999"
+	var ihtm = "999999:59"
+	var ihts = "9999999:59:59.999"
+	var imts = "9999999:59.999"
+	testdb.Exec("delete GO_UNIT_INTERVAL2_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_INTERVAL2_DEAL VALUES(?,?,?,?,?,?,?,?)", rowid, iytm, id2h, id2m, id2s, ihtm, ihts, imts)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_INTERVAL2_DEAL where id = ? and iy2m = ? AND id2h = ? AND id2m = ? AND id2s = ? AND ih2m = ? AND ih2s = ? AND im2s = ?;",
+		rowid, iytm, id2h, id2m, id2s, ihtm, ihts, imts)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Interval2_0 FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Interval2_Min(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1004
+	var iytm = "-9999-11"
+	var id2h = "-99999 23"
+	var id2m = "-99999 23:59"
+	var id2s = "-99999 23:59:59.999"
+	var ihtm = "-999999:59"
+	var ihts = "-9999999:59:59.999"
+	var imts = "-9999999:59.999"
+	testdb.Exec("delete GO_UNIT_INTERVAL2_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_INTERVAL2_DEAL VALUES(?,?,?,?,?,?,?,?)", rowid, iytm, id2h, id2m, id2s, ihtm, ihts, imts)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_INTERVAL2_DEAL where id = ? and iy2m = ? AND id2h = ? AND id2m = ? AND id2s = ? AND ih2m = ? AND ih2s = ? AND im2s = ?;",
+		rowid, iytm, id2h, id2m, id2s, ihtm, ihts, imts)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Interval2_0 FAIL.")
+	}
+	testdb.Close()
+}

+ 188 - 0
go_unit/unittest/Db/Exec/Exec_Insert_Json_test.go

@@ -0,0 +1,188 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"testing"
+	"xugugodriver/go_unit/unittest"
+)
+
+func TestDbExec_Insert_Json_NULL(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1001
+	testdb.Exec("delete GO_UNIT_JSON_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_JSON_DEAL VALUES(?,?)", rowid, nil)
+	var equalsql = fmt.Sprintf("select count(*) from GO_UNIT_JSON_DEAL where id = %d and j1 IS NULL;", rowid)
+	var equalrow = testdb.QueryRow(equalsql)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Guid_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Json_nullchar(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1002
+	var j1 = "null"
+	testdb.Exec("delete GO_UNIT_JSON_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_JSON_DEAL VALUES(?,?)", rowid, j1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_JSON_DEAL where id = ? and j1 = ?;", rowid, j1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Json_nullchar FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Json_truechar(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1003
+	var j1 = "true"
+	testdb.Exec("delete GO_UNIT_JSON_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_JSON_DEAL VALUES(?,?)", rowid, j1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_JSON_DEAL where id = ? and j1 = ?;", rowid, j1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Json_truechar FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Json_falsechar(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1004
+	var j1 = "false"
+	testdb.Exec("delete GO_UNIT_JSON_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_JSON_DEAL VALUES(?,?)", rowid, j1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_JSON_DEAL where id = ? and j1 = ?;", rowid, j1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Json_falsechar FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Json_1char(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1005
+	var j1 = "1"
+	testdb.Exec("delete GO_UNIT_JSON_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_JSON_DEAL VALUES(?,?)", rowid, j1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_JSON_DEAL where id = ? and j1 = ?;", rowid, j1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Json_1char FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Json_minus1char(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1006
+	var j1 = "-1"
+	testdb.Exec("delete GO_UNIT_JSON_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_JSON_DEAL VALUES(?,?)", rowid, j1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_JSON_DEAL where id = ? and j1 = ?;", rowid, j1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Json_minus1char FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Json_decimalchar(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1007
+	var j1 = "0.01"
+	testdb.Exec("delete GO_UNIT_JSON_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_JSON_DEAL VALUES(?,?)", rowid, j1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_JSON_DEAL where id = ? and j1 = ?;", rowid, j1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Json_decimalchar FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Json_chinese(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1008
+	var j1 = "\"中文数据测试\""
+	testdb.Exec("delete GO_UNIT_JSON_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_JSON_DEAL VALUES(?,?)", rowid, j1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_JSON_DEAL where id = ? and j1 = ?;", rowid, j1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Json_decimalchar FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Json_charlist(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1009
+	var j1 = "[\"abc\", true, false, 1, 1.1, null]"
+	testdb.Exec("delete GO_UNIT_JSON_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_JSON_DEAL VALUES(?,?)", rowid, j1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_JSON_DEAL where id = ? and j1 = ?;", rowid, j1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Json_decimalchar FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Json_chartuple(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1010
+	var j1 = "{\"key1\": \"value\", \"key2\": true, \"key3\": false, \"key4\": 1, \"key5\": 1.1, \"key6\": null}"
+	testdb.Exec("delete GO_UNIT_JSON_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_JSON_DEAL VALUES(?,?)", rowid, j1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_JSON_DEAL where id = ? and j1 = ?;", rowid, j1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Json_decimalchar FAIL.")
+	}
+	testdb.Close()
+}

+ 134 - 0
go_unit/unittest/Db/Exec/Exec_Insert_Xml_test.go

@@ -0,0 +1,134 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"testing"
+	"xugugodriver/go_unit/unittest"
+)
+
+func TestDbExec_Insert_Xml_NULL(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1001
+	testdb.Exec("delete GO_UNIT_Xml_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_Xml_DEAL VALUES(?,?)", rowid, nil)
+	var equalsql = fmt.Sprintf("select count(*) from GO_UNIT_Xml_DEAL where id = %d and x1 IS NULL;", rowid)
+	var equalrow = testdb.QueryRow(equalsql)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Xml_NULL FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Xml_string(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1002
+	var x1 = "<string>abc</string>"
+	testdb.Exec("delete GO_UNIT_Xml_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_Xml_DEAL VALUES(?,?)", rowid, x1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_Xml_DEAL where id = ? and x1 = ?;", rowid, x1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Xml_string FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Xml_stringchinese(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1003
+	var x1 = "<string>中文数据测试</string>"
+	testdb.Exec("delete GO_UNIT_Xml_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_Xml_DEAL VALUES(?,?)", rowid, x1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_Xml_DEAL where id = ? and x1 = ?;", rowid, x1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Xml_stringchinese FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Xml_interger(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1004
+	var x1 = "<int>11</int>"
+	testdb.Exec("delete GO_UNIT_Xml_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_Xml_DEAL VALUES(?,?)", rowid, x1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_Xml_DEAL where id = ? and x1 = ?;", rowid, x1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Xml_interger FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Xml_double(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1005
+	var x1 = "<double>11.1</double>"
+	testdb.Exec("delete GO_UNIT_Xml_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_Xml_DEAL VALUES(?,?)", rowid, x1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_Xml_DEAL where id = ? and x1 = ?;", rowid, x1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Xml_interger FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Xml_true(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1006
+	var x1 = "<bool>true</bool>"
+	testdb.Exec("delete GO_UNIT_Xml_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_Xml_DEAL VALUES(?,?)", rowid, x1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_Xml_DEAL where id = ? and x1 = ?;", rowid, x1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Xml_interger FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbExec_Insert_Xml_false(t *testing.T) {
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	var rowid = 1007
+	var x1 = "<bool>false</bool>"
+	testdb.Exec("delete GO_UNIT_Xml_DEAL where id = ?", rowid)
+	testdb.Exec("INSERT INTO GO_UNIT_Xml_DEAL VALUES(?,?)", rowid, x1)
+	var equalrow = testdb.QueryRow("select count(*) from GO_UNIT_Xml_DEAL where id = ? and x1 = ?;", rowid, x1)
+	var row_count int32
+	equalrow.Scan(&row_count)
+	if row_count != 1 {
+		t.Errorf("TestDbExec_Insert_Xml_interger FAIL.")
+	}
+	testdb.Close()
+}

+ 35 - 0
go_unit/unittest/Db/Ping_test.go

@@ -0,0 +1,35 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"xugugodriver/go_unit/unittest"
+
+	"testing"
+)
+
+func TestDbPing(t *testing.T) {
+
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	pingerr := testdb.Ping()
+	if pingerr != nil {
+		t.Errorf("TestDbPing FAIL.")
+	}
+	testdb.Close()
+}
+
+func TestDbPingErr(t *testing.T) {
+
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	testdb.Close()
+	pingerr := testdb.Ping()
+	if pingerr == nil {
+		t.Errorf("TestDbPing FAIL.")
+	}
+}

+ 18 - 0
go_unit/unittest/Db/Prepare_test.go

@@ -0,0 +1,18 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	"testing"
+	"xugugodriver/go_unit/unittest"
+)
+
+func TestDbPrepareSelect(t *testing.T) {
+
+	testdb, err := sql.Open("xugusql", unittest.Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	testdb.Prepare("select 1 from dual;")
+	testdb.Close()
+}

+ 215 - 0
go_unit/unittest/Init.go

@@ -0,0 +1,215 @@
+package unittest
+
+import (
+	"database/sql"
+	"fmt"
+	_ "xugugodriver/xugu"
+)
+
+var table_name = []string{
+	"GO_UNIT_INT",
+	"GO_UNIT_FLOAT",
+	"GO_UNIT_CHAR",
+	"GO_UNIT_DATE",
+	"GO_UNIT_INTERVAL1",
+	"GO_UNIT_INTERVAL2",
+	"GO_UNIT_BLOB",
+	"GO_UNIT_CLOB",
+	"GO_UNIT_BOOLEAN",
+	"GO_UNIT_BINARY",
+	"GO_UNIT_GUID",
+	"GO_UNIT_JSON",
+	"GO_UNIT_XML",
+	"GO_UNIT_TRANSATION",
+
+	"GO_UNIT_INT_DEAL",
+	"GO_UNIT_FLOAT_DEAL",
+	"GO_UNIT_CHAR_DEAL",
+	"GO_UNIT_DATE_DEAL",
+	"GO_UNIT_INTERVAL1_DEAL",
+	"GO_UNIT_INTERVAL2_DEAL",
+	"GO_UNIT_BLOB_DEAL",
+	"GO_UNIT_CLOB_DEAL",
+	"GO_UNIT_BOOLEAN_DEAL",
+	"GO_UNIT_BINARY_DEAL",
+	"GO_UNIT_GUID_DEAL",
+	"GO_UNIT_JSON_DEAL",
+	"GO_UNIT_XML_DEAL",
+}
+
+var create_table = []string{
+	"create table GO_UNIT_INT(ID INT PRIMARY KEY, TINY TINYINT, SMALL SMALLINT, INTE INTEGER, BIG BIGINT);",
+	"create table GO_UNIT_FLOAT(ID INT PRIMARY KEY, F1 FLOAT, D1 DOUBLE, NUM NUMERIC(12,6));",
+	"create table GO_UNIT_CHAR(ID INT PRIMARY KEY, CH CHAR,CHN CHAR(30), VAR VARCHAR);",
+	"create table GO_UNIT_DATE(ID INT PRIMARY KEY, DT DATE, TM TIME, TMZ TIME WITH TIME ZONE,DTTM DATETIME , DTTMZ DATETIME WITH TIME ZONE, TS TIMESTAMP, TSZ TIMESTAMP WITH TIME ZONE);",
+	"create table GO_UNIT_INTERVAL1(ID INT PRIMARY KEY, IY INTERVAL YEAR, IM INTERVAL MONTH, ITD INTERVAL DAY,IH INTERVAL HOUR,IMIN INTERVAL MINUTE,ITS INTERVAL SECOND);",
+	"create table GO_UNIT_INTERVAL2(ID INT PRIMARY KEY, IY2M INTERVAL YEAR TO MONTH, ID2H INTERVAL DAY TO HOUR,ID2M INTERVAL DAY TO MINUTE,ID2S INTERVAL DAY TO SECOND, IH2M INTERVAL HOUR TO MINUTE,IH2S INTERVAL HOUR TO SECOND,IM2S INTERVAL MINUTE TO SECOND);",
+	"create table GO_UNIT_BLOB(ID INT PRIMARY KEY, B1 BLOB)",
+	"create table GO_UNIT_CLOB(ID INT PRIMARY KEY, C1 CLOB)",
+	"create table GO_UNIT_BOOLEAN(ID INT PRIMARY KEY, B1 BOOLEAN);",
+	"create table GO_UNIT_BINARY(ID INT PRIMARY KEY, B1 BIT, B2 VARBIT, B3 BINARY);",
+	"create table GO_UNIT_GUID(ID INT PRIMARY KEY, G1 GUID);",
+	"create table GO_UNIT_JSON(ID INT PRIMARY KEY, J1 JSON)",
+	"create table GO_UNIT_XML(ID INT PRIMARY KEY, X1 XML)",
+	"create table GO_UNIT_TRANSATION(ID INT PRIMARY KEY, I1 INT)",
+
+	"create table GO_UNIT_INT_DEAL(ID INT PRIMARY KEY, TINY TINYINT, SMALL SMALLINT, INTE INTEGER, BIG BIGINT);",
+	"create table GO_UNIT_FLOAT_DEAL(ID INT PRIMARY KEY, F1 FLOAT, D1 DOUBLE, NUM NUMERIC(12,6));",
+	"create table GO_UNIT_CHAR_DEAL(ID INT PRIMARY KEY, CH CHAR,CHN CHAR(30), VAR VARCHAR);",
+	"create table GO_UNIT_DATE_DEAL(ID INT PRIMARY KEY, DT DATE, TM TIME, TMZ TIME WITH TIME ZONE,DTTM DATETIME , DTTMZ DATETIME WITH TIME ZONE, TS TIMESTAMP, TSZ TIMESTAMP WITH TIME ZONE);",
+	"create table GO_UNIT_INTERVAL1_DEAL(ID INT PRIMARY KEY, IY INTERVAL YEAR, IM INTERVAL MONTH, ITD INTERVAL DAY,IH INTERVAL HOUR,IMIN INTERVAL MINUTE,ITS INTERVAL SECOND);",
+	"create table GO_UNIT_INTERVAL2_DEAL(ID INT PRIMARY KEY, IY2M INTERVAL YEAR TO MONTH, ID2H INTERVAL DAY TO HOUR,ID2M INTERVAL DAY TO MINUTE,ID2S INTERVAL DAY TO SECOND, IH2M INTERVAL HOUR TO MINUTE,IH2S INTERVAL HOUR TO SECOND,IM2S INTERVAL MINUTE TO SECOND);",
+	"create table GO_UNIT_BLOB_DEAL(ID INT PRIMARY KEY, B1 BLOB)",
+	"create table GO_UNIT_CLOB_DEAL(ID INT PRIMARY KEY, C1 CLOB)",
+	"create table GO_UNIT_BOOLEAN_DEAL(ID INT PRIMARY KEY, B1 BOOLEAN);",
+	"create table GO_UNIT_BINARY_DEAL(ID INT PRIMARY KEY, B1 BIT, B2 VARBIT, B3 BINARY);",
+	"create table GO_UNIT_GUID_DEAL(ID INT PRIMARY KEY, G1 GUID);",
+	"create table GO_UNIT_JSON_DEAL(ID INT PRIMARY KEY, J1 JSON)",
+	"create table GO_UNIT_XML_DEAL(ID INT PRIMARY KEY, X1 XML)",
+}
+
+var insert_table = []string{
+	// GO_UNIT_INT
+	"INSERT INTO GO_UNIT_INT VALUES(1,NULL,NULL,NULL,NULL);",
+	"INSERT INTO GO_UNIT_INT VALUES(2,0,0,0,0);",
+	"INSERT INTO GO_UNIT_INT VALUES(3,1,1,1,1);",
+	"INSERT INTO GO_UNIT_INT VALUES(4,-1,-1,-1,-1);",
+	"INSERT INTO GO_UNIT_INT VALUES(5,127,32767,2147483647,9223372036854775807);",
+	"INSERT INTO GO_UNIT_INT VALUES(6,-128,-32768,-2147483648,-9223372036854775808);",
+
+	// GO_UNIT_FLOAT
+	"INSERT INTO GO_UNIT_FLOAT VALUES(1,NULL,NULL,NULL);",
+	"INSERT INTO GO_UNIT_FLOAT VALUES(2,0,0,0);",
+	"INSERT INTO GO_UNIT_FLOAT VALUES(3,1,1,1);",
+	"INSERT INTO GO_UNIT_FLOAT VALUES(4,999999,999999999999999,999999);",
+	"INSERT INTO GO_UNIT_FLOAT VALUES(5,0.0000000001,0.0000000001,0.000001);",
+	"INSERT INTO GO_UNIT_FLOAT VALUES(6,0.99999,0.9999999999,0.999999);",
+	"INSERT INTO GO_UNIT_FLOAT VALUES(7,-1,-1,-1);",
+	"INSERT INTO GO_UNIT_FLOAT VALUES(8,-999999,-999999999999999,-999999);",
+	"INSERT INTO GO_UNIT_FLOAT VALUES(9,-0.0000000001,-0.0000000001,-0.000001);",
+	"INSERT INTO GO_UNIT_FLOAT VALUES(10,-0.99999,-0.9999999999,-0.999999);",
+
+	// GO_UNIT_CHAR
+	"INSERT INTO GO_UNIT_CHAR VALUES(1,NULL,NULL,NULL);",
+	"INSERT INTO GO_UNIT_CHAR VALUES(2,'','','');",
+	"INSERT INTO GO_UNIT_CHAR VALUES(3,' ',' ',' ');",
+	"INSERT INTO GO_UNIT_CHAR VALUES(4,'A','ABC','ABC');",
+	"INSERT INTO GO_UNIT_CHAR VALUES(5,'\"','\"!@#$%^&*()_+~','\"!@#$%^&*()_+~');",
+	"INSERT INTO GO_UNIT_CHAR VALUES(6,'中','中文','中文数据');",
+	"INSERT INTO GO_UNIT_CHAR VALUES(7,'1',REPEAT('0123456789',3),REPEAT('0123456789',500));",
+	"INSERT INTO GO_UNIT_CHAR VALUES(8,'一',REPEAT('零一二三四五六七八九',3),REPEAT('零一二三四五六七八九',500));",
+
+	// GO_UNIT_DATE
+	"INSERT INTO GO_UNIT_DATE VALUES(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);",
+	"INSERT INTO GO_UNIT_DATE values(2,'0001-01-01','00:00:00','00:00:00 +0','0001-01-01 00:00:00','0001-01-01 00:00:00 +0','0001-01-01 00:00:00','0001-01-01 00:00:00 +0');",
+	"INSERT INTO GO_UNIT_DATE values(3,'9999-12-31','23:59:59.999','23:59:59.999 +12','9999-12-31 23:59:59.999','9999-12-31 23:59:59.999 +12','9999-12-31 23:59:59.999','9999-12-31 23:59:59.999 +12');",
+
+	// GO_UNIT_INTERVAL1
+	"INSERT INTO GO_UNIT_INTERVAL1 VALUES(1,NULL,NULL,NULL,NULL,NULL,NULL);",
+	"INSERT INTO GO_UNIT_INTERVAL1 VALUES(2,0,0,0,0,0,0);",
+	"INSERT INTO GO_UNIT_INTERVAL1 VALUES(3,9999,99999,999999,9999999,99999999,999999999);",
+	"INSERT INTO GO_UNIT_INTERVAL1 VALUES(4,-9999,-99999,-999999,-9999999,-99999999,-999999999);",
+
+	// GO_UNIT_INTERVAL2
+	"INSERT INTO GO_UNIT_INTERVAL2 VALUES(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL);",
+	"INSERT INTO GO_UNIT_INTERVAL2 VALUES(2,'0-0','0 0','0 0:0','0 0:0:0','0:0','0:0:0','0:0');",
+	"INSERT INTO GO_UNIT_INTERVAL2 VALUES(3,'9999-11','99999 23','99999 23:59','99999 23:59:59.999','999999:59','9999999:59:59.999','9999999:59.999');",
+	"INSERT INTO GO_UNIT_INTERVAL2 VALUES(4,'-9999-11','-99999 23','-99999 23:59','-99999 23:59:59.999','-999999:59','-9999999:59:59.999','-9999999:59.999');",
+
+	// GO_UNIT_BLOB
+	"INSERT INTO GO_UNIT_BLOB VALUES(1,NULL);",
+	"INSERT INTO GO_UNIT_BLOB VALUES(2,'');",
+	"INSERT INTO GO_UNIT_BLOB VALUES(3,'123456789');",
+	"INSERT INTO GO_UNIT_BLOB VALUES(4,'ABCDEFABCDEF');",
+	// 插入500MB  是否要每次都进行插入呢。影响效率
+	"INSERT INTO GO_UNIT_BLOB VALUES(5,REPEAT('0123456789ABCDEF',33554420));",
+
+	// GO_UNIT_CLOB
+	"INSERT INTO GO_UNIT_CLOB VALUES(1,NULL);",
+	"INSERT INTO GO_UNIT_CLOB VALUES(2,'');",
+	"INSERT INTO GO_UNIT_CLOB VALUES(3,'123456789');",
+	"INSERT INTO GO_UNIT_CLOB VALUES(4,'ABCDEFGHIJKLMNOPQRSTUVWXYZ');",
+	"INSERT INTO GO_UNIT_CLOB VALUES(5,'!@#$%^&*()_+-={}[]''\"');",
+	"INSERT INTO GO_UNIT_CLOB VALUES(6,'中文数据测试一二三四五六七八九十');",
+	"INSERT INTO GO_UNIT_CLOB VALUES(7,REPEAT('1234567890中文数据测试一二三四五六七八九十',8388605));",
+
+	// GO_UNIT_BOOLEAN
+	"INSERT INTO GO_UNIT_BOOLEAN VALUES(1,NULL);",
+	"INSERT INTO GO_UNIT_BOOLEAN VALUES(2,'');",
+	"INSERT INTO GO_UNIT_BOOLEAN VALUES(3,TRUE);",
+	"INSERT INTO GO_UNIT_BOOLEAN VALUES(4,FALSE);",
+	// 此处还有一个UNKNOW 的插入,暂时未找到语法,用  "SELECT 1 = nulL FROM dual;" 代替。
+
+	// GO_UNIT_BINARY
+	"INSERT INTO GO_UNIT_BINARY VALUES(1,NULL,NULL,NULL);",
+	"INSERT INTO GO_UNIT_BINARY VALUES(2,'','','');",
+	"INSERT INTO GO_UNIT_BINARY VALUES(3,'0','0','0');",
+	"INSERT INTO GO_UNIT_BINARY VALUES(4,'1','0011011','000001010011100101110111');",
+
+	// GO_UNIT_GUID
+	"INSERT INTO GO_UNIT_GUID VALUES(1,NULL);",
+	"INSERT INTO GO_UNIT_GUID VALUES(2,'0941BCBD12CF4DF18EB27AEF709B3624');",
+
+	// GO_UNIT_JSON
+	"INSERT INTO GO_UNIT_JSON VALUES(1,NULL);",
+	"INSERT INTO GO_UNIT_JSON VALUES(2,'null');",
+	"INSERT INTO GO_UNIT_JSON VALUES(3,'true');",
+	"INSERT INTO GO_UNIT_JSON VALUES(4,'false');",
+	"INSERT INTO GO_UNIT_JSON VALUES(5,'1');",
+	"INSERT INTO GO_UNIT_JSON VALUES(6,'-1');",
+	"INSERT INTO GO_UNIT_JSON VALUES(7,'0.01');",
+	"INSERT INTO GO_UNIT_JSON VALUES(8,'\"中文数据测试\"');",
+	"INSERT INTO GO_UNIT_JSON VALUES(9,'[\"abc\", true, false, 1, 1.1, null]');",
+	"INSERT INTO GO_UNIT_JSON VALUES(10,'{\"key1\": \"value\", \"key2\": true, \"key3\": false, \"key4\": 1, \"key5\": 1.1, \"key6\": null}');",
+
+	// GO_UNIT_XML
+	"INSERT INTO GO_UNIT_XML VALUES(1,NULL);",
+	"INSERT INTO GO_UNIT_XML VALUES(2,'<string>abc</string>');",
+	"INSERT INTO GO_UNIT_XML VALUES(3,'<string>中文数据测试</string>');",
+	"INSERT INTO GO_UNIT_XML VALUES(4,'<int>11</int>');",
+	"INSERT INTO GO_UNIT_XML VALUES(5,'<double>11.1</double>');",
+	"INSERT INTO GO_UNIT_XML VALUES(6,'<bool>true</bool>');",
+	"INSERT INTO GO_UNIT_XML VALUES(7,'<bool>false</bool>');",
+}
+
+var db *sql.DB
+var ip = "192.168.2.216"
+var port = "5138"
+var database = "SYSTEM"
+var user = "SYSDBA"
+var pwd = "SYSDBA"
+var char_set = "UTF8"
+var Dsn = fmt.Sprintf("IP=%s;Port=%s;DB=%s;User=%s;PWD=%s;CHAR_SET=%s;",
+	ip, port, database, user, pwd, char_set)
+
+// 是否需要初始化数据库环境
+var need_inti = false
+
+func init() {
+
+	var err error
+	db, err = sql.Open("xugusql", Dsn)
+	if err != nil {
+		fmt.Printf("[ERROR] %s\n", err.Error())
+	}
+	if need_inti {
+		// 删除表
+		for _, value := range table_name {
+			var table_alive = fmt.Sprintf("select count(*) from all_tables where table_name = '%s'", value)
+			var row = db.QueryRow(table_alive)
+			var table_count int32
+			row.Scan(&table_count)
+			if table_count > 0 { // 暂时设置成1 不需要反复插入
+				var drop_sql = fmt.Sprintf("drop table %s", value)
+				db.Exec(drop_sql)
+			}
+		}
+		// 重新创建表
+		for _, value := range create_table {
+			db.Exec(value)
+		}
+		for _, insertsql := range insert_table {
+			db.Exec(insertsql)
+		}
+	}
+}

+ 0 - 276
main.go

@@ -1,281 +1,5 @@
 package main
 
-import (
-	"database/sql"
-	"fmt"
-	"log"
-	"os"
-	"sync"
-	"time"
-	_ "xugu_go_driver/xugu"
-)
-
-func main3() {
-	db, err := sql.Open("xugusql", "IP=192.168.2.216;DB=SYSTEM;User=SYSDBA;PWD=SYSDBA;Port=15138;AUTO_COMMIT=on;CHAR_SET=UTF8")
-	if err != nil {
-		log.Fatal("err ", err)
-	}
-	// if err := db.Ping(); err != nil {
-	// 	log.Fatal("err ping ", err)
-	// }
-
-	// rows, err := db.Query("select * from dual")
-	// if err != nil {
-	// 	log.Fatal(err)
-	// }
-	// // rows, err := db.Query("select * from test1 where id = ?;", 4)
-	// // if err != nil {
-	// // 	log.Fatal(err)
-	// // }
-	// var cols []string
-	// cols, err = rows.Columns()
-	// if err != nil {
-	// 	log.Fatal(err)
-	// }
-	// fmt.Println("cols: ", cols)
-	// pvals := make([]interface{}, len(cols))
-	// for key, _ := range pvals {
-	// 	dest := make([]byte, 216)
-	// 	pvals[key] = &dest
-	// } /* end for */
-	// for rows.Next() {
-	// 	err = rows.Scan(pvals...)
-	// 	if err != nil {
-	// 		log.Fatal(err)
-	// 	}
-	// 	for _, v := range pvals {
-	// 		fmt.Printf("输出 %s\t", string(*(v.(*[]byte))))
-	// 	}
-	// 	fmt.Printf("\n")
-	// }
-	//  rows.Close()
-
-	// stmt, err := db.Prepare("select * from test1 where id = ?")
-	// if err != nil {
-	// 	log.Fatal(err)
-	// }
-	// stmt.Exec(2)
-	// ret, err := db.Exec("insert into test1 (id) values (9)")
-	// if err != nil {
-	// 	log.Fatal(err)
-	// }
-	// ret.LastInsertId()
-
-	// stmt, err := db.Prepare("select * from test1 where id = ?")
-	// if err != nil {
-	// 	log.Fatal(err)
-	// }
-	// rows, err := stmt.Query(5)
-	// if err != nil {
-	// 	log.Fatal(err)
-	// }
-	// var cols []string
-	// cols, err = rows.Columns()
-	// if err != nil {
-	// 	log.Fatal(err)
-	// }
-	// fmt.Println("cols: ", cols)
-	// pvals := make([]interface{}, len(cols))
-	// for key, _ := range pvals {
-	// 	dest := make([]byte, 216)
-	// 	pvals[key] = &dest
-	// } /* end for */
-	// for rows.Next() {
-	// 	err = rows.Scan(pvals...)
-	// 	if err != nil {
-	// 		log.Fatal(err)
-	// 	}
-	// 	for _, v := range pvals {
-	// 		fmt.Printf("输出 %s\t", string(*(v.(*[]byte))))
-	// 	}
-	// 	fmt.Printf("\n")
-	// }
-	// rows.Close()
-
-	//	db.Exec("set auto_commit on;")
-
-	// rows, err := db.Query("select * from gotab2;")
-	// if err != nil {
-	// 	fmt.Printf("[ERROR] %s\n", err.Error())
-	// 	return
-	// }
-
-	// column, err := rows.Columns()
-	// if err != nil {
-	// 	fmt.Printf("[ERROR] %s\n", err.Error())
-	// 	return
-	// }
-	// rows_value := make([]interface{}, len(column))
-	// for key, _ := range rows_value {
-	// 	dest := make([]byte, 216)
-	// 	rows_value[key] = &dest
-	// }
-
-	// for rows.Next() {
-	// 	rows.Scan(rows_value...)
-
-	// 	for _, v := range rows_value {
-	// 		fmt.Printf("结果: %s\t", string(*(v.(*[]byte))))
-	// 	}
-	// 	fmt.Printf("\n")
-	// }
-
-	// rows.Close()
-	// db.Close()
-	// 打开文件以写入
-	file, err := os.OpenFile("output.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
-	if err != nil {
-		log.Fatalf("无法打开文件: %v", err)
-	}
-	defer file.Close()
-
-	// 创建一个新的日志记录器,将输出写入文件
-	logger := log.New(file, "", log.LstdFlags)
-	var wg sync.WaitGroup
-	const numGoroutines = 10000
-
-	for i := 0; i < numGoroutines; i++ {
-		wg.Add(1)
-		go func(i int) {
-			defer wg.Done()
-			processQuery(db, i, logger)
-		}(i)
-	}
-
-	wg.Wait()
-	fmt.Println("所有goroutine已完成")
-	defer db.Close()
-}
-
-func processQuery(db *sql.DB, id int, logger *log.Logger) {
-	fmt.Printf("goroutine %d 开始\n", id)
-	//db.Query("select 1 from dual;")
-	rows, err := db.Query("select * from gotab3;")
-	if err != nil {
-		fmt.Printf("[ERROR] %s\n", err.Error())
-		logger.Printf("[ERROR] %s\n", err.Error())
-		return
-	}
-	defer rows.Close()
-
-	column, err := rows.Columns()
-	if err != nil {
-		fmt.Printf("[ERROR] %s\n", err.Error())
-		logger.Printf("[ERROR] %s\n", err.Error())
-		return
-	}
-
-	rowsValue := make([]interface{}, len(column))
-	for key := range rowsValue {
-		dest := make([]byte, 100000)
-		rowsValue[key] = &dest
-	}
-
-	for rows.Next() {
-		err := rows.Scan(rowsValue...)
-		if err != nil {
-			fmt.Printf("[ERROR] %s\n", err.Error())
-			logger.Printf("[ERROR] %s\n", err.Error())
-			return
-		}
-
-		for _, v := range rowsValue {
-			sss := []byte(*(v.(*[]byte)))
-			v = sss
-		}
-	}
-	//time.Sleep(time.Second * 100)
-	logger.Println("goroutine %d 完成\n", id)
-	fmt.Printf("goroutine %d 完成\n", id)
-}
-
-type UserInfo struct {
-	Id        int
-	UniqueID  string
-	Username  string
-	Account   string
-	Password  string
-	Telephone string
-	Email     string
-	Role      string
-	GroupId   sql.NullInt32
-}
-type LicenseApplication struct {
-	Creator                   string // 创建人
-	ApplicationDate           string //申请日期
-	AssociatedProject         string // 关联项目
-	SalesPerson               string //销售人员
-	SalesEmail                string // 销售接收邮箱
-	SupportPerson             string //技服人员
-	SupportEmail              string // 技服接收邮箱
-	TotalNodes                string //总节点数
-	Company                   string //使用单位
-	ProductName               string // 产品名称
-	Version                   string //版本
-	NodeCount                 string //节点数
-	Processor                 string //处理器
-	OperatingSystem           string //操作系统
-	MasterMacAddress          string // 主MasterMac地址
-	SecondaryMasterMacAddress string // 副MasterMac地址
-}
-
-type LicenseInfo struct {
-	ID           int          `json:"id"`
-	UserID       int          `json:"user_id"`
-	UpUser       string       `json:"up_user"`
-	UpTime       sql.NullTime `json:"up_time"`
-	DelTime      sql.NullTime `json:"del_time"`
-	License1     string
-	License2     string
-	LicenseFlage string
-	UniqueID     string
-	LicenseApplication
-}
-
 func main() {
 
-	db, err := sql.Open("xugusql", "IP=127.0.0.1;DB=SYSTEM;User=SYSDBA;PWD=SYSDBA;Port=5138;AUTO_COMMIT=on;CHAR_SET=UTF8")
-	if err != nil {
-		log.Fatal("err ", err)
-	}
-	query := fmt.Sprintf(`
-				 select ID,UNIQUEID,USERNAME,Account,PASSWORD,TELEPHONE,EMAIL,ROLE,GroupId  from lic_USER where id = ?;`)
-
-	rows, err := db.Query(query, 11)
-	if err != nil {
-		fmt.Println("query data: %v", err)
-		//return nil, 0, fmt.Errorf("query error: %v", err)
-	}
-	defer rows.Close()
-	var results []UserInfo
-	for rows.Next() {
-		var li UserInfo
-
-		err = rows.Scan(
-			&li.Id,
-			&li.UniqueID,
-			&li.Username,
-			&li.Account,
-			&li.Password,
-			&li.Telephone,
-			&li.Email,
-			&li.Role,
-			&li.GroupId,
-		)
-
-		if err != nil {
-			fmt.Println("scan row: %v", err)
-			//	return nil, fmt.Errorf("scan row: %v", err)
-			//return nil, 0, fmt.Errorf("scan row error: %v", err)
-		}
-		results = append(results, li)
-	}
-
-	if err = rows.Err(); err != nil {
-		//return nil, 0, fmt.Errorf("rows error: %v", err)
-	}
-	fmt.Printf("results123 %#v", results)
-
-	db.SetConnMaxLifetime(time.Minute * 3)
-
 }

+ 0 - 1
test/create_table_test.go

@@ -4,7 +4,6 @@ import (
 	"database/sql"
 	"fmt"
 	"testing"
-	_ "xugu_go_driver/xugu"
 )
 
 var crea = []string{

+ 1 - 1
xugu/xugu/xugu_buffer.go

@@ -27,7 +27,7 @@ func newBuffer(nc net.Conn) buffer {
 }
 
 func (b *buffer) peekChar() byte {
-	if b.idx >= int64(len(b.buf)) {
+	if b.idx > int64(len(b.buf[b.idx:b.length])) {
 		b.readNext(1, false)
 		b.idx-- //peekchar 只查看当前字符,不移动指针,但是readNext会移动指针,所以需要-1
 	}

+ 2 - 1
xugu/xugu/xugu_conn.go

@@ -119,12 +119,13 @@ func (xgConn *xuguConn) Query(sql string,
 	if err != nil {
 		return nil, err
 	}
-
+	//fmt.Println("驱动接收消息:", aR)
 	switch aR.rt {
 	case selectResult:
 
 		rows := &xuguRows{
 			rows_conn: xgConn,
+			aR:        aR,
 			results:   aR.s,
 			colIdx:    0,
 			prepared:  false,

+ 12 - 11
xugu/xugu/xugu_model.go

@@ -68,15 +68,16 @@ type ArgDescri struct {
 }
 
 type allResult struct {
-	rt msgType
-	s  *SelectResult
-	i  *InsertResult
-	u  *UpdateResult
-	d  *DeleteResult
-	p  *ProcRet
-	o  *OutParamRet
-	e  *ErrInfo
-	w  *WarnInfo
-	m  *Message
-	f  *FormArgDescri
+	rt   msgType
+	s    *SelectResult
+	i    *InsertResult
+	u    *UpdateResult
+	d    *DeleteResult
+	p    *ProcRet
+	o    *OutParamRet
+	e    *ErrInfo
+	w    *WarnInfo
+	m    *Message
+	f    *FormArgDescri
+	next *allResult
 }

+ 59 - 58
xugu/xugu/xugu_parse.go

@@ -110,14 +110,24 @@ func assertParamType(dV driver.Value, values *[]xuguValue) error {
 
 func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 	var err error
-	aR := allResult{}
+	i := 0
+	//aR := allResult{}
+	aRPoint := &allResult{}
+	aR := aRPoint
 	for {
 		char := readBuf.peekChar()
+		if i != 0 {
+			re := &allResult{}
+			aR.next = re
+			aR = re
+		}
+		i++
 		switch char {
 
 		case 'K':
 			readBuf.reset()
-			return &aR, nil
+			fmt.Printf("这他妈的 %#v \n 他们2222  %#v \n", aRPoint.s, aRPoint.next)
+			return aRPoint, nil
 
 		case '$':
 			readBuf.idx++
@@ -125,14 +135,14 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 				return nil, err
 			}
 			aR.rt = formArgDescri
-			return &aR, err
+			//return &aR, err
 		case 'A':
 			readBuf.idx++
 			if aR.s, err = parseSelectResult(readBuf); err != nil {
 				return nil, err
 			}
 			aR.rt = selectResult
-			return &aR, err
+		//	return &aR, err
 
 		case 'I':
 			readBuf.idx++
@@ -140,7 +150,7 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 				return nil, err
 			}
 			aR.rt = insertResult
-			return &aR, err
+			//return &aR, err
 
 		case 'U':
 			readBuf.idx++
@@ -148,16 +158,15 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 				return nil, err
 			}
 			aR.rt = updateResult
-			return &aR, err
+			//return &aR, err
 
 		case 'D':
-			readBuf.idx++
 			readBuf.idx++
 			if aR.d, err = parseDeleteResult(readBuf); err != nil {
 				return nil, err
 			}
 			aR.rt = deleteResult
-			return &aR, err
+		//	return &aR, err
 
 		case 'E':
 			readBuf.idx++
@@ -167,7 +176,7 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 			}
 			pConn.errStr = aR.e.ErrStr
 			aR.rt = errInfo
-			return &aR, err
+			//return &aR, err
 
 		case 'W':
 			readBuf.idx++
@@ -175,7 +184,7 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 				return nil, err
 			}
 			aR.rt = warnInfo
-			return &aR, err
+			//return &aR, err
 
 		case 'M':
 			readBuf.idx++
@@ -183,7 +192,7 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 				return nil, err
 			}
 			aR.rt = message
-			return &aR, err
+			//return &aR, err
 
 		default:
 			return nil, errors.New("parseMsg: unknown message type")
@@ -194,7 +203,7 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 func parseSelectResult(readBuf *buffer) (*SelectResult, error) {
 	data := &SelectResult{}
 
-	char := readBuf.peekChar()
+	var char byte
 
 	//Field_Num
 	fn, err := readBuf.readNext(4, true)
@@ -223,7 +232,8 @@ func parseSelectResult(readBuf *buffer) (*SelectResult, error) {
 		if err != nil {
 			return nil, err
 		}
-		field.FieldName = string(Field_Name)
+		parts := strings.Split(string(Field_Name), ".")
+		field.FieldName = parts[len(parts)-1]
 
 		//Field_DType:
 		Field_DType, err := readBuf.readNext(4, true)
@@ -264,64 +274,55 @@ func parseSelectResult(readBuf *buffer) (*SelectResult, error) {
 
 	//获取字段的行值,并判断类型
 	// 使用 Peek 方法检查下一个字节是否为'R'或'K'
+	for {
+		char = readBuf.peekChar()
+		//readBuf.idx++
+		if char == 'K' {
+			return data, nil
+		} else if char == 'R' { //接收字段信息后不是k 那一定是 R
+			fmt.Println("读取字段值")
 
-	char = readBuf.peekChar()
-	readBuf.idx++
-	if char == 'K' {
-		return data, nil
-	} else if char == 'R' {
-		colIdx := 0
-		//typeIdx := 0
-
-		for {
-			col := FieldValue{}
-			//获取数据的大小
-			Col_len, err := readBuf.readNext(4, true)
+			colIdx := 0
+			//typeIdx := 0
+			readBuf.idx++
+			for i := 0; i < int(Field_Num); i++ {
+				col := FieldValue{}
+				//获取数据的大小
+				Col_len, err := readBuf.readNext(4, true)
+				if err != nil {
+					return nil, err
+				}
+				col.Col_len = binary.LittleEndian.Uint32(Col_len)
+
+				//获取数据的值
+				col.Col_Data, err = readBuf.readNext(int(col.Col_len), false)
+				if err != nil {
+					return nil, err
+				}
+
+				data.Values[colIdx] = append(data.Values[colIdx], col)
+				colIdx++
+
+			} //for end
+
+		} else if char == '$' {
+			fad, err := parseFormArgDescri(readBuf)
 			if err != nil {
 				return nil, err
 			}
-			col.Col_len = binary.LittleEndian.Uint32(Col_len)
 
-			//获取数据的值
-			col.Col_Data, err = readBuf.readNext(int(col.Col_len), false)
-			if err != nil {
-				return nil, err
-			}
-			
-			data.Values[colIdx] = append(data.Values[colIdx], col)
-			colIdx++
-		
 			char := readBuf.peekChar()
-
 			//既不是R 也不是K 代表该行还有其他字段内容没有读取完成
-			if char == 'R' {
-				readBuf.idx++
-				colIdx = 0
-				continue
-			} else if char == 'K' {
+			if char == 'K' {
+				data.fad = fad
 				return data, nil
 				//break
 			}
 
-		} //for end
-
-	} else if char == '$' {
-		fad, err := parseFormArgDescri(readBuf)
-		if err != nil {
-			return nil, err
-		}
-
-		char := readBuf.peekChar()
-		//既不是R 也不是K 代表该行还有其他字段内容没有读取完成
-		if char == 'K' {
-			data.fad = fad
+			return nil, errors.New("select to $ 解析失败")
+		} else {
 			return data, nil
-			//break
 		}
-
-		return nil, errors.New("select to $ 解析失败")
-	} else {
-		return nil, errors.New("解析失败")
 	}
 
 }

+ 4 - 4
xugu/xugu/xugu_result.go

@@ -16,13 +16,13 @@ type xuguResult struct {
 // "auto increment" column when inserting a new row. Not all
 // databases support this feature, and the syntax of such
 // statements varies.
-func (self *xuguResult) LastInsertId() (int64, error) {
-	return self.insertId, nil
+func (result *xuguResult) LastInsertId() (int64, error) {
+	return result.insertId, nil
 }
 
 // RowsAffected returns the number of rows affected by an
 // update, insert, or delete. Not every database or database
 // driver may support this.
-func (self *xuguResult) RowsAffected() (int64, error) {
-	return self.affectedRows, nil
+func (result *xuguResult) RowsAffected() (int64, error) {
+	return result.affectedRows, nil
 }

+ 40 - 7
xugu/xugu/xugu_rows.go

@@ -12,10 +12,10 @@ import (
 
 type xuguRows struct {
 	rows_conn *xuguConn
-
-	results  *SelectResult
-	colIdx   int
-	prepared bool
+	aR        *allResult
+	results   *SelectResult
+	colIdx    int
+	prepared  bool
 }
 
 func (row *xuguRows) Next(dest []driver.Value) error {
@@ -38,7 +38,7 @@ func (row *xuguRows) Next(dest []driver.Value) error {
 			case fieldType_BINARY,
 				fieldType_CLOB,
 				fieldType_BLOB:
-				fmt.Println(row.results.Values[j][row.results.rowIdx].Col_Data)
+				//fmt.Println(row.results.Values[j][row.results.rowIdx].Col_Data)
 				dest[j] = row.results.Values[j][row.results.rowIdx].Col_Data
 
 			case fieldType_INTERVAL_Y, fieldType_INTERVAL_M, fieldType_INTERVAL_D,
@@ -156,11 +156,44 @@ func (row *xuguRows) Columns() []string {
 }
 
 func (row *xuguRows) ColumnTypeScanType(index int) reflect.Type {
-	fmt.Println(">>>>>ColumnTypeScanType ")
+	//fmt.Println(">>>>>ColumnTypeScanType ")
 
 	return row.results.Fields[index].scanType()
 }
 
-func (self *xuguRows) Close() error {
+// The driver is at the end of the current result set.
+// Test to see if there is another result set after the current one.
+// Only close Rows if there is no further result sets to read.
+func (row *xuguRows) HasNextResultSet() bool {
+	return row.aR.next != nil
+
+}
+
+// NextResultSet prepares the next result set for reading. It reports whether
+// there is further result sets, or false if there is no further result set
+// or if there is an error advancing to it. The Err method should be consulted
+// to distinguish between the two cases.
+//
+// After calling NextResultSet, the Next method should always be called before
+// scanning. If there are further result sets they may not have rows in the result
+// set.
+func (row *xuguRows) NextResultSet() error {
+	fmt.Println("NextResultSet")
+	if row.aR.next == nil {
+		return fmt.Errorf("there are no multiple result sets available")
+	}
+	switch row.aR.next.rt {
+	case errInfo:
+		return fmt.Errorf("error: %s", string(row.aR.next.e.ErrStr))
+
+	}
+
+	row.results = row.aR.next.s
+	row.aR = row.aR.next
+
+	return nil
+}
+
+func (row *xuguRows) Close() error {
 	return nil
 }

+ 3 - 1
xugu/xugu/xugu_sock.go

@@ -5,6 +5,7 @@ import (
 	"context"
 	"encoding/binary"
 	"errors"
+	"fmt"
 )
 
 func xgSockOpenConn(ctx context.Context, pConn *xuguConn) error {
@@ -20,7 +21,7 @@ func xgSockOpenConn(ctx context.Context, pConn *xuguConn) error {
 	buffer := make([]byte, 1)
 	n, err := pConn.conn.Read(buffer)
 	if err != nil {
-		return errors.New("接收数据库连接失败:")
+		return errors.New(fmt.Sprintln("接收数据库连接失败: ", err.Error()))
 	}
 
 	if !bytes.Equal(buffer[:n], []byte("K")) {
@@ -121,6 +122,7 @@ func xuguSockRecvMsg(pConn *xuguConn) (*allResult, error) {
 	pConn.readBuff.length += n
 	rs, err := parseMsg(&pConn.readBuff, pConn)
 	if err != nil {
+
 		return nil, err
 	}
 	pConn.readBuff.reset()

+ 4 - 4
xugu/xugu/xugu_utils.go

@@ -131,7 +131,7 @@ func reverseBytes(b []byte) []byte {
 }
 
 func gt(name string) {
-	fmt.Printf("\n=============%s================\n", name)
+	//fmt.Printf("\n=============%s================\n", name)
 }
 
 func switchSQLType(sql string) int {
@@ -147,9 +147,9 @@ func switchSQLType(sql string) int {
 	// 根据SQL语句前缀判断类型
 	switch {
 	case strings.HasPrefix(kstr, "SELECT"):
-		if strings.Contains(sql, ";") && len(sql[strings.Index(sql, ";"):]) > 5 {
-			return SQL_OTHER // 多结果集
-		}
+		// if strings.Contains(sql, ";") && len(sql[strings.Index(sql, ";"):]) > 5 {
+		// 	return SQL_OTHER // 多结果集
+		// }
 		return SQL_SELECT
 	case strings.HasPrefix(kstr, "INSERT"):
 		return SQL_INSERT

+ 0 - 92
xugu/xugu_buffer.go

@@ -1,92 +0,0 @@
-package xugu
-
-import (
-	"errors"
-	"net"
-	"time"
-)
-
-var (
-	ErrBusyBuffer = errors.New("busy buffer")
-)
-
-type buffer struct {
-	buf     []byte // buf 是一个字节缓冲区,长度和容量相等。
-	conn    net.Conn
-	idx     int64
-	length  int
-	timeout time.Duration
-}
-
-// newBuffer 分配并返回一个新的缓冲区。
-func newBuffer(nc net.Conn) buffer {
-	return buffer{
-		buf:  make([]byte, 2048),
-		conn: nc,
-	}
-}
-
-func (b *buffer) peekChar() byte {
-	if b.idx > int64(len(b.buf[b.idx:b.length])) {
-		b.readNext(1, false)
-		b.idx-- //peekchar 只查看当前字符,不移动指针,但是readNext会移动指针,所以需要-1
-	}
-	ret := b.buf[b.idx]
-	return ret
-}
-func (b *buffer) reset() {
-	b.idx = 0
-	b.length = 0
-	b.buf = make([]byte, 2048)
-}
-
-func (b *buffer) readNext(need int, reverse bool) ([]byte, error) {
-	if need == 0 {
-		return nil, nil
-	}
-	//长度不够返回
-	if len(b.buf[b.idx:b.length]) < need {
-		buffer := make([]byte, need+1)
-		b.buf = append(b.buf[:b.length], buffer...)
-		n, err := b.conn.Read(b.buf[b.length:])
-		if err != nil {
-			// if err == io.EOF {
-
-			// }
-			return nil, err
-		}
-
-		b.length += n
-
-		for b.length-int(b.idx) < need {
-
-			n, err := b.conn.Read(b.buf[b.length:])
-			if err != nil {
-				// if err == io.EOF {
-				// 	fmt.Println("End of data")
-
-				// }
-
-				return nil, err
-			}
-			//nTmp += n
-			b.length += n
-		}
-
-	}
-
-	offset := b.idx
-	b.idx += int64(need)
-	if GlobalIsBig {
-		reverse = false
-	}
-	if reverse {
-		tmp := reverseBytes(b.buf[offset:b.idx])
-
-		return tmp, nil
-	} else {
-
-		return b.buf[offset:b.idx], nil
-	}
-
-}

+ 0 - 388
xugu/xugu_conn.go

@@ -1,388 +0,0 @@
-package xugu
-
-import (
-	"bytes"
-	"context"
-	"database/sql/driver"
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"net"
-	"sync"
-)
-
-type xuguConn struct {
-	dsnConfig
-	conn        net.Conn
-	mu          sync.Mutex
-	useSSL      bool // 是否使用加密
-	havePrepare int  //default 0
-
-	prepareNo   int
-	prepareName string
-	//presPrepareCata *Result
-
-	errStr []byte
-
-	sendBuff bytes.Buffer
-	readBuff buffer
-}
-
-type dsnConfig struct {
-	IP             string
-	Port           string
-	Database       string
-	User           string
-	Password       string
-	Encryptor      string //加密库的解密口令
-	CharSet        string //客户端使用的字符集名
-	TimeZone       string
-	IsoLevel       string //事务隔离级别
-	LockTimeout    string //加锁超时
-	AutoCommit     string
-	StrictCommit   string
-	Result         string
-	ReturnSchema   string
-	ReturnCursorID string
-	LobRet         string
-	ReturnRowid    string
-	Version        string
-}
-
-func (xgConn *xuguConn) Begin() (driver.Tx, error) {
-
-	_, err := xgConn.exec("Begin;", nil)
-	if err != nil {
-		return nil, err
-	}
-	return &xuguTx{tconn: xgConn}, nil
-
-}
-
-func (xgConn *xuguConn) Close() error {
-
-	xgConn.mu.Lock()
-	defer xgConn.mu.Unlock()
-	err := xgConn.conn.Close()
-	if err != nil {
-		xgConn.mu.Unlock()
-		return err
-	}
-
-	return nil
-}
-
-func (xgConn *xuguConn) Query(sql string,
-	args []driver.Value) (driver.Rows, error) {
-
-	xgConn.mu.Lock()
-	defer xgConn.mu.Unlock()
-
-	// 检测sql语句不是查询则报错
-	if switchSQLType(sql) != SQL_SELECT {
-		return nil, errors.New("The executed SQL statement is not a SELECT")
-	}
-
-	// 有传进来的参数
-	if len(args) != 0 {
-		values := []xuguValue{}
-		//判断类型
-		for _, param := range args {
-			err := assertParamType(param, &values)
-			if err != nil {
-				return nil, err
-			}
-		}
-		//send msg
-		if err := sockSendPutStatement(xgConn, []byte(sql), &values, len(args)); err != nil {
-			return nil, err
-		}
-
-		if err := sockSendExecute(xgConn); err != nil {
-			return nil, err
-		}
-
-	} else {
-
-		//send msg
-		if err := sockSendPutStatement(xgConn, []byte(sql), nil, len(args)); err != nil {
-			return nil, err
-		}
-
-		if err := sockSendExecute(xgConn); err != nil {
-			return nil, err
-		}
-
-	}
-	//recv msg
-	aR, err := xuguSockRecvMsg(xgConn)
-	if err != nil {
-		return nil, err
-	}
-	fmt.Println("驱动接收消息:", aR)
-	switch aR.rt {
-	case selectResult:
-
-		rows := &xuguRows{
-			rows_conn: xgConn,
-			results:   aR.s,
-			colIdx:    0,
-			prepared:  false,
-		}
-
-		return rows, nil
-	case errInfo:
-
-		return nil, errors.New(string(aR.e.ErrStr))
-	case warnInfo:
-
-		return nil, errors.New(string(aR.w.WarnStr))
-	default:
-	}
-
-	return nil, errors.New("xugu Query error")
-}
-
-func (xgConn *xuguConn) Ping(ctx context.Context) error {
-
-	//send
-	xgConn.mu.Lock()
-	defer xgConn.mu.Unlock()
-	sockSendPutStatement(xgConn, []byte("select count(*) from dual;"), nil, 0)
-	sockSendExecute(xgConn)
-
-	_, err := xuguSockRecvMsg(xgConn)
-	if err != nil {
-		return err
-	}
-	xgConn.readBuff.reset()
-
-	return nil
-}
-
-func (xgConn *xuguConn) Prepare(sql string) (driver.Stmt, error) {
-
-	xgConn.mu.Lock()
-	defer xgConn.mu.Unlock()
-
-	//判断sql类型
-	switch switchSQLType(sql) {
-	case SQL_PROCEDURE:
-		return nil, errors.New("Prepare does not support stored procedures")
-	case SQL_UNKNOWN:
-		return nil, errors.New("Unknown SQL statement type")
-	case SQL_CREATE:
-		return nil, errors.New("Prepare does not support DDL.")
-	}
-	//发送创建prepare
-	prepareName := "GTONG"
-
-	err := xuguPrepare(xgConn, sql, prepareName)
-	if err != nil {
-		return nil, err
-	}
-	count := assertParamCount(sql)
-	stmt := &xuguStmt{
-		stmt_conn:  xgConn,
-		prepared:   true,
-		prename:    make([]byte, 128),
-		curopend:   false,
-		curname:    make([]byte, 128),
-		paramCount: count,
-		mysql:      sql,
-	}
-	stmt.prename = []byte(fmt.Sprintf("? %s", xgConn.prepareName))
-
-	return stmt, nil
-}
-
-func xuguPrepare(pConn *xuguConn, cmd_sql string, prepareName string) error {
-
-	prepareName = fmt.Sprintf("%s%d", prepareName, pConn.prepareNo)
-	sqlRet := fmt.Sprintf("PREPARE %s AS %s", prepareName, cmd_sql)
-	pConn.prepareName = prepareName
-	pConn.prepareNo++
-	//send msg
-	sockSendPutStatement(pConn, []byte(sqlRet), nil, 0)
-	sockSendExecute(pConn)
-	//recv msg
-	aR, err := xuguSockRecvMsg(pConn)
-	switch aR.rt {
-
-	case errInfo:
-
-		return errors.New(string(aR.e.ErrStr))
-	case warnInfo:
-
-		return errors.New(string(aR.w.WarnStr))
-	default:
-	}
-
-	if err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func xuguUnPrepare(pConn *xuguConn, prepareName string) error {
-
-	sqlRet := fmt.Sprintf("DEALLOCATE %s ", prepareName)
-
-	//send msg
-	sockSendPutStatement(pConn, []byte(sqlRet), nil, 0)
-	sockSendExecute(pConn)
-	//recv msg
-	aR, err := xuguSockRecvMsg(pConn)
-	switch aR.rt {
-
-	case 'K':
-		return nil
-	case errInfo:
-
-		return errors.New(string(aR.e.ErrStr))
-	case warnInfo:
-
-		return errors.New(string(aR.w.WarnStr))
-	default:
-	}
-
-	if err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (xgConn *xuguConn) Exec(sql string,
-	args []driver.Value) (driver.Result, error) {
-
-	xgConn.mu.Lock()
-	defer xgConn.mu.Unlock()
-
-	// 检测sql语句是查询则报错
-	if switchSQLType(sql) == SQL_SELECT {
-		return nil, errors.New("The executed SQL statement is  a SELECT")
-	}
-
-	// 有传进来的参数
-	if len(args) != 0 {
-		values := []xuguValue{}
-		//判断类型
-		for _, param := range args {
-			err := assertParamType(param, &values)
-			if err != nil {
-				return nil, err
-			}
-		}
-		//send msg
-		if err := sockSendPutStatement(xgConn, []byte(sql), &values, len(args)); err != nil {
-			return nil, err
-		}
-
-		if err := sockSendExecute(xgConn); err != nil {
-			return nil, err
-		}
-
-	} else {
-
-		//send msg
-		if err := sockSendPutStatement(xgConn, []byte(sql), nil, len(args)); err != nil {
-			return nil, err
-		}
-
-		if err := sockSendExecute(xgConn); err != nil {
-			return nil, err
-		}
-
-	}
-	//recv msg
-	aR, err := xuguSockRecvMsg(xgConn)
-	if err != nil {
-		return nil, err
-	}
-
-	switch aR.rt {
-	case selectResult:
-
-		return nil, errors.New("exec is Query error")
-	case errInfo:
-
-		return nil, errors.New(string(aR.e.ErrStr))
-	case warnInfo:
-
-		return nil, errors.New(string(aR.w.WarnStr))
-	case updateResult:
-		return &xuguResult{affectedRows: int64(aR.u.UpdateNum), insertId: int64(0)}, nil
-	case insertResult:
-		return &xuguResult{affectedRows: int64(0), insertId: int64(aR.i.RowidLen)}, nil
-	default:
-		return &xuguResult{
-			affectedRows: int64(0),
-			insertId:     int64(0),
-		}, nil
-	}
-
-}
-
-func (xgConn *xuguConn) exec(sql string, args []driver.Value) (driver.Result, error) {
-	// 有传进来的参数
-	if len(args) != 0 {
-		values := []xuguValue{}
-		//判断类型
-		for _, param := range args {
-			err := assertParamType(param, &values)
-			if err != nil {
-				return nil, err
-			}
-		}
-		//send msg
-		if err := sockSendPutStatement(xgConn, []byte(sql), &values, len(args)); err != nil {
-			return nil, err
-		}
-
-		if err := sockSendExecute(xgConn); err != nil {
-			return nil, err
-		}
-
-	} else {
-
-		//send msg
-		if err := sockSendPutStatement(xgConn, []byte(sql), nil, len(args)); err != nil {
-			return nil, err
-		}
-
-		if err := sockSendExecute(xgConn); err != nil {
-			return nil, err
-		}
-
-	}
-
-	//recv msg
-	aR, err := xuguSockRecvMsg(xgConn)
-	if err != nil {
-		return nil, err
-	}
-	switch aR.rt {
-	case selectResult:
-
-		return nil, errors.New("exec is Query error")
-	case updateResult:
-		return &xuguResult{affectedRows: int64(aR.u.UpdateNum), insertId: int64(0)}, nil
-	case insertResult:
-
-		return &xuguResult{affectedRows: int64(0), insertId: int64(binary.LittleEndian.Uint64(aR.i.RowidData))}, nil
-	case errInfo:
-
-		return nil, errors.New(string(aR.e.ErrStr))
-	case warnInfo:
-
-		return nil, errors.New(string(aR.w.WarnStr))
-	default:
-		return &xuguResult{
-			affectedRows: int64(0),
-			insertId:     int64(0),
-		}, nil
-	}
-
-}

+ 0 - 64
xugu/xugu_connector.go

@@ -1,64 +0,0 @@
-package xugu
-
-import (
-	"context"
-	"database/sql/driver"
-	"fmt"
-	"net"
-	"time"
-)
-
-type connector struct {
-	dsn string
-}
-
-// Driver implements driver.Connector interface.
-// Driver returns &XuguDriver{}
-func (conntor *connector) Driver() driver.Driver {
-
-	return &XuguDriver{}
-}
-
-// Connect implements driver.Connector interface.
-// Connect returns a connection to the database.
-/*
-dsn解析
-创建连接
-设置为 tcp 长连接(
-创建连接缓冲区
-设置连接超时配置
-接收来自服务端的握手请求
-*/
-func (conntor *connector) Connect(ctx context.Context) (driver.Conn, error) {
-
-	GlobalIsBig = CheckEndian()
-
-	dsnConfig := parseDSN(conntor.dsn)
-
-	xgConn := &xuguConn{conn: nil}
-	xgConn.dsnConfig = dsnConfig
-
-	nd := net.Dialer{Timeout: 10 * time.Millisecond}
-	netConn, err := nd.DialContext(ctx, "tcp", fmt.Sprintf("%s:%s", xgConn.IP, xgConn.Port))
-	if err != nil {
-		return nil, err
-	}
-
-	// 启用 TCP 保活
-	if tc, ok := netConn.(*net.TCPConn); ok {
-		if err := tc.SetKeepAlive(true); err != nil {
-			//c.cfg.Logger.Print(err) // 如果设置保活失败,记录错误但不终止
-			return nil, err
-		}
-	}
-
-	xgConn.conn = netConn
-	xgConn.mu.Lock()
-	xgConn.readBuff = newBuffer(xgConn.conn)
-	err = xgSockOpenConn(ctx, xgConn)
-	if err != nil {
-		return nil, err
-	}
-	xgConn.mu.Unlock()
-	return xgConn, nil
-}

+ 0 - 32
xugu/xugu_define.go

@@ -1,32 +0,0 @@
-package xugu
-
-var GlobalIsBig bool
-
-// 协议消息类型
-type msgType byte
-
-const (
-	selectResult msgType = iota + 0x01
-	insertResult
-	updateResult
-	deleteResult
-	procRet
-	outParamRet
-	errInfo
-	warnInfo
-	message
-	formArgDescri
-)
-
-// SQL类型常量
-const (
-	SQL_UNKNOWN = iota
-	SQL_SELECT
-	SQL_INSERT
-	SQL_UPDATE
-	SQL_DELETE
-	SQL_CREATE
-	SQL_ALTER
-	SQL_PROCEDURE
-	SQL_OTHER
-)

+ 0 - 50
xugu/xugu_driver.go

@@ -1,50 +0,0 @@
-package xugu
-
-import (
-	"context"
-	"database/sql"
-	"database/sql/driver"
-	"time"
-)
-
-// XuguDriver is exported to make the driver directly accessible
-type XuguDriver struct{}
-
-/* Register Driver */
-func init() {
-
-	/* Register makes a database driver available by the provided name.
-	 * If Register is called twice with the same name or if driver is nil,
-	 * it panics.
-	 */
-	sql.Register("xugusql", &XuguDriver{})
-	timezone, _ := time.LoadLocation("Asia/Shanghai")
-	time.Local = timezone
-}
-
-// Open opens a database specified by its database driver name and a
-// driver-specific data source name, usually consisting of at least a
-// database name and connection information.
-//
-// Most users will open a database via a driver-specific connection
-// helper function that returns a *DB. No database drivers are included
-// in the Go standard library. See https://golang.org/s/sqldrivers for
-// a list of third-party drivers.
-//
-// Open may just validate its arguments without creating a connection
-// to the database. To verify that the data source name is valid, call
-// Ping.
-// The returned DB is safe for concurrent use by multiple goroutines
-// and maintains its own pool of idle connections. Thus, the Open
-// function should be called just once. It is rarely necessary to
-// close a DB.
-func (db XuguDriver) Open(dsn string) (driver.Conn, error) {
-
-	conn := &connector{dsn: dsn}
-	return conn.Connect(context.Background())
-}
-
-func (db XuguDriver) OpenConnector(dsn string) (driver.Connector, error) {
-
-	return &connector{dsn: dsn}, nil
-}

+ 0 - 229
xugu/xugu_fields.go

@@ -1,229 +0,0 @@
-package xugu
-
-import (
-	"database/sql"
-	"reflect"
-	"time"
-)
-
-type FieldDescri struct {
-	FieldNameLen    int
-	FieldName       string
-	FieldType       fieldType
-	FieldPreciScale fieldPreciScaleInfo
-	FieldFlag       uint32
-}
-
-type fieldPreciScaleInfo struct {
-	scale    uint16
-	accuracy uint16
-}
-
-type fieldType uint16
-
-const (
-	fieldType_EMPTY fieldType = iota + 0x00
-	fieldType_NULL
-	fieldType_BOOL
-	fieldType_I1
-	fieldType_I2
-	fieldType_I4
-	fieldType_I8
-	fieldType_NUM
-	fieldType_R4
-	fieldType_R8
-
-	fieldType_DATE
-	fieldType_TIME
-	fieldType_TIME_TZ
-	fieldType_DATETIME
-	fieldType_DATETIME_TZ
-
-	fieldType_INTERVAL_Y
-	fieldType_INTERVAL_Y2M
-	fieldType_INTERVAL_M
-
-	fieldType_INTERVAL_D
-	fieldType_INTERVAL_D2H
-	fieldType_INTERVAL_H
-	fieldType_INTERVAL_D2M
-	fieldType_INTERVAL_H2M
-	fieldType_INTERVAL_MI
-	fieldType_INTERVAL_D2S
-	fieldType_INTERVAL_H2S
-	fieldType_INTERVAL_M2S
-	fieldType_INTERVAL_S
-
-	fieldType_ROWVER
-	fieldType_GUID
-	fieldType_CHAR
-	fieldType_NCHAR
-	fieldType_CLOB
-
-	fieldType_BINARY
-	fieldType_BLOB
-
-	fieldType_GEOM
-	fieldType_POINT
-	fieldType_BOX
-	fieldType_POLYLINE
-	fieldType_POLYGON
-
-	fieldType_BLOB_I
-	fieldType_BLOB_S
-	fieldType_BLOB_M
-	fieldType_BLOB_OM
-	fieldType_STREAM
-	fieldType_ROWID
-	fieldType_SIBLING
-	fieldType_MAX_SYS fieldType = 47
-
-	fieldType_BLADE_BEGIN fieldType = 101
-	fieldType_BLADE_END   fieldType = 1000
-
-	fieldType_OBJECT fieldType = 1001 // object type
-	fieldType_REFROW
-	fieldType_RECORD  // record type
-	fieldType_VARRAY  // array type
-	fieldType_TABLE   // table type
-	fieldType_ITABLE  // Idxby table
-	fieldType_CURSOR  // involved ref-record type (cannot change)
-	fieldType_REFCUR  // REF_CURSOR type
-	fieldType_ROWTYPE // ref row type
-	fieldType_COLTYPE // ref column type
-	fieldType_CUR_REC
-	fieldType_PARAM
-)
-
-/* {{ */
-func (self *FieldDescri) typeDatabaseName() string {
-	switch self.FieldType {
-	case fieldType_BOOL:
-		return "BOOLEAN"
-	case fieldType_CHAR, fieldType_NCHAR:
-		return "CHAR"
-	case fieldType_I1:
-		return "TINYINT"
-	case fieldType_I2:
-		return "SHORT"
-	case fieldType_I4:
-		return "INTEGER"
-	case fieldType_I8:
-		return "BIGINT"
-	case fieldType_R4:
-		return "FLOAT"
-	case fieldType_R8:
-		return "DOUBLE"
-	case fieldType_NUM:
-		return "NUMERIC"
-	case fieldType_DATE:
-		return "DATE"
-	case fieldType_TIME:
-		return "TIME"
-	case fieldType_TIME_TZ:
-		return "TIMEZONE"
-	case fieldType_DATETIME:
-		return "DATETIME"
-	case fieldType_DATETIME_TZ:
-		return "DATETIME TIMEZONE"
-	case fieldType_BINARY:
-		return "BINARY"
-	case fieldType_INTERVAL_Y:
-		return "INTERVAL YEAR"
-	case fieldType_INTERVAL_Y2M:
-		return "INTERVAL YEAR TO MONTH"
-	case fieldType_INTERVAL_D2S:
-		return "INTERVAL DAY TO SECOND"
-	case fieldType_CLOB:
-		return "CLOB"
-	case fieldType_BLOB:
-		return "BLOB"
-	default:
-		return ""
-	}
-}
-
-/* {{ */
-func (self *FieldDescri) scanType() reflect.Type {
-
-	switch self.FieldType {
-
-	case fieldType_BOOL:
-		return scanTypeBool
-	case fieldType_I1:
-		return scanTypeInt8
-	case fieldType_I2:
-		return scanTypeInt16
-	case fieldType_I4:
-		return scanTypeInt32
-	case fieldType_I8:
-		return scanTypeInt64
-	case fieldType_R4:
-		return scanTypeFloat32
-	case fieldType_R8:
-		return scanTypeFloat64
-	case fieldType_DATE,
-		fieldType_TIME,
-		fieldType_DATETIME:
-		return scanTypeNullTime
-	case fieldType_TIME_TZ,
-		fieldType_DATETIME_TZ,
-		fieldType_CHAR,
-		fieldType_NCHAR,
-		fieldType_BINARY,
-		//fieldTypeInterval,
-		fieldType_NUM,
-		fieldType_INTERVAL_Y2M,
-		fieldType_INTERVAL_D2S,
-		//fieldTypeLob,
-		fieldType_CLOB,
-		fieldType_BLOB:
-		return scanTypeRawBytes
-	default:
-		return scanTypeUnknown
-
-	}
-}
-
-var (
-	scanTypeFloat32   = reflect.TypeOf(float32(0))
-	scanTypeFloat64   = reflect.TypeOf(float64(0))
-	scanTypeNullFloat = reflect.TypeOf(sql.NullFloat64{})
-	scanTypeNullInt   = reflect.TypeOf(sql.NullInt64{})
-	scanTypeNullTime  = reflect.TypeOf(time.Time{})
-	scanTypeInt8      = reflect.TypeOf(int8(0))
-	scanTypeInt16     = reflect.TypeOf(int16(0))
-	scanTypeInt32     = reflect.TypeOf(int32(0))
-	scanTypeInt64     = reflect.TypeOf(int64(0))
-	scanTypeUnknown   = reflect.TypeOf(new(interface{}))
-	scanTypeRawBytes  = reflect.TypeOf(sql.RawBytes{})
-	scanTypeUint8     = reflect.TypeOf(uint8(0))
-	scanTypeUint16    = reflect.TypeOf(uint16(0))
-	scanTypeUint32    = reflect.TypeOf(uint32(0))
-	scanTypeUint64    = reflect.TypeOf(uint64(0))
-	scanTypeBool      = reflect.TypeOf(bool(false))
-)
-
-// func processValue(value driver.Value) {
-// 	switch v := value.(type) {
-// 	case nil:
-// 		fmt.Println("Value is nil")
-// 	case int64:
-// 		fmt.Printf("Value is int64: %d\n", v)
-// 	case float64:
-// 		fmt.Printf("Value is float64: %f\n", v)
-// 	case bool:
-// 		fmt.Printf("Value is bool: %t\n", v)
-// 	case []byte:
-// 		fmt.Printf("Value is []byte: %x\n", v)
-// 	case string:
-// 		fmt.Printf("Value is string: %s\n", v)
-// 	case time.Time:
-// 		fmt.Printf("Value is time.Time: %s\n", v)
-// 	case driver.Rows:
-// 		fmt.Println("Value is driver.Rows")
-// 		// You can further process the rows here
-// 	default:
-// 		fmt.Println("Unknown type")
-// 	}
-// }

+ 0 - 82
xugu/xugu_model.go

@@ -1,82 +0,0 @@
-package xugu
-
-type SelectResult struct {
-	Field_Num uint32
-	Fields    []FieldDescri
-	Values    [][]FieldValue //[字段][字段所有值]
-	rowIdx    int
-	fad       *FormArgDescri
-	next      *SelectResult
-}
-type FormArgDescri struct {
-	ArgNum uint32
-	Args   []ArgDescri
-}
-
-type FieldValue struct {
-	Col_len  uint32
-	Col_Data []byte
-}
-
-type InsertResult struct {
-	RowidLen  uint32
-	RowidData []byte
-}
-
-type UpdateResult struct {
-	UpdateNum uint32
-}
-
-type DeleteResult struct {
-	DeleteNum uint32
-}
-
-type ProcRet struct {
-	RetDType   uint32
-	RetDataLen uint32
-	RetData    []byte
-}
-
-type OutParamRet struct {
-	OutParamNo    uint32
-	OutParamDType uint32
-	OutParamLen   uint32
-	OutParamData  []byte
-}
-
-type ErrInfo struct {
-	ErrStrLen uint32
-	ErrStr    []byte
-}
-
-type WarnInfo struct {
-	WarnStrLen uint32
-	WarnStr    []byte
-}
-
-type Message struct {
-	MsgStrLen uint32
-	MsgStr    []byte
-}
-
-type ArgDescri struct {
-	ArgNameLen    uint32
-	ArgName       []byte
-	ArgNo         uint32
-	ArgDType      uint32
-	ArgPreciScale uint32
-}
-
-type allResult struct {
-	rt msgType
-	s  *SelectResult
-	i  *InsertResult
-	u  *UpdateResult
-	d  *DeleteResult
-	p  *ProcRet
-	o  *OutParamRet
-	e  *ErrInfo
-	w  *WarnInfo
-	m  *Message
-	f  *FormArgDescri
-}

+ 0 - 513
xugu/xugu_parse.go

@@ -1,513 +0,0 @@
-package xugu
-
-import (
-	"database/sql/driver"
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"strconv"
-	"strings"
-	"time"
-)
-
-type xuguValue struct {
-	// 布尔值,如果值为 true,表示当前字段的数据类型是大对象数据类型
-	islob bool
-	//字段名
-	paramName []byte
-	//paramNameLength [2]byte
-	// 字段的实际值
-	value []byte
-	// 值的长度
-	valueLength int
-	// 字段的类型
-	types fieldType
-}
-
-// 判断参数个数
-func assertParamCount(query string) int {
-
-	paramCount := strings.Count(query, "?")
-
-	return paramCount
-}
-func assertParamType(dV driver.Value, values *[]xuguValue) error {
-	var dest xuguValue
-	switch srcv := dV.(type) {
-
-	case int64:
-		buf := make([]byte, 8)
-		binary.BigEndian.PutUint64(buf, uint64(srcv))
-		dest.value = buf
-		dest.valueLength = 8
-		dest.islob = false
-		dest.types = fieldType_I8
-
-	case float64:
-		S := strconv.FormatFloat(srcv, 'f', 15, 64)
-		dest.value = []byte(S)
-		dest.valueLength = len(S)
-		dest.islob = false
-		dest.types = fieldType_CHAR
-
-	case bool:
-		//S := strconv.FormatBool(srcv)
-		var tmp []byte
-		if srcv {
-			tmp = []byte{1}
-		} else {
-			tmp = []byte{0}
-		}
-
-		dest.value = []byte(tmp)
-		dest.valueLength = 1
-		dest.islob = false
-		dest.types = fieldType_BOOL
-
-	case string:
-		dest.value = []byte(srcv)
-		dest.valueLength = len(srcv)
-		dest.islob = false
-		dest.types = fieldType_CHAR
-		if dest.valueLength == 0 {
-			dest.valueLength = 1
-			dest.value = []byte{0}
-		}
-
-	case time.Time:
-		tm := fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d",
-			srcv.Year(), int(srcv.Month()), srcv.Day(),
-			srcv.Hour(), srcv.Minute(), srcv.Second())
-		dest.value = []byte(tm)
-		//	dest.valueLength = strings.Count(tm, "") - 1
-		dest.valueLength = len(tm)
-		dest.islob = false
-		//dest.types = fieldType_TIME
-		dest.types = fieldType_CHAR
-	case []byte:
-		dest.value = srcv
-		dest.valueLength = len(srcv)
-		dest.islob = true
-		dest.types = fieldType_BLOB
-		if dest.valueLength == 0 {
-			dest.valueLength = 1
-			dest.value = []byte{0}
-		}
-
-	case nil:
-		dest.value = nil
-		dest.valueLength = 0
-		dest.islob = false
-		dest.types = fieldType_NULL
-
-	default:
-		return errors.New("unknown data type")
-	}
-
-	*values = append(*values, dest)
-	return nil
-}
-
-func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
-	var err error
-	aR := allResult{}
-	for {
-		char := readBuf.peekChar()
-		switch char {
-
-		case 'K':
-			readBuf.reset()
-			return &aR, nil
-
-		case '$':
-			readBuf.idx++
-			if aR.f, err = parseFormArgDescri(readBuf); err != nil {
-				return nil, err
-			}
-			aR.rt = formArgDescri
-			//return &aR, err
-		case 'A':
-			readBuf.idx++
-			if aR.s, err = parseSelectResult(readBuf); err != nil {
-				return nil, err
-			}
-			aR.rt = selectResult
-		//	return &aR, err
-
-		case 'I':
-			readBuf.idx++
-			if aR.i, err = parseInsertResult(readBuf); err != nil {
-				return nil, err
-			}
-			aR.rt = insertResult
-			//return &aR, err
-
-		case 'U':
-			readBuf.idx++
-			if aR.u, err = parseUpdateResult(readBuf); err != nil {
-				return nil, err
-			}
-			aR.rt = updateResult
-			//return &aR, err
-
-		case 'D':
-			readBuf.idx++
-			readBuf.idx++
-			if aR.d, err = parseDeleteResult(readBuf); err != nil {
-				return nil, err
-			}
-			aR.rt = deleteResult
-		//	return &aR, err
-
-		case 'E':
-			readBuf.idx++
-
-			if aR.e, err = parseErrInfo(readBuf); err != nil {
-				return nil, err
-			}
-			pConn.errStr = aR.e.ErrStr
-			aR.rt = errInfo
-			//return &aR, err
-
-		case 'W':
-			readBuf.idx++
-			if aR.w, err = parseWarnInfo(readBuf); err != nil {
-				return nil, err
-			}
-			aR.rt = warnInfo
-			//return &aR, err
-
-		case 'M':
-			readBuf.idx++
-			if aR.m, err = parseMessage(readBuf); err != nil {
-				return nil, err
-			}
-			aR.rt = message
-			//return &aR, err
-
-		default:
-			return nil, errors.New("parseMsg: unknown message type")
-		}
-
-	}
-}
-func parseSelectResult(readBuf *buffer) (*SelectResult, error) {
-	data := &SelectResult{}
-
-	char := readBuf.peekChar()
-
-	//Field_Num
-	fn, err := readBuf.readNext(4, true)
-	if err != nil {
-		return nil, err
-	}
-
-	Field_Num := binary.LittleEndian.Uint32(fn)
-	data.Field_Num = Field_Num
-	data.rowIdx = 0
-
-	//获取字段信息
-	for i := 0; i < int(Field_Num); i++ {
-
-		field := FieldDescri{}
-
-		//Field_Name_Len
-		Field_Name_Len, err := readBuf.readNext(4, true)
-		if err != nil {
-			return nil, err
-		}
-		field.FieldNameLen = int(binary.LittleEndian.Uint32(Field_Name_Len))
-
-		//Field_Name:
-		Field_Name, err := readBuf.readNext(field.FieldNameLen, false)
-		if err != nil {
-			return nil, err
-		}
-		field.FieldName = string(Field_Name)
-
-		//Field_DType:
-		Field_DType, err := readBuf.readNext(4, true)
-		if err != nil {
-			return nil, err
-		}
-		field.FieldType = fieldType(binary.LittleEndian.Uint32(Field_DType))
-
-		//Field_Preci_Scale:
-		Field_Preci_Scale, err := readBuf.readNext(4, true)
-		if err != nil {
-			return nil, err
-		}
-
-		fieldPreciScale := binary.LittleEndian.Uint32(Field_Preci_Scale)
-		if int32(fieldPreciScale) <= 0 {
-			field.FieldPreciScale = fieldPreciScaleInfo{
-				scale:    0,
-				accuracy: 0,
-			}
-		} else {
-			field.FieldPreciScale = fieldPreciScaleInfo{
-				scale:    uint16(fieldPreciScale >> 16),
-				accuracy: uint16(fieldPreciScale & 0xFFFF),
-			}
-		}
-
-		//Field_Flag:
-		Field_Flag, err := readBuf.readNext(4, true)
-		if err != nil {
-			return nil, err
-		}
-		field.FieldFlag = binary.LittleEndian.Uint32(Field_Flag)
-		data.Fields = append(data.Fields, field)
-	}
-
-	data.Values = make([][]FieldValue, data.Field_Num)
-
-	//获取字段的行值,并判断类型
-	// 使用 Peek 方法检查下一个字节是否为'R'或'K'
-
-	char = readBuf.peekChar()
-	//readBuf.idx++
-	if char == 'K' {
-		return data, nil
-	} else if char == 'R' {
-		colIdx := 0
-		//typeIdx := 0
-		readBuf.idx++
-		for {
-			col := FieldValue{}
-			//获取数据的大小
-			Col_len, err := readBuf.readNext(4, true)
-			if err != nil {
-				return nil, err
-			}
-			col.Col_len = binary.LittleEndian.Uint32(Col_len)
-
-			//获取数据的值
-			col.Col_Data, err = readBuf.readNext(int(col.Col_len), false)
-			if err != nil {
-				return nil, err
-			}
-
-			data.Values[colIdx] = append(data.Values[colIdx], col)
-			colIdx++
-
-			char := readBuf.peekChar()
-
-			//既不是R 也不是K 代表该行还有其他字段内容没有读取完成
-			if char == 'R' {
-				readBuf.idx++
-				colIdx = 0
-				continue
-			} else if char == 'K' {
-
-				return data, nil
-				//break
-			}
-
-		} //for end
-
-	} else if char == '$' {
-		fad, err := parseFormArgDescri(readBuf)
-		if err != nil {
-			return nil, err
-		}
-
-		char := readBuf.peekChar()
-		//既不是R 也不是K 代表该行还有其他字段内容没有读取完成
-		if char == 'K' {
-			data.fad = fad
-			return data, nil
-			//break
-		}
-
-		return nil, errors.New("select to $ 解析失败")
-	} else {
-		return nil, errors.New("解析失败")
-	}
-
-}
-
-func parseInsertResult(readBuf *buffer) (*InsertResult, error) {
-
-	//Rowid_Len
-	Rowid_L, err := readBuf.readNext(4, true)
-	if err != nil {
-		return nil, err
-	}
-	Rowid_Len := binary.LittleEndian.Uint32(Rowid_L)
-	//Rowid_Data
-	encoded, err := readBuf.readNext(int(Rowid_Len), false)
-	if err != nil {
-		return nil, err
-	}
-
-	//检测是否结束
-	char := readBuf.peekChar()
-
-	if char == 'K' {
-		return &InsertResult{
-			RowidLen:  Rowid_Len,
-			RowidData: encoded,
-		}, nil
-	}
-	return nil, errors.New("parseInsertResult error")
-}
-
-func parseUpdateResult(readBuf *buffer) (*UpdateResult, error) {
-	updatas, err := readBuf.readNext(4, true)
-	if err != nil {
-		return nil, err
-	}
-	updateNum := binary.LittleEndian.Uint32(updatas)
-
-	return &UpdateResult{UpdateNum: updateNum}, nil
-}
-
-func parseDeleteResult(readBuf *buffer) (*DeleteResult, error) {
-	deletes, err := readBuf.readNext(4, true)
-	if err != nil {
-		return nil, err
-	}
-	deleteNum := binary.LittleEndian.Uint32(deletes)
-
-	return &DeleteResult{DeleteNum: deleteNum}, nil
-}
-
-func parseProcRet(readBuf *buffer) (*ProcRet, error) {
-	retDypes, err := readBuf.readNext(4, true)
-	if err != nil {
-		return nil, err
-	}
-	retDType := binary.LittleEndian.Uint32(retDypes)
-	retDataLens, err := readBuf.readNext(4, true)
-	if err != nil {
-		return nil, err
-	}
-	retDataLen := binary.LittleEndian.Uint32(retDataLens)
-	retData, err := readBuf.readNext(int(retDataLen), false)
-	if err != nil {
-		return nil, err
-	}
-
-	return &ProcRet{RetDType: retDType, RetDataLen: retDataLen, RetData: retData}, nil
-}
-
-func parseOutParamRet(readBuf *buffer) (*OutParamRet, error) {
-	outParamNos, err := readBuf.readNext(4, true)
-	if err != nil {
-		return nil, err
-	}
-	outParamNo := binary.LittleEndian.Uint32(outParamNos)
-
-	outParamDTypes, err := readBuf.readNext(4, true)
-	if err != nil {
-		return nil, err
-	}
-	outParamDType := binary.LittleEndian.Uint32(outParamDTypes)
-
-	outParamLens, err := readBuf.readNext(4, true)
-	if err != nil {
-		return nil, err
-	}
-	outParamLen := binary.LittleEndian.Uint32(outParamLens)
-
-	outParamData, err := readBuf.readNext(int(outParamLen), false)
-	if err != nil {
-		return nil, err
-	}
-
-	return &OutParamRet{
-		OutParamNo:    outParamNo,
-		OutParamDType: outParamDType,
-		OutParamLen:   outParamLen,
-		OutParamData:  outParamData,
-	}, nil
-}
-
-func parseErrInfo(readBuf *buffer) (*ErrInfo, error) {
-	errStrLens, err := readBuf.readNext(4, true)
-	if err != nil {
-		return nil, err
-	}
-	errStrLen := binary.LittleEndian.Uint32(errStrLens)
-
-	errStr, err := readBuf.readNext(int(errStrLen), false)
-	if err != nil {
-		return nil, err
-	}
-	return &ErrInfo{ErrStrLen: errStrLen, ErrStr: errStr}, nil
-
-}
-
-func parseWarnInfo(readBuf *buffer) (*WarnInfo, error) {
-	warnStrLens, err := readBuf.readNext(4, true)
-	if err != nil {
-		return nil, err
-	}
-	warnStrLen := binary.LittleEndian.Uint32(warnStrLens)
-
-	warnStr, err := readBuf.readNext(int(warnStrLen), false)
-	if err != nil {
-		return nil, err
-	}
-	return &WarnInfo{WarnStrLen: warnStrLen, WarnStr: warnStr}, nil
-}
-
-func parseMessage(readBuf *buffer) (*Message, error) {
-	msgStrLens, err := readBuf.readNext(4, true)
-	if err != nil {
-		return nil, err
-	}
-	msgStrLen := binary.LittleEndian.Uint32(msgStrLens)
-
-	msgStr, err := readBuf.readNext(int(msgStrLen), false)
-	if err != nil {
-		return nil, err
-	}
-
-	return &Message{MsgStrLen: msgStrLen, MsgStr: msgStr}, nil
-}
-
-func parseFormArgDescri(readBuf *buffer) (*FormArgDescri, error) {
-	//	FormArgDescri:   '$' Arg_Num { Arg_Name_Len Arg_Name Arg_No Arg_DType Arg_Preci_Scale }+
-	Arg_Nums, err := readBuf.readNext(4, true)
-	if err != nil {
-		return nil, err
-	}
-	Arg_Num := binary.LittleEndian.Uint32(Arg_Nums)
-	formArgDescri := &FormArgDescri{ArgNum: Arg_Num}
-	for i := 0; i < int(Arg_Num); i++ {
-		arg := ArgDescri{}
-		//Arg_Name_Len
-		ArgNameLen, err := readBuf.readNext(4, true)
-		if err != nil {
-			return nil, err
-		}
-		arg.ArgNameLen = binary.LittleEndian.Uint32(ArgNameLen)
-		//Arg_Name
-		arg.ArgName, err = readBuf.readNext(int(arg.ArgNameLen), false)
-		if err != nil {
-			return nil, err
-		}
-		//Arg_No
-		ArgNo, err := readBuf.readNext(4, true)
-		if err != nil {
-			return nil, err
-		}
-		arg.ArgNo = binary.LittleEndian.Uint32(ArgNo)
-		//Argg_DType
-		ArgDType, err := readBuf.readNext(4, true)
-		if err != nil {
-			return nil, err
-		}
-		arg.ArgDType = binary.LittleEndian.Uint32(ArgDType)
-		//Arg_Preci_Scale
-		ArgPreciScale, err := readBuf.readNext(4, true)
-		if err != nil {
-			return nil, err
-		}
-		arg.ArgPreciScale = binary.LittleEndian.Uint32(ArgPreciScale)
-		formArgDescri.Args = append(formArgDescri.Args, arg)
-	}
-	return formArgDescri, nil
-}

+ 0 - 156
xugu/xugu_parse_time.go

@@ -1,156 +0,0 @@
-package xugu
-
-type TIMESTAMP struct {
-	year     int
-	month    int
-	day      int
-	hour     int
-	minute   int
-	second   int
-	fraction int // 毫秒
-}
-
-// 是否是闰年
-func IsLeapYear(year int) bool {
-	return (year%4 == 0 && year%100 != 0) || (year%400 == 0)
-}
-
-// 月份到天数的映射
-var mtod = [2][13]int{
-	{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, // 非闰年
-	{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}, // 闰年
-}
-
-func dt2dtm(t int64) TIMESTAMP {
-	var (
-		y, m, d, s int
-		mm, nn     int
-		wday       int
-		ms         int
-		rn_num     int
-	)
-
-	if t >= 0 { // 1970年以后
-		ms = int(t % 1000)
-		t /= 1000
-		s = int(t % 86400)
-		d = int(t / 86400)
-		wday = (d + 4) % 7
-		mm = d / 146097
-		nn = d % 146097
-		y = 1970 + 400*mm
-		mm = nn / 36524
-		nn = nn % 36524
-		y += 100 * mm
-		mm = nn / 1461
-		nn = nn % 1461
-		y += 4 * mm
-		if nn > 1096 {
-			y += 3
-		}
-		if nn > 730 && nn <= 1096 {
-			y += 2
-		}
-		if nn > 365 && nn <= 730 {
-			y++
-		}
-		if nn == 0 {
-			y--
-		}
-		rn_num = (y-1)/4 - (y-1)/100 + (y-1)/400
-		rn_num -= 477
-		d = d - 365*(y-1970) - rn_num
-	} else { // 1970年以前
-		ms = int(t % 1000)
-		t /= 1000
-		if ms != 0 {
-			ms += 1000
-			t--
-		}
-		s = int(t % 86400)
-		d = int(t / 86400)
-		if s != 0 {
-			s += 86400
-			d--
-		}
-		wday = (d + 4) % 7
-		if wday < 0 {
-			wday += 7
-		}
-		mm = d / 146097
-		nn = d % 146097
-		y = 1969 + 400*mm
-		mm = nn / 36524
-		nn = nn % 36524
-		y += 100 * mm
-		mm = nn / 1461
-		nn = nn % 1461
-		y += 4 * mm
-		if nn < -1096 {
-			y -= 3
-		}
-		if nn < -731 && nn >= -1096 {
-			y -= 2
-		}
-		if nn < -365 && nn >= -731 {
-			y--
-		}
-		if nn == 0 {
-			y++
-		}
-		rn_num = y/4 - y/100 + y/400
-		rn_num -= 477
-		d = d - 365*(y+1-1970) - rn_num
-		if IsLeapYear(y) {
-			d += 366
-		} else {
-			d += 365
-		}
-	}
-
-	if d < 0 {
-		y--
-		if IsLeapYear(y) {
-			d += 366
-		} else {
-			d += 365
-		}
-	}
-
-	d++
-	if IsLeapYear(y) {
-		if d > 366 {
-			d -= 366
-			y++
-		}
-	} else if d > 365 {
-		d -= 365
-		y++
-	}
-
-	if IsLeapYear(y) {
-		for m = 0; m <= 11; m++ {
-			if d > mtod[1][m] && d <= mtod[1][m+1] {
-				d -= mtod[1][m]
-				break
-			}
-		}
-	} else {
-		for m = 0; m <= 11; m++ {
-			if d > mtod[0][m] && d <= mtod[0][m+1] {
-				d -= mtod[0][m]
-				break
-			}
-		}
-	}
-
-	return TIMESTAMP{
-		year:     y,
-		month:    m + 1,
-		day:      d,
-		hour:     s / 3600,
-		minute:   (s % 3600) / 60,
-		second:   s % 60,
-		fraction: ms,
-	}
-}

+ 0 - 28
xugu/xugu_result.go

@@ -1,28 +0,0 @@
-package xugu
-
-type xuguResult struct {
-
-	// Returns the number of rows affected
-	// by update, delete and other related operations
-	affectedRows int64
-
-	// Returns the GUID number of
-	// the insert operation (not supported)
-	insertId int64
-}
-
-// LastInsertId returns the integer generated by the database
-// in response to a command. Typically this will be from an
-// "auto increment" column when inserting a new row. Not all
-// databases support this feature, and the syntax of such
-// statements varies.
-func (self *xuguResult) LastInsertId() (int64, error) {
-	return self.insertId, nil
-}
-
-// RowsAffected returns the number of rows affected by an
-// update, insert, or delete. Not every database or database
-// driver may support this.
-func (self *xuguResult) RowsAffected() (int64, error) {
-	return self.affectedRows, nil
-}

+ 0 - 166
xugu/xugu_rows.go

@@ -1,166 +0,0 @@
-package xugu
-
-import (
-	"database/sql/driver"
-	"encoding/binary"
-	"fmt"
-	"io"
-	"math"
-	"reflect"
-	"time"
-)
-
-type xuguRows struct {
-	rows_conn *xuguConn
-
-	results  *SelectResult
-	colIdx   int
-	prepared bool
-}
-
-func (row *xuguRows) Next(dest []driver.Value) error {
-
-	if row.results.rowIdx >= len(row.results.Values[0]) {
-		//return errors.New("The result set has been released")
-		return io.EOF
-	}
-	//	fmt.Println(" -- int(row.results.Field_Num)", int(row.results.Field_Num))
-
-	for j := 0; j < int(row.results.Field_Num); j++ {
-
-		coluType := row.results.Fields[j].FieldType
-		//fmt.Println("  --coluType: ", coluType, row.results.Fields[j].typeDatabaseName())
-		if len(row.results.Values[j][row.results.rowIdx].Col_Data) == 0 {
-			dest[j] = nil
-		} else {
-			switch coluType {
-
-			case fieldType_BINARY,
-				fieldType_CLOB,
-				fieldType_BLOB:
-				fmt.Println(row.results.Values[j][row.results.rowIdx].Col_Data)
-				dest[j] = row.results.Values[j][row.results.rowIdx].Col_Data
-
-			case fieldType_INTERVAL_Y, fieldType_INTERVAL_M, fieldType_INTERVAL_D,
-				fieldType_INTERVAL_H, fieldType_INTERVAL_S,
-				fieldType_INTERVAL_MI:
-				dest[j] = binary.BigEndian.Uint32(row.results.Values[j][row.results.rowIdx].Col_Data)
-
-			case fieldType_TIME,
-				fieldType_TIME_TZ:
-				timeTmp := int32(binary.BigEndian.Uint32(row.results.Values[j][row.results.rowIdx].Col_Data))
-				//tv, _ := time.Parse("2006-01-02 15:04:05", string(reverseBytes(row.results.Values[j][row.results.rowIdx].Col_Data)))
-				tv := time.Date(0, 1, 1, 0, 0, 0, 0, time.UTC).Add((time.Millisecond * time.Duration(timeTmp)))
-				utcTime := tv.UTC()
-				dest[j] = utcTime
-			case fieldType_DATE:
-
-				timeTmp := int32(binary.BigEndian.Uint32(row.results.Values[j][row.results.rowIdx].Col_Data))
-				//tv, _ := time.Parse("2006-01-02 15:04:05", string(reverseBytes(row.results.Values[j][row.results.rowIdx].Col_Data)))
-				tv := time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC).Add((time.Hour * 24 * time.Duration(timeTmp)))
-				utcTime := tv.UTC()
-				dest[j] = utcTime
-				// fmt.Println(string(row.results.Values[j][row.results.rowIdx].Col_Data))
-				// tv, _ := time.Parse("15:04:05", string(row.results.Values[j][row.results.rowIdx].Col_Data))
-				// dest[j] = tv
-
-			case fieldType_DATETIME,
-				fieldType_DATETIME_TZ:
-
-				if len(row.results.Values[j][row.results.rowIdx].Col_Data) == 0 {
-					dest[j] = nil
-				} else {
-					//timeTmp := binary.LittleEndian.Uint64(reverseBytes(row.results.Values[j][row.results.rowIdx].Col_Data)
-					timeTmp := binary.BigEndian.Uint64(row.results.Values[j][row.results.rowIdx].Col_Data)
-					//tv, _ := time.Parse("2006-01-02 15:04:05", string(reverseBytes(row.results.Values[j][row.results.rowIdx].Col_Data)))
-					tv := time.Unix(0, int64(timeTmp)*1000000)
-					utcTime := tv.UTC()
-					dest[j] = utcTime
-				}
-
-			case fieldType_R4:
-				if len(row.results.Values[j][row.results.rowIdx].Col_Data) == 0 {
-					dest[j] = nil
-				} else {
-					dest[j] = math.Float32frombits(binary.BigEndian.Uint32(row.results.Values[j][row.results.rowIdx].Col_Data))
-				}
-
-			case fieldType_R8:
-				if len(row.results.Values[j][row.results.rowIdx].Col_Data) == 0 {
-					dest[j] = nil
-				} else {
-					dest[j] = math.Float64frombits(binary.BigEndian.Uint64(row.results.Values[j][row.results.rowIdx].Col_Data))
-				}
-			case fieldType_NUM:
-				dest[j] = row.results.Values[j][row.results.rowIdx].Col_Data
-			case fieldType_I1:
-				if len(row.results.Values[j][row.results.rowIdx].Col_Data) == 0 {
-					dest[j] = nil
-				} else {
-					dest[j] = int8(row.results.Values[j][row.results.rowIdx].Col_Data[0])
-				}
-			case fieldType_I2:
-				if len(row.results.Values[j][row.results.rowIdx].Col_Data) == 0 {
-					dest[j] = nil
-				} else {
-					dest[j] = int16(binary.BigEndian.Uint16(row.results.Values[j][row.results.rowIdx].Col_Data))
-				}
-			case fieldType_I4:
-				if len(row.results.Values[j][row.results.rowIdx].Col_Data) == 0 {
-					dest[j] = nil
-				} else {
-					dest[j] = int32(binary.BigEndian.Uint32(row.results.Values[j][row.results.rowIdx].Col_Data))
-				}
-			case fieldType_I8:
-				if len(row.results.Values[j][row.results.rowIdx].Col_Data) == 0 {
-					dest[j] = nil
-				} else {
-					dest[j] = int64(binary.BigEndian.Uint64(row.results.Values[j][row.results.rowIdx].Col_Data))
-					//dest[j] = row.results.Values[j][row.results.rowIdx].Col_Data
-				}
-			case fieldType_CHAR, fieldType_NCHAR:
-				if row.results.Values[j][row.results.rowIdx].Col_Data == nil {
-					dest[j] = string("")
-				} else if row.results.Values[j][row.results.rowIdx].Col_Data[0] == 0x00 {
-					dest[j] = string("")
-				} else {
-					dest[j] = string(row.results.Values[j][row.results.rowIdx].Col_Data)
-				}
-			default:
-
-				//填入一行的数据
-				//TODO这里长度改为一行长度
-				dest[j] = make([]byte, len(row.results.Values))
-				// Values[字段][0]
-				dest[j] = row.results.Values[j][row.results.rowIdx].Col_Data
-
-			}
-		}
-	}
-	row.results.rowIdx++
-
-	return nil
-}
-
-// Columns返回列的名字集,它的个数是从slice的长度中推断出来的。
-// 如果不知道特定的列名,应该为该条目返回一个空的字符串
-func (row *xuguRows) Columns() []string {
-
-	var columns []string
-
-	for _, v := range row.results.Fields {
-		columns = append(columns, v.FieldName)
-	}
-
-	return columns
-}
-
-func (row *xuguRows) ColumnTypeScanType(index int) reflect.Type {
-	fmt.Println(">>>>>ColumnTypeScanType ")
-
-	return row.results.Fields[index].scanType()
-}
-
-func (self *xuguRows) Close() error {
-	return nil
-}

+ 0 - 130
xugu/xugu_sock.go

@@ -1,130 +0,0 @@
-package xugu
-
-import (
-	"bytes"
-	"context"
-	"encoding/binary"
-	"errors"
-	"fmt"
-)
-
-func xgSockOpenConn(ctx context.Context, pConn *xuguConn) error {
-	//发送
-	//fmt.Printf("login   database = '%s' user = '%s'  password = '%s' version='201' ", pConn.Database, pConn.User, pConn.Password)
-	//	message := "login   database = 'SYSTEM' user = 'SYSDBA'  password = 'SYSDBA' version='201' "
-	dsnMessage := generateLoginString(pConn.dsnConfig)
-	_, err := pConn.conn.Write([]byte(dsnMessage))
-	if err != nil {
-		return errors.New("向数据库发起连接失败")
-	}
-
-	buffer := make([]byte, 1)
-	n, err := pConn.conn.Read(buffer)
-	if err != nil {
-		return errors.New(fmt.Sprintln("接收数据库连接失败: ", err.Error()))
-	}
-
-	if !bytes.Equal(buffer[:n], []byte("K")) {
-		return errors.New("数据库连接失败")
-	} else {
-		return nil
-	}
-
-}
-
-func sockSendPutStatement(pConn *xuguConn, sql []byte, values *[]xuguValue, paramCount int) error {
-	if pConn.sendBuff.Len() > 0 {
-		//将缓冲区重置为空
-		pConn.sendBuff.Reset()
-	}
-	// ?
-	pConn.sendBuff.Write([]byte("?"))
-	// Comand_Len
-	sqlLength := uint32(len(sql))
-	var networkBytes [4]byte
-	binary.BigEndian.PutUint32(networkBytes[:], sqlLength)
-	pConn.sendBuff.Write(networkBytes[:])
-	//  Comand_str
-	pConn.sendBuff.Write(sql)
-	//'0' end
-	binary.BigEndian.PutUint32(networkBytes[:], 0)
-	pConn.sendBuff.Write([]byte{0})
-	// Param_num
-
-	var Param_num [4]byte
-	binary.BigEndian.PutUint32(Param_num[:], uint32(paramCount))
-	pConn.sendBuff.Write(Param_num[:])
-	if values != nil {
-		//当缓冲区大于8190字节时,直接发送
-		// if pConn.sendBuff.Len() > 8190 {
-		// 	_, err := pConn.conn.Write(pConn.sendBuff.Bytes())
-		// 	if err != nil {
-		// 		fmt.Println("sockSend Write failed: ", err)
-		// 		return err
-		// 	}
-		// }
-
-		//发送后续参数
-		//	Param_num   { Param_name_len Param_name Param_INOUT Param_DType Param_Data_Len Param_Data }
-		for _, value := range *values {
-			//Param_name_len
-			if value.paramName == nil {
-				var Param_name_len [2]byte
-				pConn.sendBuff.Write(Param_name_len[:])
-				//Param_name
-				// var Param_name []byte
-				// pConn.sendBuff.Write(Param_name)
-
-			} else {
-				var Param_name_len [2]byte
-
-				binary.BigEndian.PutUint16(Param_name_len[:], uint16(len(value.paramName)))
-				pConn.sendBuff.Write(Param_name_len[:])
-
-				//Param_name
-				pConn.sendBuff.Write(value.paramName[:])
-
-			}
-
-			//Param_INOUT
-			Param_INOUT := [2]byte{0x1}
-			pConn.sendBuff.Write(reverseBytes(Param_INOUT[:]))
-
-			//Param_DType
-			var Param_DType [2]byte
-			binary.BigEndian.PutUint16(Param_DType[:], uint16(value.types))
-			pConn.sendBuff.Write(Param_DType[:])
-			//Param_Data_Len 根据DType 修改长度
-			Param_Data_Len := make([]byte, 4)
-			binary.BigEndian.PutUint32(Param_Data_Len[:], uint32(value.valueLength))
-			pConn.sendBuff.Write(Param_Data_Len[:])
-			//Param_Data 根据DType 修改长度
-			//Param_Data := make([]byte, value.valueLength)
-			pConn.sendBuff.Write([]byte(value.value))
-		}
-
-	}
-
-	return nil
-}
-
-func sockSendExecute(pConn *xuguConn) error {
-	//	fmt.Println("SockSendExecute msg: ", pConn.sendBuff.String())
-	_, err := pConn.conn.Write(pConn.sendBuff.Bytes())
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-func xuguSockRecvMsg(pConn *xuguConn) (*allResult, error) {
-	n, _ := pConn.conn.Read(pConn.readBuff.buf)
-	pConn.readBuff.length += n
-	rs, err := parseMsg(&pConn.readBuff, pConn)
-	if err != nil {
-
-		return nil, err
-	}
-	pConn.readBuff.reset()
-	return rs, nil
-}

+ 0 - 143
xugu/xugu_stmt.go

@@ -1,143 +0,0 @@
-package xugu
-
-import (
-	"database/sql/driver"
-	"errors"
-)
-
-type xuguStmt struct {
-
-	// 上下文连接句柄指针
-	stmt_conn *xuguConn
-
-	// 布尔值,用于标识执行的 SQL 语句是否已准备好
-	prepared bool
-
-	// 接受准备好的 SQL 语句的代码
-	prename []byte
-
-	// 布尔值,用于标识游标是否启用
-	curopend bool
-
-	// 游标名称
-	curname []byte
-
-	// 执行的 SQL 语句中的参数数量
-	paramCount int
-	mysql      string
-
-	//需替换的参数字段信息
-	//parser *xuguParse
-}
-
-func (stmt *xuguStmt) Close() error {
-	//关闭 prepare
-	err := xuguUnPrepare(stmt.stmt_conn, stmt.stmt_conn.prepareName)
-	//释放资源
-
-	return err
-}
-
-func (stmt *xuguStmt) NumInput() int {
-
-	return assertParamCount(stmt.mysql)
-	//return 0
-}
-
-func (stmt *xuguStmt) Exec(args []driver.Value) (driver.Result, error) {
-	
-
-	stmt.stmt_conn.mu.Lock()
-	defer stmt.stmt_conn.mu.Unlock()
-	//send msg
-	//如果有参数
-	if stmt.paramCount > 0 && len(args) > 0 {
-		values := []xuguValue{}
-		for _, param := range args {
-			assertParamType(param, &values)
-		}
-		sockSendPutStatement(stmt.stmt_conn, stmt.prename, &values, stmt.paramCount)
-		sockSendExecute(stmt.stmt_conn)
-		//没有参数
-	} else {
-		sockSendPutStatement(stmt.stmt_conn, []byte(stmt.mysql), nil, 0)
-		sockSendExecute(stmt.stmt_conn)
-	}
-
-	//recv msg
-	aR, err := xuguSockRecvMsg(stmt.stmt_conn)
-	if err != nil {
-		return nil, err
-	}
-	switch aR.rt {
-	case selectResult:
-
-		return nil, errors.New("exec is Query error")
-	case updateResult:
-		return &xuguResult{affectedRows: int64(aR.u.UpdateNum), insertId: int64(0)}, nil
-	case insertResult:
-		return &xuguResult{affectedRows: int64(0), insertId: int64(aR.i.RowidLen)}, nil
-	case errInfo:
-
-		return nil, errors.New(string(aR.e.ErrStr))
-	case warnInfo:
-
-		return nil, errors.New(string(aR.w.WarnStr))
-	default:
-		return &xuguResult{
-			affectedRows: int64(0),
-			insertId:     int64(0),
-		}, nil
-	}
-
-}
-
-func (stmt *xuguStmt) Query(args []driver.Value) (driver.Rows, error) {
-
-	
-	stmt.stmt_conn.mu.Lock()
-	defer stmt.stmt_conn.mu.Unlock()
-
-	//send msg
-	//如果有参数
-	if stmt.paramCount > 0 && len(args) > 0 {
-		values := []xuguValue{}
-		for _, param := range args {
-			assertParamType(param, &values)
-		}
-		sockSendPutStatement(stmt.stmt_conn, stmt.prename, &values, stmt.paramCount)
-		sockSendExecute(stmt.stmt_conn)
-		//没有参数
-	} else {
-		sockSendPutStatement(stmt.stmt_conn, []byte(stmt.mysql), nil, 0)
-		sockSendExecute(stmt.stmt_conn)
-	}
-
-	//recv msg
-	aR, err := xuguSockRecvMsg(stmt.stmt_conn)
-	if err != nil {
-		return nil, err
-	}
-
-	switch aR.rt {
-	case selectResult:
-
-		rows := &xuguRows{
-			rows_conn: stmt.stmt_conn,
-			results:   aR.s,
-			colIdx:    0,
-			prepared:  false,
-		}
-
-		return rows, nil
-	case errInfo:
-
-		return nil, errors.New(string(aR.e.ErrStr))
-	case warnInfo:
-
-		return nil, errors.New(string(aR.w.WarnStr))
-	default:
-	}
-
-	return nil, errors.New("xugu Query error")
-}

+ 0 - 36
xugu/xugu_tranx.go

@@ -1,36 +0,0 @@
-package xugu
-
-import "errors"
-
-type xuguTx struct {
-	tconn *xuguConn
-}
-
-func (tx *xuguTx) Commit() error {
-	tx.tconn.mu.Lock()
-	defer tx.tconn.mu.Unlock()
-
-	if tx.tconn == nil {
-		return errors.New("invalid connection")
-	}
-	_, err := tx.tconn.exec("commit;", nil)
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-func (tx *xuguTx) Rollback() error {
-	tx.tconn.mu.Lock()
-	defer tx.tconn.mu.Unlock()
-
-	if tx.tconn == nil {
-		return errors.New("invalid connection")
-	}
-	_, err := tx.tconn.exec("rollback;", nil)
-	if err != nil {
-		return err
-	}
-
-	return err
-}

+ 0 - 189
xugu/xugu_utils.go

@@ -1,189 +0,0 @@
-package xugu
-
-import (
-	"encoding/binary"
-	"fmt"
-	"strings"
-)
-
-func parseDSN(dsn string) dsnConfig {
-	// Initialize a dsnConfig struct
-	var config dsnConfig
-
-	// Split the string by semicolons
-	pairs := strings.Split(dsn, ";")
-
-	// Iterate over the pairs and map them to the struct fields
-	for _, pair := range pairs {
-		// Split each pair by the equals sign
-		kv := strings.SplitN(pair, "=", 2)
-		if len(kv) != 2 {
-			continue
-		}
-		key, value := strings.TrimSpace(kv[0]), strings.Trim(strings.TrimSpace(kv[1]), "'")
-		keyL := strings.ToLower(key)
-
-		// Map the key to the appropriate struct field
-		switch keyL {
-		case "ip":
-			config.IP = value
-		case "port":
-			config.Port = value
-		case "db":
-			config.Database = value
-		case "user":
-			config.User = value
-		case "pwd":
-			config.Password = value
-		case "encryptor":
-			config.Encryptor = value
-		case "char_set":
-			config.CharSet = value
-		case "time_zone":
-			config.TimeZone = value
-		case "iso_level":
-			config.IsoLevel = value
-		case "lock_timeout":
-			config.LockTimeout = value
-		case "auto_commit":
-			config.AutoCommit = value
-		case "strict_commit":
-			config.StrictCommit = value
-		case "result":
-			config.Result = value
-		case "return_schema":
-			config.ReturnSchema = value
-		case "return_cursor_id":
-			config.ReturnCursorID = value
-		case "lob_ret":
-			config.LobRet = value
-		case "return_rowid":
-			config.ReturnRowid = value
-		case "version":
-			config.Version = value
-		}
-	}
-
-	return config
-}
-
-func generateLoginString(config dsnConfig) string {
-	baseString := "login   database = '%s' user = '%s'  password = '%s' "
-	additionalParams := ""
-
-	if config.Encryptor != "" {
-		additionalParams += fmt.Sprintf(" encryptor='%s'", config.Encryptor)
-	}
-	if config.CharSet != "" {
-		additionalParams += fmt.Sprintf(" char_set='%s'", config.CharSet)
-	}
-	if config.TimeZone != "" {
-		additionalParams += fmt.Sprintf(" time_zone='%s'", config.TimeZone)
-	}
-	if config.IsoLevel != "" {
-		additionalParams += fmt.Sprintf(" iso_level='%s'", config.IsoLevel)
-	}
-	if config.LockTimeout != "" {
-		additionalParams += fmt.Sprintf(" lock_timeout='%s'", config.LockTimeout)
-	}
-	if config.AutoCommit != "" {
-		additionalParams += fmt.Sprintf(" auto_commit='%s'", config.AutoCommit)
-	}
-	if config.StrictCommit != "" {
-		additionalParams += fmt.Sprintf(" strict_commit='%s'", config.StrictCommit)
-	}
-	if config.Result != "" {
-		additionalParams += fmt.Sprintf(" result='%s'", config.Result)
-	}
-	if config.ReturnSchema != "" {
-		additionalParams += fmt.Sprintf(" return_schema='%s'", config.ReturnSchema)
-	}
-	if config.ReturnCursorID != "" {
-		additionalParams += fmt.Sprintf(" return_cursor_id='%s'", config.ReturnCursorID)
-	}
-	if config.LobRet != "" {
-		additionalParams += fmt.Sprintf(" lob_ret='%s'", config.LobRet)
-	}
-	if config.ReturnRowid != "" {
-		additionalParams += fmt.Sprintf(" return_rowid='%s'", config.ReturnRowid)
-	}
-	if config.Version != "" {
-		additionalParams += fmt.Sprintf(" version='%s'", config.Version)
-	} else {
-		additionalParams += " version='201'"
-	}
-
-	finalString := fmt.Sprintf(baseString, config.Database, config.User, config.Password)
-	if additionalParams != "" {
-		finalString += additionalParams
-	}
-	//finalString += " version='201'"
-	return finalString
-}
-
-// reverseBytes 反转 byte slice 的顺序
-func reverseBytes(b []byte) []byte {
-	reversed := make([]byte, len(b))
-	for i := range b {
-		reversed[i] = b[len(b)-1-i]
-	}
-	return reversed
-}
-
-func gt(name string) {
-	fmt.Printf("\n=============%s================\n", name)
-}
-
-func switchSQLType(sql string) int {
-	// 去掉首尾的空格、换行符和回车符
-	sql = strings.TrimSpace(sql)
-	if len(sql) < 6 {
-		return SQL_OTHER
-	}
-
-	// 取前6个字符并转为大写
-	kstr := strings.ToUpper(sql[:6])
-
-	// 根据SQL语句前缀判断类型
-	switch {
-	case strings.HasPrefix(kstr, "SELECT"):
-		if strings.Contains(sql, ";") && len(sql[strings.Index(sql, ";"):]) > 5 {
-			return SQL_OTHER // 多结果集
-		}
-		return SQL_SELECT
-	case strings.HasPrefix(kstr, "INSERT"):
-		return SQL_INSERT
-	case strings.HasPrefix(kstr, "UPDATE"):
-		return SQL_UPDATE
-	case strings.HasPrefix(kstr, "DELETE"):
-		return SQL_DELETE
-	case strings.HasPrefix(kstr, "CREATE"):
-		return SQL_CREATE
-	case strings.HasPrefix(kstr, "ALTER "):
-		return SQL_ALTER
-	case strings.HasPrefix(kstr, "EXEC "):
-		return SQL_PROCEDURE
-	case strings.HasPrefix(kstr, "EXECUT"):
-		return SQL_PROCEDURE
-	case strings.HasPrefix(kstr, "STC"):
-		return SQL_SELECT
-	default:
-		return SQL_OTHER
-	}
-}
-
-// CheckEndian 判断机器的字节序
-func CheckEndian() bool {
-	var i int32 = 0x01020304
-	b := [4]byte{}
-
-	// 将整数值写入字节切片
-	binary.BigEndian.PutUint32(b[:], uint32(i))
-
-	// 判断字节序
-	if b[0] == 0x01 {
-		return false // 大端字节序
-	} else {
-		return true // 小端字节序
-	}
-}