123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- package xugusql
- import (
- "C"
- "context"
- "database/sql/driver"
- "errors"
- "unsafe"
- )
- type xugusqlConn struct {
- conn unsafe.Pointer
- /* xugusqlResult */
- affectedRows int
- insertId int
- }
- func (self *xugusqlConn) get_error() error {
- message := cgo_c_calloc(ERROR_BUFF_SIZE)
- defer func() {
- cgo_c_free(unsafe.Pointer(message))
- }()
- var length C.int
- cgo_xgc_error(&self.conn, message, &length)
- return errors.New(C.GoString(message))
- }
- func (self *xugusqlConn) Begin() (driver.Tx, error) {
- err := self.exec("set auto_commit off;")
- if err != nil {
- return nil, self.get_error()
- }
- return &xugusqlTx{tconn: self}, nil
- }
- func (self *xugusqlConn) Close() error {
- re := cgo_xgc_disconnect(&self.conn)
- if re < 0 {
- return self.get_error()
- }
- return nil
- }
- func (self *xugusqlConn) Prepare(query string) (driver.Stmt, error) {
- sql := C.CString(query)
- defer func() {
- cgo_c_free(unsafe.Pointer(sql))
- }()
- switch cgo_xgc_sql_type(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.")
- }
- stmt := &xugusqlStmt{
- stmt_conn: self.conn,
- prepared: false,
- prename: nil,
- curopend: false,
- curname: nil,
- param_count: 0,
- result: nil,
- mysql: query,
- }
- if stmt.prename == nil {
- stmt.prename = cgo_c_calloc(PREPARE_NAME_BUFF_SIZE)
- }
- re := cgo_xgc_prepare(&self.conn, sql, stmt.prename)
- if re < 0 {
- return nil, self.get_error()
- }
- stmt.prepared = true
- return stmt, nil
- }
- func (self *xugusqlConn) Query(query string,
- args []driver.Value) (driver.Rows, error) {
- sql := C.CString(query)
- defer func() {
- cgo_c_free(unsafe.Pointer(sql))
- }()
- parser := &parse{
- bind_type: 0,
- param_count: 0,
- position: 0,
- }
- if len(args) != 0 {
- for pos, param := range args {
- err := parser.assertParamType(param, pos)
- if err != nil {
- return nil, err
- }
- }
- if len(parser.Val) != parser.assertParamCount(query) {
- return nil, errors.New("The number of parameters does not match")
- }
- switch parser.assertBindType(query) {
- case BIND_PARAM_BY_POS:
- for pos, param := range parser.Val {
- if !param.islob {
- re := cgo_xgc_bindparambypos(&self.conn, pos+1, SQL_PARAM_INPUT,
- param.types, unsafe.Pointer(param.value), param.buff, ¶m.length)
- if re < 0 {
- return nil, self.get_error()
- }
- } else {
- re := cgo_xgc_bindparambypos(&self.conn, pos+1, SQL_PARAM_INPUT,
- param.types, unsafe.Pointer(¶m.plob), param.buff, ¶m.length)
- if re < 0 {
- return nil, self.get_error()
- }
- }
- }
- case BIND_PARAM_BY_NAME:
- parser.assertParamName(query)
- for pos, param := range parser.Val {
- if !param.islob {
- re := cgo_xgc_bindparambyname(&self.conn, parser.param_names[pos], SQL_PARAM_INPUT,
- param.types, unsafe.Pointer(param.value), param.buff, ¶m.rcode, ¶m.length)
- if re < 0 {
- return nil, self.get_error()
- }
- } else {
- re := cgo_xgc_bindparambyname(&self.conn, parser.param_names[pos], SQL_PARAM_INPUT,
- param.types, unsafe.Pointer(¶m.plob), param.buff, ¶m.rcode, ¶m.length)
- if re < 0 {
- return nil, self.get_error()
- }
- }
- }
- }
- }
- defer func() {
- for pos, param := range parser.Val {
- if parser.bind_type == BIND_PARAM_BY_NAME {
- cgo_c_free(unsafe.Pointer(parser.param_names[pos]))
- }
- if !param.islob {
- cgo_c_free(unsafe.Pointer(param.value))
- } else {
- cgo_xgc_lob_distroy(¶m.plob)
- }
- }
- }()
- rows := &xugusqlRows{
- rows_conn: self.conn,
- result: nil,
- lastRowRelt: int(0),
- lastRelt: int(0),
- prepared: false,
- }
- var fieldCount, effectCount C.int
- var rowCount C.longlong
- re := cgo_xgc_exec_with_reader(&self.conn, sql, &rows.result,
- &fieldCount, &rowCount, &effectCount)
- if re < 0 {
- return nil, self.get_error()
- }
- return rows, nil
- }
- func (self *xugusqlConn) Exec(query string,
- args []driver.Value) (driver.Result, error) {
- sql := C.CString(query)
- switch cgo_xgc_sql_type(sql) {
- case SQL_SELECT:
- return nil, errors.New("Exec does not support queries")
- case SQL_UNKNOWN:
- return nil, errors.New("Unknown SQL statement type")
- }
- parser := &parse{
- bind_type: 0,
- param_count: 0,
- position: 0,
- }
- if len(args) != 0 {
- for pos, param := range args {
- err := parser.assertParamType(param, pos)
- if err != nil {
- return nil, err
- }
- }
- if len(parser.Val) != parser.assertParamCount(query) {
- return nil, errors.New("The number of parameters does not match")
- }
- switch parser.assertBindType(query) {
- case BIND_PARAM_BY_POS:
- for pos, param := range parser.Val {
- if !param.islob {
- re := cgo_xgc_bindparambypos(&self.conn, pos+1, SQL_PARAM_INPUT,
- param.types, unsafe.Pointer(param.value), param.buff, ¶m.length)
- if re < 0 {
- return nil, self.get_error()
- }
- } else {
- re := cgo_xgc_bindparambypos(&self.conn, pos+1, SQL_PARAM_INPUT,
- param.types, unsafe.Pointer(¶m.plob), param.buff, ¶m.length)
- if re < 0 {
- return nil, self.get_error()
- }
- }
- }
- case BIND_PARAM_BY_NAME:
- parser.assertParamName(query)
- for pos, param := range parser.Val {
- if !param.islob {
- re := cgo_xgc_bindparambyname(&self.conn, parser.param_names[pos], SQL_PARAM_INPUT,
- param.types, unsafe.Pointer(param.value), param.buff, ¶m.rcode, ¶m.length)
- if re < 0 {
- return nil, self.get_error()
- }
- } else {
- re := cgo_xgc_bindparambyname(&self.conn, parser.param_names[pos], SQL_PARAM_INPUT,
- param.types, unsafe.Pointer(¶m.plob), param.buff, ¶m.rcode, ¶m.length)
- if re < 0 {
- return nil, self.get_error()
- }
- }
- }
- }
- }
- defer func() {
- cgo_c_free(unsafe.Pointer(sql))
- for pos, param := range parser.Val {
- if parser.bind_type == BIND_PARAM_BY_NAME {
- cgo_c_free(unsafe.Pointer(parser.param_names[pos]))
- }
- if !param.islob {
- cgo_c_free(unsafe.Pointer(param.value))
- } else {
- cgo_xgc_lob_distroy(¶m.plob)
- }
- }
- }()
- self.affectedRows = 0
- self.insertId = 0
- err := self.exec(query)
- if err == nil {
- return &xugusqlResult{
- affectedRows: int64(self.affectedRows),
- insertId: int64(self.insertId),
- }, nil
- }
- return nil, err
- }
- func (self *xugusqlConn) exec(query string) error {
- sql := C.CString(query)
- defer func() {
- cgo_c_free(unsafe.Pointer(sql))
- }()
- self.affectedRows = cgo_xgc_execnoquery(&self.conn, sql)
- if self.affectedRows < 0 {
- return self.get_error()
- }
- return nil
- }
- func (self *xugusqlConn) ExecContext(ctx context.Context,
- query string, args []driver.NamedValue) (driver.Result, error) {
- Value, err := namedValueToValue(args)
- if err != nil {
- return nil, err
- }
- return self.Exec(query, Value)
- }
- func (self *xugusqlConn) Ping(ctx context.Context) error {
- sql := C.CString("select count(*) from dual;")
- defer func() {
- cgo_c_free(unsafe.Pointer(sql))
- }()
- var fieldCount, effectCount C.int
- var rowCount C.longlong
- var result unsafe.Pointer
- re := cgo_xgc_exec_with_reader(&self.conn, sql, &result,
- &fieldCount, &rowCount, &effectCount)
- if re < 0 {
- return self.get_error()
- }
- return nil
- }
|