Przeglądaj źródła

fix: buff接收消息size问题。
TODO:buff 接收消息EOF状态处理,
TODO:多结果集处理

GTong 9 miesięcy temu
rodzic
commit
ef3a7d156f

+ 6 - 1
.gitignore

@@ -1,3 +1,8 @@
 xugusql_driver/
 go.mod
-go.sum
+go.sum
+main.go
+xugu_zhushi/
+2000w.go
+协议.ini
+.vscode/

+ 94 - 48
main.go

@@ -6,6 +6,7 @@ import (
 	"log"
 	"os"
 	"sync"
+	"time"
 	_ "xugu_go_driver/xugu"
 )
 
@@ -188,63 +189,108 @@ func processQuery(db *sql.DB, id int, logger *log.Logger) {
 	fmt.Printf("goroutine %d 完成\n", id)
 }
 
+type userInfo struct {
+	Id       int
+	Username string
+	Password string
+	Power    sql.NullByte
+}
+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=10.28.20.101;DB=SYSTEM;User=SYSDBA;PWD=SYSDBA;Port=5190;AUTO_COMMIT=on;CHAR_SET=UTF8")
+
+	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)
 	}
-	lp := LicenseProcess{
-		Creator:         "Alice",
-		ApplyDate:       "2023-01-01",
-		RelatedProject:  "Project A",
-		SalesPerson:     "Bob",
-		SalesEmail:      "bob@example.com",
-		TechSupport:     "Charlie",
-		TechEmail:       "charlie@example.com",
-		ProductName:     "Product X",
-		Version:         "1.0",
-		Processor:       "Intel",
-		OperatingSystem: "Linux",
-		IP:              "192.168.1.1",
-		MAC:             "00:1A:2B:3C:4D:5E",
-	}
-	var Ins2 = `
-	INSERT INTO LicenseProcess (
-		Creator, ApplyDate, RelatedProject, SalesPerson, SalesEmail, TechSupport, TechEmail,
-		ProductName, Version, Processor, OperatingSystem, IP, MAC
-	) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
-	`
-	_, err = db.Exec(Ins2,
-		lp.Creator, lp.ApplyDate, lp.RelatedProject, lp.SalesPerson, lp.SalesEmail, lp.TechSupport, lp.TechEmail,
-		lp.ProductName, lp.Version, lp.Processor, lp.OperatingSystem, lp.IP, lp.MAC,
-	)
-	if err != nil {
+	query := fmt.Sprintf(`
+				SELECT la.*,li.lic1, li.lic2
+				FROM LicenseApplication la
+				JOIN licenseRecord lr ON la.UniqueID = lr.LicenseUniqueID
+				JOIN LicenseInfo li ON la.UniqueID = li.LicenseApplicationUniqueID
+				WHERE lr.USERS LIKE '%%%s%%'
+				LIMIT ? OFFSET ?`, "test3")
 
-		fmt.Printf("[ERROR] %s\n", err.Error())
-		return
+	rows, err := db.Query(query, 10, 0)
+	if err != nil {
+		fmt.Println("query data: %v", err)
+		//return nil, 0, fmt.Errorf("query error: %v", err)
 	}
+	defer rows.Close()
+	var results []LicenseInfo
+	for rows.Next() {
+		var li LicenseInfo
 
-	fmt.Printf("%s ... ok\n", Ins2)
+		err = rows.Scan(
+			&li.ID,
+			&li.UniqueID,
+			&li.UserID,
+			&li.UpUser,
+			&li.UpTime,
+			&li.DelTime,
+			&li.LicenseApplication.Creator,
+			&li.LicenseApplication.ApplicationDate,
+			&li.LicenseApplication.AssociatedProject,
+			&li.LicenseApplication.SalesPerson,
+			&li.LicenseApplication.SalesEmail,
+			&li.LicenseApplication.SupportPerson,
+			&li.LicenseApplication.SupportEmail,
+			&li.LicenseApplication.TotalNodes,
+			&li.LicenseApplication.Company,
+			&li.LicenseApplication.ProductName,
+			&li.LicenseApplication.Version,
+			&li.LicenseApplication.NodeCount,
+			&li.LicenseApplication.Processor,
+			&li.LicenseApplication.OperatingSystem,
+			&li.LicenseApplication.MasterMacAddress,
+			&li.LicenseApplication.SecondaryMasterMacAddress,
+			&li.License1,
+			&li.License2,
+		)
 
-	err = db.Close()
-	if err != nil {
+		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)
+	}
 
-		fmt.Printf("[ERROR] %s\n", err.Error())
+	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)
 
-type LicenseProcess struct {
-	Creator         string // 创建人
-	ApplyDate       string // 申请日期
-	RelatedProject  string // 关联项目
-	SalesPerson     string // 销售人员
-	SalesEmail      string // 销售邮箱
-	TechSupport     string // 技术人员
-	TechEmail       string // 技术邮箱
-	ProductName     string // 产品名称
-	Version         string // 版本
-	Processor       string // 处理器
-	OperatingSystem string // 操作系统
-	IP              string // IP
-	MAC             string // MAC
 }

