|
@@ -0,0 +1,107 @@
|
|
|
+package xugu
|
|
|
+
|
|
|
+import (
|
|
|
+ "context"
|
|
|
+ "database/sql/driver"
|
|
|
+ "errors"
|
|
|
+ "fmt"
|
|
|
+ "net"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+type connector struct {
|
|
|
+ dsn string
|
|
|
+}
|
|
|
+
|
|
|
+func NewConnector(dsn string) *connector {
|
|
|
+ return &connector{dsn: dsn}
|
|
|
+}
|
|
|
+
|
|
|
+var IPS_COUNTER int = 0
|
|
|
+
|
|
|
+// Driver implements driver.Connector interface.
|
|
|
+// Driver returns &XuguDriver{}
|
|
|
+func (self *connector) Driver() driver.Driver {
|
|
|
+ return &XuguDriver{}
|
|
|
+}
|
|
|
+
|
|
|
+// Connect implements driver.Connector interface.
|
|
|
+// Connect returns a connection to the database.
|
|
|
+func (self *connector) Connect(ctx context.Context) (driver.Conn, error) {
|
|
|
+
|
|
|
+ obj := &xugusqlConn{conn: nil}
|
|
|
+ //connKeyValue := C.CString(self.dsn)
|
|
|
+
|
|
|
+ defer func() {
|
|
|
+ // cgo_c_free(unsafe.Pointer(connKeyValue))
|
|
|
+ }()
|
|
|
+ fmt.Println("Connect")
|
|
|
+ re, _ := xgc_connect(ctx, self.dsn, &obj.conn)
|
|
|
+ if re < 0 {
|
|
|
+ return nil, obj.get_error()
|
|
|
+ // pos := strings.Index(strings.ToUpper(self.dsn), "IPS=")
|
|
|
+ // if pos != -1 {
|
|
|
+ // IPS_COUNTER++
|
|
|
+ // re := xgc_connect_ips(ctx, &self.dsn, &obj.conn)
|
|
|
+ // if re < 0 {
|
|
|
+ // return nil, obj.get_error()
|
|
|
+ // }
|
|
|
+ // } else {
|
|
|
+ // re, _ := xgc_connect(ctx, self.dsn, &obj.conn)
|
|
|
+ // if re < 0 {
|
|
|
+ // return nil, obj.get_error()
|
|
|
+ // }
|
|
|
+ }
|
|
|
+
|
|
|
+ return obj, nil
|
|
|
+}
|
|
|
+
|
|
|
+func xgc_connect(ctx context.Context, pdsn string, __pConn *net.Conn) (int, error) {
|
|
|
+ fmt.Println("xgc_connect pdsn:", pdsn)
|
|
|
+ return XGSOpenConn(ctx, pdsn, __pConn)
|
|
|
+}
|
|
|
+func xgc_connect_ips(ctx context.Context, pdsn *string, __pConn *net.Conn) int {
|
|
|
+ return 0
|
|
|
+}
|
|
|
+
|
|
|
+func XGSOpenConn(ctx context.Context, pdsn string, __pConn *net.Conn) (int, error) {
|
|
|
+ fmt.Println("XGSOpenConn")
|
|
|
+ nd := net.Dialer{Timeout: 5 * time.Second}
|
|
|
+ netConn, err := nd.DialContext(ctx, "tcp", pdsn)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("tcp", err)
|
|
|
+ return -8, err
|
|
|
+ }
|
|
|
+
|
|
|
+ // 启用 TCP 保活
|
|
|
+ if tc, ok := netConn.(*net.TCPConn); ok {
|
|
|
+ if err := tc.SetKeepAlive(true); err != nil {
|
|
|
+ //c.cfg.Logger.Print(err) // 如果设置保活失败,记录错误但不终止
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //发送
|
|
|
+
|
|
|
+ message := "login database = 'SYSTEM' user = 'SYSDBA' password = 'SYSDBA' version='201' "
|
|
|
+
|
|
|
+ _, err = netConn.Write([]byte(message))
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("发送数据失败:", err)
|
|
|
+
|
|
|
+ }
|
|
|
+ fmt.Println("数据已发送:", message)
|
|
|
+
|
|
|
+ buffer := make([]byte, 1024)
|
|
|
+ n, err := netConn.Read(buffer)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("Error reading from server:", err)
|
|
|
+
|
|
|
+ }
|
|
|
+ fmt.Println("Message from server:", string(buffer[:n]))
|
|
|
+ return 1, nil
|
|
|
+}
|
|
|
+
|
|
|
+func (self *xugusqlConn) get_error() error {
|
|
|
+
|
|
|
+ return errors.New("errors")
|
|
|
+}
|