+ 0 - 0
test/stability_test.log


+ 54 - 19
test/typeTime_test.go

@@ -154,31 +154,66 @@ FROM example_table`
 	defer rows.Close()
 
 	for rows.Next() {
-		var record ExampleRecord
+		var example ExampleRecord
 		err := rows.Scan(
-			&record.TimeField,
-			&record.DatetimeField,
-			&record.DateField,
-			&record.TimeWithZoneField,
-			&record.DatetimeWithZoneField,
-			&record.IntervalYearField,
-			&record.IntervalMonthField,
-			&record.IntervalDayField,
-			&record.IntervalHourField,
-			&record.IntervalMinuteField,
-			&record.IntervalSecondField,
-			&record.IntervalDayToHourField,
-			&record.IntervalDayToMinuteField,
-			&record.IntervalDayToSecondField,
-			&record.IntervalHourToMinuteField,
-			&record.IntervalHourToSecondField,
-			&record.IntervalMinuteToSecondField,
+			&example.TimeField,
+			&example.DatetimeField,
+			&example.DateField,
+			&example.TimeWithZoneField,
+			&example.DatetimeWithZoneField,
+			&example.IntervalYearField,
+			&example.IntervalMonthField,
+			&example.IntervalDayField,
+			&example.IntervalHourField,
+			&example.IntervalMinuteField,
+			&example.IntervalSecondField,
+			&example.IntervalDayToHourField,
+			&example.IntervalDayToMinuteField,
+			&example.IntervalDayToSecondField,
+			&example.IntervalHourToMinuteField,
+			&example.IntervalHourToSecondField,
+			&example.IntervalMinuteToSecondField,
 		)
 		if err != nil {
 			log.Fatalf("Failed to scan row: %v", err)
 		}
 
-		fmt.Printf("%+v\n", record)
+		fmt.Printf("ExampleRecord:\n"+
+			"TimeField: %v\n"+
+			"DatetimeField: %v\n"+
+			"DateField: %v\n"+
+			"TimeWithZoneField: %v\n"+
+			"DatetimeWithZoneField: %v\n"+
+			"IntervalYearField: %s\n"+
+			"IntervalMonthField: %s\n"+
+			"IntervalDayField: %s\n"+
+			"IntervalHourField: %s\n"+
+			"IntervalMinuteField: %s\n"+
+			"IntervalSecondField: %s\n"+
+			"IntervalDayToHourField: %s\n"+
+			"IntervalDayToMinuteField: %s\n"+
+			"IntervalDayToSecondField: %s\n"+
+			"IntervalHourToMinuteField: %s\n"+
+			"IntervalHourToSecondField: %s\n"+
+			"IntervalMinuteToSecondField: %s\n",
+			example.TimeField,
+			example.DatetimeField,
+			example.DateField,
+			example.TimeWithZoneField,
+			example.DatetimeWithZoneField,
+			example.IntervalYearField,
+			example.IntervalMonthField,
+			example.IntervalDayField,
+			example.IntervalHourField,
+			example.IntervalMinuteField,
+			example.IntervalSecondField,
+			example.IntervalDayToHourField,
+			example.IntervalDayToMinuteField,
+			example.IntervalDayToSecondField,
+			example.IntervalHourToMinuteField,
+			example.IntervalHourToSecondField,
+			example.IntervalMinuteToSecondField)
+
 	}
 
 	if err = rows.Err(); err != nil {

+ 8 - 10
xugu/xugu_buffer.go

@@ -2,7 +2,6 @@ package xugu
 
 import (
 	"errors"
-	"fmt"
 	"net"
 	"time"
 )
@@ -28,8 +27,11 @@ func newBuffer(nc net.Conn) buffer {
 }
 
 func (b *buffer) peekChar() byte {
+	if b.idx >= int64(len(b.buf)) {
+		b.readNext(1, false)
+		b.idx-- //peekchar 只查看当前字符,不移动指针,但是readNext会移动指针,所以需要-1
+	}
 	ret := b.buf[b.idx]
-	//	fmt.Println("peekChar内部的: ", b.buf[b.idx:])
 	return ret
 }
 func (b *buffer) reset() {
@@ -39,8 +41,10 @@ func (b *buffer) reset() {
 }
 
 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...)
@@ -49,7 +53,6 @@ func (b *buffer) readNext(need int, reverse bool) ([]byte, error) {
 			// if err == io.EOF {
 
 			// }
-			//	fmt.Println("Error reading from server:", err)
 			return nil, err
 		}
 
@@ -63,7 +66,7 @@ func (b *buffer) readNext(need int, reverse bool) ([]byte, error) {
 				// 	fmt.Println("End of data")
 
 				// }
-				fmt.Println("Error reading from server:", err)
+
 				return nil, err
 			}
 			//nTmp += n
@@ -78,15 +81,10 @@ func (b *buffer) readNext(need int, reverse bool) ([]byte, error) {
 		reverse = false
 	}
 	if reverse {
-		//	tmp2 := b.buf[offset:b.idx]
-		//fmt.Println("readNext: 转换小端前", tmp2, " - ", string(tmp2))
 		tmp := reverseBytes(b.buf[offset:b.idx])
-		//	fmt.Println("readNext: 转换小端后", tmp, " - ", string(tmp))
 
 		return tmp, nil
 	} else {
-		//	fmt.Println("readNext: 没有转换:", b.buf[offset:b.idx])
-		//	fmt.Println("readNext: 没有转换:", string(b.buf[offset:b.idx]))
 
 		return b.buf[offset:b.idx], nil
 	}

+ 6 - 25
xugu/xugu_conn.go

@@ -50,20 +50,17 @@ type dsnConfig struct {
 }
 
 func (xgConn *xuguConn) Begin() (driver.Tx, error) {
-	gt("xuguConn.Begin")
-	defer gt("xuguConn.Begin end")
+	
 	return &xuguTx{tconn: xgConn}, nil
 
 }
 
 func (xgConn *xuguConn) Close() error {
-	gt("xuguConn.Close")
-	defer gt("xuguConn.Close end")
+
 	xgConn.mu.Lock()
 	defer xgConn.mu.Unlock()
 	err := xgConn.conn.Close()
 	if err != nil {
-		fmt.Println("Close connection error")
 		xgConn.mu.Unlock()
 		return err
 	}
@@ -73,8 +70,7 @@ func (xgConn *xuguConn) Close() error {
 
 func (xgConn *xuguConn) Query(sql string,
 	args []driver.Value) (driver.Rows, error) {
-	gt("xuguConn.Query")
-	defer gt("xuguConn.Query end")
+
 
 	xgConn.mu.Lock()
 	defer xgConn.mu.Unlock()
@@ -145,8 +141,6 @@ func (xgConn *xuguConn) Query(sql string,
 }
 
 func (xgConn *xuguConn) Ping(ctx context.Context) error {
-	gt("xuguConn.Ping")
-	defer gt("xuguConn.Ping end")
 
 	//send
 	xgConn.mu.Lock()
@@ -156,7 +150,6 @@ func (xgConn *xuguConn) Ping(ctx context.Context) error {
 
 	_, err := xuguSockRecvMsg(xgConn)
 	if err != nil {
-		fmt.Println("Ping err : ", err.Error())
 		return err
 	}
 	xgConn.readBuff.reset()
@@ -165,8 +158,7 @@ func (xgConn *xuguConn) Ping(ctx context.Context) error {
 }
 
 func (xgConn *xuguConn) Prepare(sql string) (driver.Stmt, error) {
-	gt("xuguConn.Prepare")
-	defer gt("xuguConn.Prepare end")
+
 
 	xgConn.mu.Lock()
 	defer xgConn.mu.Unlock()
@@ -184,7 +176,6 @@ func (xgConn *xuguConn) Prepare(sql string) (driver.Stmt, error) {
 	prepareName := "GTONG"
 
 	err := xuguPrepare(xgConn, sql, prepareName)
-	fmt.Println("xuguPrepare err : ", err)
 	if err != nil {
 		return nil, err
 	}
@@ -205,7 +196,6 @@ func (xgConn *xuguConn) Prepare(sql string) (driver.Stmt, error) {
 
 func xuguPrepare(pConn *xuguConn, cmd_sql string, prepareName string) error {
 
-	fmt.Println("\n ---xuguPrepare")
 	prepareName = fmt.Sprintf("%s%d", prepareName, pConn.prepareNo)
 	sqlRet := fmt.Sprintf("PREPARE %s AS %s", prepareName, cmd_sql)
 	pConn.prepareName = prepareName
@@ -227,21 +217,16 @@ func xuguPrepare(pConn *xuguConn, cmd_sql string, prepareName string) error {
 	}
 
 	if err != nil {
-		fmt.Println("xuguPrepare parseMsg(&pConn.readBuff, pConn)")
 		return err
 	}
 
-	fmt.Println("\n ---xuguPrepare end")
-
 	return nil
 }
 
 func xuguUnPrepare(pConn *xuguConn, prepareName string) error {
 
-	fmt.Println("\n ---xuguUnPrepare")
 	sqlRet := fmt.Sprintf("DEALLOCATE %s ", prepareName)
-	fmt.Println("sqlRet : ", sqlRet)
-	fmt.Println("prepareName : ", prepareName)
+
 	//send msg
 	sockSendPutStatement(pConn, []byte(sqlRet), nil, 0)
 	sockSendExecute(pConn)
@@ -261,19 +246,15 @@ func xuguUnPrepare(pConn *xuguConn, prepareName string) error {
 	}
 
 	if err != nil {
-		fmt.Println("xuguUnPrepare parseMsg(&pConn.readBuff, pConn)")
 		return err
 	}
 
-	fmt.Println("\n ---xuguUnPrepare end")
-
 	return nil
 }
 
 func (xgConn *xuguConn) Exec(sql string,
 	args []driver.Value) (driver.Result, error) {
-	gt("xuguConn.Exec")
-	defer gt("xuguConn.Exec end")
+	
 	xgConn.mu.Lock()
 	defer xgConn.mu.Unlock()
 

+ 3 - 7
xugu/xugu_connector.go

@@ -15,7 +15,7 @@ type connector struct {
 // Driver implements driver.Connector interface.
 // Driver returns &XuguDriver{}
 func (conntor *connector) Driver() driver.Driver {
-	fmt.Println(">>>>>(conntor *connector) Driver()")
+
 	return &XuguDriver{}
 }
 
@@ -30,8 +30,7 @@ dsn解析
 接收来自服务端的握手请求
 */
 func (conntor *connector) Connect(ctx context.Context) (driver.Conn, error) {
-	gt("(conntor *connector) Connect(ctx context.Context) run ")
-	defer gt("(conntor *connector) Connect(ctx context.Context) end")
+
 	GlobalIsBig = CheckEndian()
 
 	dsnConfig := parseDSN(conntor.dsn)
@@ -39,10 +38,9 @@ func (conntor *connector) Connect(ctx context.Context) (driver.Conn, error) {
 	xgConn := &xuguConn{conn: nil}
 	xgConn.dsnConfig = dsnConfig
 
-	nd := net.Dialer{Timeout: 50 * time.Second}
+	nd := net.Dialer{Timeout: 10 * time.Millisecond}
 	netConn, err := nd.DialContext(ctx, "tcp", fmt.Sprintf("%s:%s", xgConn.IP, xgConn.Port))
 	if err != nil {
-		fmt.Println("tcp Connect error: ", err)
 		return nil, err
 	}
 
@@ -50,7 +48,6 @@ func (conntor *connector) Connect(ctx context.Context) (driver.Conn, error) {
 	if tc, ok := netConn.(*net.TCPConn); ok {
 		if err := tc.SetKeepAlive(true); err != nil {
 			//c.cfg.Logger.Print(err) // 如果设置保活失败,记录错误但不终止
-			fmt.Println("SetKeepAlive error", err)
 			return nil, err
 		}
 	}
@@ -58,7 +55,6 @@ func (conntor *connector) Connect(ctx context.Context) (driver.Conn, error) {
 	xgConn.conn = netConn
 	xgConn.mu.Lock()
 	xgConn.readBuff = newBuffer(xgConn.conn)
-	fmt.Println("连接串为: ", conntor.dsn)
 	err = xgSockOpenConn(ctx, xgConn)
 	if err != nil {
 		return nil, err

+ 3 - 6
xugu/xugu_driver.go

@@ -12,8 +12,7 @@ type XuguDriver struct{}
 
 /* Register Driver */
 func init() {
-	gt("init()")
-	defer gt("init() end")
+
 	/* 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.
@@ -40,14 +39,12 @@ func init() {
 // function should be called just once. It is rarely necessary to
 // close a DB.
 func (db XuguDriver) Open(dsn string) (driver.Conn, error) {
-	gt("Open")
-	defer gt("Open end")
+
 	conn := &connector{dsn: dsn}
 	return conn.Connect(context.Background())
 }
 
 func (db XuguDriver) OpenConnector(dsn string) (driver.Connector, error) {
-	gt("OpenConnector")
-	defer gt("OpenConnector end")
+
 	return &connector{dsn: dsn}, nil
 }

+ 23 - 25
xugu/xugu_fields.go

@@ -2,8 +2,6 @@ package xugu
 
 import (
 	"database/sql"
-	"database/sql/driver"
-	"fmt"
 	"reflect"
 	"time"
 )
@@ -206,26 +204,26 @@ var (
 	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")
-	}
-}
+// 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")
+// 	}
+// }

+ 5 - 5
xugu/xugu_model.go

@@ -6,6 +6,11 @@ type SelectResult struct {
 	Values    [][]FieldValue //[字段][字段所有值]
 	rowIdx    int
 	fad       *FormArgDescri
+	next      *SelectResult
+}
+type FormArgDescri struct {
+	ArgNum uint32
+	Args   []ArgDescri
 }
 
 type FieldValue struct {
@@ -54,11 +59,6 @@ type Message struct {
 	MsgStr    []byte
 }
 
-type FormArgDescri struct {
-	ArgNum uint32
-	Args   []ArgDescri
-}
-
 type ArgDescri struct {
 	ArgNameLen    uint32
 	ArgName       []byte

+ 3 - 36
xugu/xugu_parse.go

@@ -26,10 +26,8 @@ type xuguValue struct {
 
 // 判断参数个数
 func assertParamCount(query string) int {
-	fmt.Println("----assertParamCount func 判断参数个数")
 
 	paramCount := strings.Count(query, "?")
-	fmt.Println("Parse.param_count = ", paramCount)
 
 	return paramCount
 }
@@ -97,7 +95,7 @@ func assertParamType(dV driver.Value, values *[]xuguValue) error {
 		}
 
 	case nil:
-		dest.value = []byte{0}
+		dest.value = nil
 		dest.valueLength = 0
 		dest.islob = false
 		dest.types = fieldType_NULL
@@ -115,17 +113,14 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 	aR := allResult{}
 	for {
 		char := readBuf.peekChar()
-		fmt.Println("parseMsg 内的 peekChar: ", char, "-", string(char))
 		switch char {
 
 		case 'K':
-			fmt.Println("消息类型为K")
 			readBuf.reset()
 			return &aR, nil
 
 		case '$':
 			readBuf.idx++
-			fmt.Println("消息类型为$")
 			if aR.f, err = parseFormArgDescri(readBuf); err != nil {
 				return nil, err
 			}
@@ -133,7 +128,6 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 			return &aR, err
 		case 'A':
 			readBuf.idx++
-			fmt.Println("消息类型为A")
 			if aR.s, err = parseSelectResult(readBuf); err != nil {
 				return nil, err
 			}
@@ -142,7 +136,6 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 
 		case 'I':
 			readBuf.idx++
-			fmt.Println("消息类型为I")
 			if aR.i, err = parseInsertResult(readBuf); err != nil {
 				return nil, err
 			}
@@ -150,7 +143,6 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 			return &aR, err
 
 		case 'U':
-			fmt.Println("消息类型为U")
 			readBuf.idx++
 			if aR.u, err = parseUpdateResult(readBuf); err != nil {
 				return nil, err
@@ -159,7 +151,6 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 			return &aR, err
 
 		case 'D':
-			fmt.Println("消息类型为D")
 			readBuf.idx++
 			readBuf.idx++
 			if aR.d, err = parseDeleteResult(readBuf); err != nil {
@@ -169,7 +160,6 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 			return &aR, err
 
 		case 'E':
-			fmt.Println("消息类型为E")
 			readBuf.idx++
 
 			if aR.e, err = parseErrInfo(readBuf); err != nil {
@@ -180,7 +170,6 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 			return &aR, err
 
 		case 'W':
-			fmt.Println("消息类型为W")
 			readBuf.idx++
 			if aR.w, err = parseWarnInfo(readBuf); err != nil {
 				return nil, err
@@ -189,7 +178,6 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 			return &aR, err
 
 		case 'M':
-			fmt.Println("消息类型为M")
 			readBuf.idx++
 			if aR.m, err = parseMessage(readBuf); err != nil {
 				return nil, err
@@ -198,18 +186,15 @@ func parseMsg(readBuf *buffer, pConn *xuguConn) (*allResult, error) {
 			return &aR, err
 
 		default:
-			fmt.Println("消息类型为其他")
 			return nil, errors.New("parseMsg: unknown message type")
 		}
 
 	}
 }
 func parseSelectResult(readBuf *buffer) (*SelectResult, error) {
-	fmt.Println("调用 parseSelectResult")
 	data := &SelectResult{}
 
 	char := readBuf.peekChar()
-	fmt.Println("--=char: ", string(char), char)
 
 	//Field_Num
 	fn, err := readBuf.readNext(4, true)
@@ -220,7 +205,6 @@ func parseSelectResult(readBuf *buffer) (*SelectResult, error) {
 	Field_Num := binary.LittleEndian.Uint32(fn)
 	data.Field_Num = Field_Num
 	data.rowIdx = 0
-	fmt.Println("Field_Num: ", data.Field_Num)
 
 	//获取字段信息
 	for i := 0; i < int(Field_Num); i++ {
@@ -233,7 +217,6 @@ func parseSelectResult(readBuf *buffer) (*SelectResult, error) {
 			return nil, err
 		}
 		field.FieldNameLen = int(binary.LittleEndian.Uint32(Field_Name_Len))
-		fmt.Println("field.FieldNameLen: ", field.FieldNameLen)
 
 		//Field_Name:
 		Field_Name, err := readBuf.readNext(field.FieldNameLen, false)
@@ -241,7 +224,6 @@ func parseSelectResult(readBuf *buffer) (*SelectResult, error) {
 			return nil, err
 		}
 		field.FieldName = string(Field_Name)
-		fmt.Println("field.Field_Name: ", field.FieldName)
 
 		//Field_DType:
 		Field_DType, err := readBuf.readNext(4, true)
@@ -249,7 +231,6 @@ func parseSelectResult(readBuf *buffer) (*SelectResult, error) {
 			return nil, err
 		}
 		field.FieldType = fieldType(binary.LittleEndian.Uint32(Field_DType))
-		fmt.Println("field.FieldType: ", field.FieldType)
 
 		//Field_Preci_Scale:
 		Field_Preci_Scale, err := readBuf.readNext(4, true)
@@ -269,7 +250,6 @@ func parseSelectResult(readBuf *buffer) (*SelectResult, error) {
 				accuracy: uint16(fieldPreciScale & 0xFFFF),
 			}
 		}
-		fmt.Println("field.FieldPreciScale: ", field.FieldPreciScale)
 
 		//Field_Flag:
 		Field_Flag, err := readBuf.readNext(4, true)
@@ -277,7 +257,6 @@ func parseSelectResult(readBuf *buffer) (*SelectResult, error) {
 			return nil, err
 		}
 		field.FieldFlag = binary.LittleEndian.Uint32(Field_Flag)
-		fmt.Println("field.FieldFlag: ", field.FieldFlag)
 		data.Fields = append(data.Fields, field)
 	}
 
@@ -285,20 +264,14 @@ func parseSelectResult(readBuf *buffer) (*SelectResult, error) {
 
 	//获取字段的行值,并判断类型
 	// 使用 Peek 方法检查下一个字节是否为'R'或'K'
-	fmt.Println("\n\n=========开始获取行数据=================================")
-	defer func() {
-		fmt.Println("\n\n=========获取行数据结束=================================")
-	}()
 
 	char = readBuf.peekChar()
-	fmt.Println("  --char: ", string(char))
 	readBuf.idx++
 	if char == 'K' {
 		return data, nil
 	} else if char == 'R' {
 		colIdx := 0
 		//typeIdx := 0
-		fmt.Println("开始循环 ")
 
 		for {
 			col := FieldValue{}
@@ -314,15 +287,12 @@ func parseSelectResult(readBuf *buffer) (*SelectResult, error) {
 			if err != nil {
 				return nil, err
 			}
-			fmt.Println("col.Col_Data: ", col.Col_Data)
+			
 			data.Values[colIdx] = append(data.Values[colIdx], col)
 			colIdx++
-			// if col.Col_len > 8000 {
-			// 	fmt.Println("数据为: ", col.Col_Data)
-			// }
+		
 			char := readBuf.peekChar()
 
-			//fmt.Println("buf is ", readBuf.buf[readBuf.idx:])
 			//既不是R 也不是K 代表该行还有其他字段内容没有读取完成
 			if char == 'R' {
 				readBuf.idx++
@@ -336,7 +306,6 @@ func parseSelectResult(readBuf *buffer) (*SelectResult, error) {
 		} //for end
 
 	} else if char == '$' {
-		fmt.Println("  查询返回 $ ")
 		fad, err := parseFormArgDescri(readBuf)
 		if err != nil {
 			return nil, err
@@ -506,7 +475,6 @@ func parseFormArgDescri(readBuf *buffer) (*FormArgDescri, error) {
 	}
 	Arg_Num := binary.LittleEndian.Uint32(Arg_Nums)
 	formArgDescri := &FormArgDescri{ArgNum: Arg_Num}
-	fmt.Println("-- parseFormArgDescri Arg_Num:", Arg_Num)
 	for i := 0; i < int(Arg_Num); i++ {
 		arg := ArgDescri{}
 		//Arg_Name_Len
@@ -540,6 +508,5 @@ func parseFormArgDescri(readBuf *buffer) (*FormArgDescri, error) {
 		arg.ArgPreciScale = binary.LittleEndian.Uint32(ArgPreciScale)
 		formArgDescri.Args = append(formArgDescri.Args, arg)
 	}
-	fmt.Printf("formArgDescri %#v \n", formArgDescri)
 	return formArgDescri, nil
 }

+ 0 - 4
xugu/xugu_result.go

@@ -1,7 +1,5 @@
 package xugu
 
-import "fmt"
-
 type xuguResult struct {
 
 	// Returns the number of rows affected
@@ -19,7 +17,6 @@ type xuguResult struct {
 // databases support this feature, and the syntax of such
 // statements varies.
 func (self *xuguResult) LastInsertId() (int64, error) {
-	fmt.Println(">>>>>(self *xugusqlResult) LastInsertId()")
 	return self.insertId, nil
 }
 
@@ -27,6 +24,5 @@ func (self *xuguResult) LastInsertId() (int64, error) {
 // update, insert, or delete. Not every database or database
 // driver may support this.
 func (self *xuguResult) RowsAffected() (int64, error) {
-	fmt.Println(">>>>>(self *xugusqlResult) RowsAffected()")
 	return self.affectedRows, nil
 }

+ 30 - 14
xugu/xugu_rows.go

@@ -19,8 +19,7 @@ type xuguRows struct {
 }
 
 func (row *xuguRows) Next(dest []driver.Value) error {
-	gt("Next()")
-	defer gt("Next() end")
+
 
 	if row.results.rowIdx >= len(row.results.Values[0]) {
 		//return errors.New("The result set has been released")
@@ -67,25 +66,44 @@ func (row *xuguRows) Next(dest []driver.Value) error {
 
 		case fieldType_R4:
 			dest[j] = math.Float32frombits(binary.BigEndian.Uint32(row.results.Values[j][row.results.rowIdx].Col_Data))
-			fmt.Println("float32 ", dest[j])
 		case fieldType_R8:
 
 			dest[j] = math.Float64frombits(binary.BigEndian.Uint64(row.results.Values[j][row.results.rowIdx].Col_Data))
-			fmt.Println("	dest[j]  r8", dest[j])
 		case fieldType_NUM:
 			dest[j] = row.results.Values[j][row.results.rowIdx].Col_Data
 		case fieldType_I1:
-			dest[j] = int8(row.results.Values[j][row.results.rowIdx].Col_Data[0])
+			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:
-			dest[j] = int16(binary.BigEndian.Uint16(row.results.Values[j][row.results.rowIdx].Col_Data))
+			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:
-			dest[j] = binary.BigEndian.Uint32(row.results.Values[j][row.results.rowIdx].Col_Data)
+			if len(row.results.Values[j][row.results.rowIdx].Col_Data) == 0 {
+				dest[j] = nil
+			} else {
+				dest[j] = binary.BigEndian.Uint32(row.results.Values[j][row.results.rowIdx].Col_Data)
+			}
 		case fieldType_I8:
-			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
-
+			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:
-			dest[j] = string(row.results.Values[j][row.results.rowIdx].Col_Data)
+			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:
 
 			//填入一行的数据
@@ -104,8 +122,7 @@ func (row *xuguRows) Next(dest []driver.Value) error {
 // Columns返回列的名字集,它的个数是从slice的长度中推断出来的。
 // 如果不知道特定的列名,应该为该条目返回一个空的字符串
 func (row *xuguRows) Columns() []string {
-	gt("Columns()")
-	defer gt("Columns() end")
+	
 
 	var columns []string
 
@@ -123,6 +140,5 @@ func (row *xuguRows) ColumnTypeScanType(index int) reflect.Type {
 }
 
 func (self *xuguRows) Close() error {
-	fmt.Println(">>>>>((self *xuguRows) Close() ")
 	return nil
 }

+ 1 - 16
xugu/xugu_sock.go

@@ -5,11 +5,9 @@ import (
 	"context"
 	"encoding/binary"
 	"errors"
-	"fmt"
 )
 
 func xgSockOpenConn(ctx context.Context, pConn *xuguConn) error {
-	fmt.Println("   ---xgSockOpenConn(ctx context.Context, pConn *xuguConn)")
 	//发送
 	//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' "
@@ -18,7 +16,6 @@ func xgSockOpenConn(ctx context.Context, pConn *xuguConn) error {
 	if err != nil {
 		return errors.New("向数据库发起连接失败")
 	}
-	fmt.Println("数据已发送:", dsnMessage)
 
 	buffer := make([]byte, 1)
 	n, err := pConn.conn.Read(buffer)
@@ -46,20 +43,16 @@ func sockSendPutStatement(pConn *xuguConn, sql []byte, values *[]xuguValue, para
 	var networkBytes [4]byte
 	binary.BigEndian.PutUint32(networkBytes[:], sqlLength)
 	pConn.sendBuff.Write(networkBytes[:])
-	fmt.Println("sqlLength", sqlLength)
 	//  Comand_str
 	pConn.sendBuff.Write(sql)
-	fmt.Println("Comand_str", sql, string(sql))
 	//'0' end
 	binary.BigEndian.PutUint32(networkBytes[:], 0)
 	pConn.sendBuff.Write([]byte{0})
-	fmt.Println("0", 0)
 	// Param_num
 
 	var Param_num [4]byte
 	binary.BigEndian.PutUint32(Param_num[:], uint32(paramCount))
 	pConn.sendBuff.Write(Param_num[:])
-	fmt.Println("Param_num", paramCount)
 	if values != nil {
 		//当缓冲区大于8190字节时,直接发送
 		// if pConn.sendBuff.Len() > 8190 {
@@ -72,13 +65,11 @@ func sockSendPutStatement(pConn *xuguConn, sql []byte, values *[]xuguValue, para
 
 		//发送后续参数
 		//	Param_num   { Param_name_len Param_name Param_INOUT Param_DType Param_Data_Len Param_Data }
-		for i, value := range *values {
-			fmt.Println("循环 ", i)
+		for _, value := range *values {
 			//Param_name_len
 			if value.paramName == nil {
 				var Param_name_len [2]byte
 				pConn.sendBuff.Write(Param_name_len[:])
-				fmt.Println("Param_name_len", Param_name_len)
 				//Param_name
 				// var Param_name []byte
 				// pConn.sendBuff.Write(Param_name)
@@ -102,16 +93,13 @@ func sockSendPutStatement(pConn *xuguConn, sql []byte, values *[]xuguValue, para
 			var Param_DType [2]byte
 			binary.BigEndian.PutUint16(Param_DType[:], uint16(value.types))
 			pConn.sendBuff.Write(Param_DType[:])
-			fmt.Println("Param_DType: ", 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[:])
-			fmt.Println("Param_Data_Len: ", Param_Data_Len)
 			//Param_Data 根据DType 修改长度
 			//Param_Data := make([]byte, value.valueLength)
 			pConn.sendBuff.Write([]byte(value.value))
-			fmt.Println("Param_Data: ", []byte(value.value))
 		}
 
 	}
@@ -120,13 +108,11 @@ func sockSendPutStatement(pConn *xuguConn, sql []byte, values *[]xuguValue, para
 }
 
 func sockSendExecute(pConn *xuguConn) error {
-	fmt.Println("\n ---sockSendExecute")
 	//	fmt.Println("SockSendExecute msg: ", pConn.sendBuff.String())
 	_, err := pConn.conn.Write(pConn.sendBuff.Bytes())
 	if err != nil {
 		return err
 	}
-	fmt.Println("\n ---sockSendExecute end")
 	return nil
 }
 
@@ -135,7 +121,6 @@ func xuguSockRecvMsg(pConn *xuguConn) (*allResult, error) {
 	pConn.readBuff.length += n
 	rs, err := parseMsg(&pConn.readBuff, pConn)
 	if err != nil {
-		fmt.Println("xuguPrepare parseMsg(&pConn.readBuff, pConn)")
 		return nil, err
 	}
 	pConn.readBuff.reset()

+ 2 - 12
xugu/xugu_stmt.go

@@ -3,7 +3,6 @@ package xugu
 import (
 	"database/sql/driver"
 	"errors"
-	"fmt"
 )
 
 type xuguStmt struct {
@@ -32,9 +31,7 @@ type xuguStmt struct {
 }
 
 func (stmt *xuguStmt) Close() error {
-	fmt.Println("\n>>>>>> (stmt *xuguStmt) Close method called")
 	//关闭 prepare
-	fmt.Println("stmt.stmt_conn.prepareName", stmt.stmt_conn.prepareName)
 	err := xuguUnPrepare(stmt.stmt_conn, stmt.stmt_conn.prepareName)
 	//释放资源
 
@@ -42,16 +39,13 @@ func (stmt *xuguStmt) Close() error {
 }
 
 func (stmt *xuguStmt) NumInput() int {
-	fmt.Println("\n>>>>>(stmt *xuguStmt) NumInput()")
 
-	fmt.Println("stmt.mysql: ", stmt.mysql)
 	return assertParamCount(stmt.mysql)
 	//return 0
 }
 
 func (stmt *xuguStmt) Exec(args []driver.Value) (driver.Result, error) {
-	gt("stmt Exec")
-	defer gt("stmt Exec end")
+	
 
 	stmt.stmt_conn.mu.Lock()
 	defer stmt.stmt_conn.mu.Unlock()
@@ -61,7 +55,6 @@ func (stmt *xuguStmt) Exec(args []driver.Value) (driver.Result, error) {
 		values := []xuguValue{}
 		for _, param := range args {
 			assertParamType(param, &values)
-			//fmt.Printf("Field Name: %s, Field Type: %s, Field Value: %v\n", v1, v1, v1)
 		}
 		sockSendPutStatement(stmt.stmt_conn, stmt.prename, &values, stmt.paramCount)
 		sockSendExecute(stmt.stmt_conn)
@@ -101,9 +94,7 @@ func (stmt *xuguStmt) Exec(args []driver.Value) (driver.Result, error) {
 
 func (stmt *xuguStmt) Query(args []driver.Value) (driver.Rows, error) {
 
-	gt("stmt Query")
-	defer gt("stmt Query end")
-
+	
 	stmt.stmt_conn.mu.Lock()
 	defer stmt.stmt_conn.mu.Unlock()
 
@@ -113,7 +104,6 @@ func (stmt *xuguStmt) Query(args []driver.Value) (driver.Rows, error) {
 		values := []xuguValue{}
 		for _, param := range args {
 			assertParamType(param, &values)
-			//fmt.Printf("Field Name: %s, Field Type: %s, Field Value: %v\n", v1, v1, v1)
 		}
 		sockSendPutStatement(stmt.stmt_conn, stmt.prename, &values, stmt.paramCount)
 		sockSendExecute(stmt.stmt_conn)