diff --git a/.gitignore b/.gitignore
index 66fd13c..3fa5ce2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,9 @@
# Dependency directories (remove the comment below to include it)
# vendor/
+
+# IDE
+.idea
+
+# sys
+go.sum
diff --git a/clauses/merge.go b/clauses/merge.go
new file mode 100644
index 0000000..d661d64
--- /dev/null
+++ b/clauses/merge.go
@@ -0,0 +1,49 @@
+package clauses
+
+import (
+ "gorm.io/gorm/clause"
+)
+
+type Merge struct {
+ Table clause.Table
+ Using []clause.Interface
+ On []clause.Expression
+}
+
+func (merge Merge) Name() string {
+ return "MERGE"
+}
+
+func MergeDefaultExcludeName() string {
+ return "exclude"
+}
+
+// Build build from clause
+func (merge Merge) Build(builder clause.Builder) {
+ clause.Insert{}.Build(builder)
+ builder.WriteString(" USING (")
+ for idx, iface := range merge.Using {
+ if idx > 0 {
+ builder.WriteByte(' ')
+ }
+ builder.WriteString(iface.Name())
+ builder.WriteByte(' ')
+ iface.Build(builder)
+ }
+ builder.WriteString(") ")
+ builder.WriteString(MergeDefaultExcludeName())
+ builder.WriteString(" ON (")
+ for idx, on := range merge.On {
+ if idx > 0 {
+ builder.WriteString(", ")
+ }
+ on.Build(builder)
+ }
+ builder.WriteString(")")
+}
+
+// MergeClause merge values clauses
+func (merge Merge) MergeClause(clause *clause.Clause) {
+ clause.Name = merge.Name()
+ clause.Expression = merge
+}
diff --git a/clauses/returning_into.go b/clauses/returning_into.go
new file mode 100644
index 0000000..0f2857b
--- /dev/null
+++ b/clauses/returning_into.go
@@ -0,0 +1,10 @@
+package clauses
+
+import (
+ "gorm.io/gorm/clause"
+)
+
+type ReturningInto struct {
+ Variables []clause.Column
+ Into []*clause.Values
+}
diff --git a/clauses/when_matched.go b/clauses/when_matched.go
new file mode 100644
index 0000000..b44cfb7
--- /dev/null
+++ b/clauses/when_matched.go
@@ -0,0 +1,39 @@
+package clauses
+
+import (
+ "gorm.io/gorm/clause"
+)
+
+type WhenMatched struct {
+ clause.Set
+ Where, Delete clause.Where
+}
+
+func (w WhenMatched) Name() string {
+ return "WHEN MATCHED"
+}
+
+func (w WhenMatched) Build(builder clause.Builder) {
+ if len(w.Set) > 0 {
+ builder.WriteString(" THEN")
+ builder.WriteString(" UPDATE ")
+ builder.WriteString(w.Name())
+ builder.WriteByte(' ')
+ w.Build(builder)
+
+ buildWhere := func(where clause.Where) {
+ builder.WriteString(where.Name())
+ builder.WriteByte(' ')
+ where.Build(builder)
+ }
+
+ if len(w.Where.Exprs) > 0 {
+ buildWhere(w.Where)
+ }
+
+ if len(w.Delete.Exprs) > 0 {
+ builder.WriteString(" DELETE ")
+ buildWhere(w.Delete)
+ }
+ }
+}
diff --git a/clauses/when_not_matched.go b/clauses/when_not_matched.go
new file mode 100644
index 0000000..8877554
--- /dev/null
+++ b/clauses/when_not_matched.go
@@ -0,0 +1,32 @@
+package clauses
+
+import (
+ "gorm.io/gorm/clause"
+)
+
+type WhenNotMatched struct {
+ clause.Values
+ Where clause.Where
+}
+
+func (w WhenNotMatched) Name() string {
+ return "WHEN NOT MATCHED"
+}
+
+func (w WhenNotMatched) Build(builder clause.Builder) {
+ if len(w.Columns) > 0 {
+ if len(w.Values.Values) != 1 {
+ panic("cannot insert more than one rows due to DM SQL language restriction")
+ }
+
+ builder.WriteString(" THEN")
+ builder.WriteString(" INSERT ")
+ w.Build(builder)
+
+ if len(w.Where.Exprs) > 0 {
+ builder.WriteString(w.Where.Name())
+ builder.WriteByte(' ')
+ w.Where.Build(builder)
+ }
+ }
+}
diff --git a/create.go b/create.go
new file mode 100644
index 0000000..8519d5b
--- /dev/null
+++ b/create.go
@@ -0,0 +1,154 @@
+package dm
+
+import (
+ "bytes"
+ "database/sql"
+ "reflect"
+
+ "github.com/thoas/go-funk"
+ "gorm.io/gorm"
+ "gorm.io/gorm/callbacks"
+ "gorm.io/gorm/clause"
+ gormSchema "gorm.io/gorm/schema"
+
+ "github.com/nfjBill/gorm-driver-dm/clauses"
+)
+
+func Create(db *gorm.DB) {
+ stmt := db.Statement
+ schema := stmt.Schema
+ boundVars := make(map[string]int)
+
+ if stmt == nil || schema == nil {
+ return
+ }
+
+ hasDefaultValues := len(schema.FieldsWithDefaultDBValue) > 0
+
+ if !stmt.Unscoped {
+ for _, c := range schema.CreateClauses {
+ stmt.AddClause(c)
+ }
+ }
+
+ if stmt.SQL.String() == "" {
+ values := callbacks.ConvertToCreateValues(stmt)
+ onConflict, hasConflict := stmt.Clauses["ON CONFLICT"].Expression.(clause.OnConflict)
+ // are all columns in value the primary fields in schema only?
+ if hasConflict && funk.Contains(
+ funk.Map(values.Columns, func(c clause.Column) string { return c.Name }),
+ funk.Map(schema.PrimaryFields, func(field *gormSchema.Field) string { return field.DBName }),
+ ) {
+ stmt.AddClauseIfNotExists(clauses.Merge{
+ Using: []clause.Interface{
+ clause.Select{
+ Columns: funk.Map(values.Columns, func(column clause.Column) clause.Column {
+ // HACK: I can not come up with a better alternative for now
+ // I want to add a value to the list of variable and then capture the bind variable position as well
+ buf := bytes.NewBufferString("")
+ stmt.Vars = append(stmt.Vars, values.Values[0][funk.IndexOf(values.Columns, column)])
+ stmt.BindVarTo(buf, stmt, nil)
+
+ column.Alias = column.Name
+ // then the captured bind var will be the name
+ column.Name = buf.String()
+ return column
+ }).([]clause.Column),
+ },
+ clause.From{
+ Tables: []clause.Table{{Name: db.Dialector.(Dialector).DummyTableName()}},
+ },
+ },
+ On: funk.Map(schema.PrimaryFields, func(field *gormSchema.Field) clause.Expression {
+ return clause.Eq{
+ Column: clause.Column{Table: stmt.Table, Name: field.DBName},
+ Value: clause.Column{Table: clauses.MergeDefaultExcludeName(), Name: field.DBName},
+ }
+ }).([]clause.Expression),
+ })
+ stmt.AddClauseIfNotExists(clauses.WhenMatched{Set: onConflict.DoUpdates})
+ stmt.AddClauseIfNotExists(clauses.WhenNotMatched{Values: values})
+
+ stmt.Build("MERGE", "WHEN MATCHED", "WHEN NOT MATCHED")
+ } else {
+ stmt.AddClauseIfNotExists(clause.Insert{Table: clause.Table{Name: stmt.Table}})
+ stmt.AddClause(clause.Values{Columns: values.Columns, Values: [][]interface{}{values.Values[0]}})
+ if hasDefaultValues {
+ stmt.AddClauseIfNotExists(clause.Returning{
+ Columns: funk.Map(schema.FieldsWithDefaultDBValue, func(field *gormSchema.Field) clause.Column {
+ return clause.Column{Name: field.DBName}
+ }).([]clause.Column),
+ })
+ }
+ stmt.Build("INSERT", "VALUES")
+ // 返回自增主键
+ //stmt.Build("INSERT", "VALUES", "RETURNING")
+ //if hasDefaultValues {
+ // stmt.WriteString(" INTO ")
+ // for idx, field := range schema.FieldsWithDefaultDBValue {
+ // if idx > 0 {
+ // stmt.WriteByte(',')
+ // }
+ // boundVars[field.Name] = len(stmt.Vars)
+ // stmt.AddVar(stmt, sql.Out{Dest: reflect.New(field.FieldType).Interface()})
+ // }
+ //}
+ }
+
+ if !db.DryRun {
+ for idx, vals := range values.Values {
+ // HACK HACK: replace values one by one, assuming its value layout will be the same all the time, i.e. aligned
+ for idx, val := range vals {
+ switch v := val.(type) {
+ case bool:
+ if v {
+ val = 1
+ } else {
+ val = 0
+ }
+ }
+
+ stmt.Vars[idx] = val
+ }
+ // and then we insert each row one by one then put the returning values back (i.e. last return id => smart insert)
+ // we keep track of the index so that the sub-reflected value is also correct
+
+ // BIG BUG: what if any of the transactions failed? some result might already be inserted that dm is so
+ // sneaky that some transaction inserts will exceed the buffer and so will be pushed at unknown point,
+ // resulting in dangling row entries, so we might need to delete them if an error happens
+
+ switch result, err := stmt.ConnPool.ExecContext(stmt.Context, stmt.SQL.String(), stmt.Vars...); err {
+ case nil: // success
+ db.RowsAffected, _ = result.RowsAffected()
+
+ insertTo := stmt.ReflectValue
+ switch insertTo.Kind() {
+ case reflect.Slice, reflect.Array:
+ insertTo = insertTo.Index(idx)
+ }
+
+ if hasDefaultValues {
+ // bind returning value back to reflected value in the respective fields
+ funk.ForEach(
+ funk.Filter(schema.FieldsWithDefaultDBValue, func(field *gormSchema.Field) bool {
+ return funk.Contains(boundVars, field.Name)
+ }),
+ func(field *gormSchema.Field) {
+ switch insertTo.Kind() {
+ case reflect.Struct:
+ if err = field.Set(insertTo, stmt.Vars[boundVars[field.Name]].(sql.Out).Dest); err != nil {
+ db.AddError(err)
+ }
+ case reflect.Map:
+ // todo 设置id的值
+ }
+ },
+ )
+ }
+ default: // failure
+ db.AddError(err)
+ }
+ }
+ }
+ }
+}
diff --git a/dm.go b/dm.go
new file mode 100644
index 0000000..5f371e9
--- /dev/null
+++ b/dm.go
@@ -0,0 +1,236 @@
+package dm
+
+import (
+ "database/sql"
+ "fmt"
+ "gorm.io/gorm/utils"
+ "regexp"
+ "strconv"
+ "strings"
+
+ _ "github.com/nfjBill/gorm-driver-dm/dmr"
+ "github.com/thoas/go-funk"
+ "gorm.io/gorm"
+ "gorm.io/gorm/callbacks"
+ "gorm.io/gorm/clause"
+ "gorm.io/gorm/logger"
+ "gorm.io/gorm/migrator"
+ "gorm.io/gorm/schema"
+)
+
+type Config struct {
+ DriverName string
+ DSN string
+ Conn *sql.DB
+ DefaultStringSize uint
+}
+
+type Dialector struct {
+ *Config
+}
+
+func Open(dsn string) gorm.Dialector {
+ return &Dialector{Config: &Config{DSN: dsn}}
+}
+
+func New(config Config) gorm.Dialector {
+ return &Dialector{Config: &config}
+}
+
+func (d Dialector) DummyTableName() string {
+ return "DUAL"
+}
+
+func (d Dialector) Name() string {
+ return "dm"
+}
+
+func (d Dialector) Initialize(db *gorm.DB) (err error) {
+ db.NamingStrategy = Namer{}
+ d.DefaultStringSize = 1024
+
+ // register callbacks
+ callbacks.RegisterDefaultCallbacks(db, &callbacks.Config{})
+
+ d.DriverName = "dm"
+
+ if d.Conn != nil {
+ db.ConnPool = d.Conn
+ } else {
+ db.ConnPool, err = sql.Open(d.DriverName, d.DSN)
+ }
+
+ if err = db.Callback().Create().Replace("gorm:create", Create); err != nil {
+ return
+ }
+
+ for k, v := range d.ClauseBuilders() {
+ db.ClauseBuilders[k] = v
+ }
+ return
+}
+
+func (d Dialector) ClauseBuilders() map[string]clause.ClauseBuilder {
+ return map[string]clause.ClauseBuilder{
+ "LIMIT": d.RewriteLimit,
+ }
+}
+
+func (d Dialector) RewriteLimit(c clause.Clause, builder clause.Builder) {
+ if limit, ok := c.Expression.(clause.Limit); ok {
+ if stmt, ok := builder.(*gorm.Statement); ok {
+ if _, ok := stmt.Clauses["ORDER BY"]; !ok {
+ s := stmt.Schema
+ builder.WriteString("ORDER BY ")
+ if s != nil && s.PrioritizedPrimaryField != nil {
+ builder.WriteQuoted(s.PrioritizedPrimaryField.DBName)
+ builder.WriteByte(' ')
+ } else {
+ builder.WriteString("(SELECT NULL FROM ")
+ builder.WriteString(d.DummyTableName())
+ builder.WriteString(")")
+ }
+ }
+ }
+
+ if offset := limit.Offset; offset > 0 {
+ builder.WriteString(" OFFSET ")
+ builder.WriteString(strconv.Itoa(offset))
+ builder.WriteString(" ROWS")
+ }
+ if limit := limit.Limit; limit > 0 {
+ builder.WriteString(" FETCH NEXT ")
+ builder.WriteString(strconv.Itoa(limit))
+ builder.WriteString(" ROWS ONLY")
+ }
+ }
+}
+
+func (d Dialector) DefaultValueOf(*schema.Field) clause.Expression {
+ return clause.Expr{SQL: "VALUES (DEFAULT)"}
+}
+
+func (d Dialector) Migrator(db *gorm.DB) gorm.Migrator {
+ return Migrator{
+ Migrator: migrator.Migrator{
+ Config: migrator.Config{
+ DB: db,
+ Dialector: d,
+ CreateIndexAfterCreateTable: true,
+ },
+ },
+ }
+}
+
+func (d Dialector) BindVarTo(writer clause.Writer, stmt *gorm.Statement, v interface{}) {
+ writer.WriteString(":")
+ writer.WriteString(strconv.Itoa(len(stmt.Vars)))
+}
+
+func (d Dialector) QuoteTo(writer clause.Writer, str string) {
+ writer.WriteString(str)
+}
+
+var numericPlaceholder = regexp.MustCompile(`:(\d+)`)
+
+func (d Dialector) Explain(sql string, vars ...interface{}) string {
+ return logger.ExplainSQL(sql, numericPlaceholder, `'`, funk.Map(vars, func(v interface{}) interface{} {
+ switch v := v.(type) {
+ case bool:
+ if v {
+ return 1
+ }
+ return 0
+ default:
+ return v
+ }
+ }).([]interface{})...)
+}
+
+func (d Dialector) DataTypeOf(field *schema.Field) string {
+ if _, found := field.TagSettings["RESTRICT"]; found {
+ delete(field.TagSettings, "RESTRICT")
+ }
+
+ var sqlType string
+
+ switch field.DataType {
+ case schema.Bool, schema.Int, schema.Uint, schema.Float:
+ sqlType = "INTEGER"
+
+ switch {
+ case field.DataType == schema.Float:
+ sqlType = "FLOAT"
+ case field.Size <= 8:
+ sqlType = "SMALLINT"
+ }
+
+ if val, ok := field.TagSettings["AUTOINCREMENT"]; ok && utils.CheckTruth(val) {
+ sqlType += " GENERATED BY DEFAULT AS IDENTITY"
+ }
+ case schema.String, "VARCHAR2":
+ size := field.Size
+ defaultSize := d.DefaultStringSize
+
+ if size == 0 {
+ if defaultSize > 0 {
+ size = int(defaultSize)
+ } else {
+ hasIndex := field.TagSettings["INDEX"] != "" || field.TagSettings["UNIQUE"] != ""
+ // TEXT, GEOMETRY or JSON column can't have a default value
+ if field.PrimaryKey || field.HasDefaultValue || hasIndex {
+ size = 191 // utf8mb4
+ }
+ }
+ }
+
+ if size >= 2000 {
+ sqlType = "CLOB"
+ } else {
+ sqlType = fmt.Sprintf("VARCHAR2(%d)", size)
+ }
+
+ case schema.Time:
+ sqlType = "TIMESTAMP WITH TIME ZONE"
+ if field.NotNull || field.PrimaryKey {
+ sqlType += " NOT NULL"
+ }
+ case schema.Bytes:
+ sqlType = "BLOB"
+ default:
+ sqlType = string(field.DataType)
+
+ if strings.EqualFold(sqlType, "text") {
+ sqlType = "CLOB"
+ }
+
+ if sqlType == "" {
+ panic(fmt.Sprintf("invalid sql type %s (%s) for dm", field.FieldType.Name(), field.FieldType.String()))
+ }
+
+ notNull, _ := field.TagSettings["NOT NULL"]
+ unique, _ := field.TagSettings["UNIQUE"]
+ additionalType := fmt.Sprintf("%s %s", notNull, unique)
+ if value, ok := field.TagSettings["DEFAULT"]; ok {
+ additionalType = fmt.Sprintf("%s %s %s%s", "DEFAULT", value, additionalType, func() string {
+ if value, ok := field.TagSettings["COMMENT"]; ok {
+ return " COMMENT " + value
+ }
+ return ""
+ }())
+ }
+ sqlType = fmt.Sprintf("%v %v", sqlType, additionalType)
+ }
+
+ return sqlType
+}
+
+func (d Dialector) SavePoint(tx *gorm.DB, name string) error {
+ tx.Exec("SAVEPOINT " + name)
+ return tx.Error
+}
+
+func (d Dialector) RollbackTo(tx *gorm.DB, name string) error {
+ tx.Exec("ROLLBACK TO SAVEPOINT " + name)
+ return tx.Error
+}
diff --git a/dm_test.go b/dm_test.go
new file mode 100644
index 0000000..eaaaf2a
--- /dev/null
+++ b/dm_test.go
@@ -0,0 +1,111 @@
+package dm
+
+import (
+ "fmt"
+ dmSchema "github.com/nfjBill/gorm-driver-dm/schema"
+ "gorm.io/gorm"
+ "testing"
+ "time"
+)
+
+var db *gorm.DB
+
+func init() {
+ var err error
+ dsn := "dm://sysdba:aaaaaaaaa@192.168.31.192:5236?autoCommit=true"
+ db, err = gorm.Open(Open(dsn), &gorm.Config{
+ DisableForeignKeyConstraintWhenMigrating: true,
+ })
+
+ if err != nil {
+ fmt.Printf("Error: failed to connect dm server: %v\n", err)
+ return
+ }
+
+ TB(db)
+}
+
+type Model struct {
+ ID uint `gorm:"primarykey,autoIncrement"`
+ CreatedAt time.Time
+ UpdatedAt time.Time
+ DeletedAt gorm.DeletedAt `gorm:"index"`
+}
+
+type User struct {
+ Model
+ Key string `gorm:"index:idx_key,unique,comment:备注"`
+ Name string
+ Age int
+ Content dmSchema.Clob `gorm:"size:1024000"`
+ Birthday time.Time
+}
+
+func TestAutoMigrate(t *testing.T) {
+ if Table().HasTable(&User{}) {
+ err := Table().DropTable(&User{})
+
+ if err != nil {
+ fmt.Printf("Error: failed to DropTable: %v\n", err)
+ return
+ }
+ }
+
+ err := Table().AutoMigrate(&User{})
+
+ if err != nil {
+ fmt.Printf("Error: failed to AutoMigrate: %v\n", err)
+ return
+ }
+}
+
+func TestCreate(t *testing.T) {
+ err := Table(&User{Key: "1", Name: "Jinzhu", Age: 18, Content: "asdfdasfasdfasdfj手机卡是点击", Birthday: time.Now()}).Create()
+ _ = Table(&User{Key: "2", Name: "Jinzhu", Age: 19, Content: "bbb", Birthday: time.Now()}).Create()
+ _ = Table(&User{Key: "3", Name: "Jinzhu2", Age: 20, Content: "ccc", Birthday: time.Now()}).Create()
+
+ if err != nil {
+ fmt.Printf("Error: failed to Create: %v\n", err)
+ return
+ }
+}
+
+func TestGet(t *testing.T) {
+ var data User
+ err := Table(&User{Name: "Jinzhu"}).Get(&data)
+
+ if err != nil {
+ fmt.Printf("Error: failed to Get: %v\n", err)
+ return
+ }
+}
+
+func TestWhere(t *testing.T) {
+ var data []User
+ err := Table(&User{Name: "Jinzhu"}).GetWhere(&data)
+
+ if err != nil {
+ fmt.Printf("Error: failed to Where: %v\n", err)
+ return
+ }
+}
+
+func TestAll(t *testing.T) {
+ var data []User
+ err := Table().GetAll(&data)
+
+ if err != nil {
+ fmt.Printf("Error: failed to All: %v\n", err)
+ return
+ }
+}
+
+// err
+func TestClausesAssignmentColumns(t *testing.T) {
+ err := Table(&User{Key: "3", Content: "DDDD"}).ClausesAssignmentColumns("KEY", []string{"DELETED_AT", "CONTENT"})
+
+ if err != nil {
+ fmt.Printf("Error: failed to ClausesAssignmentColumns: %v\n", err)
+ return
+ }
+}
diff --git a/dmr/a.go b/dmr/a.go
new file mode 100644
index 0000000..914c31b
--- /dev/null
+++ b/dmr/a.go
@@ -0,0 +1,803 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "bytes"
+ "crypto/tls"
+ "net"
+ "strconv"
+ "time"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/security"
+)
+
+const (
+ Dm_build_330 = 8192
+ Dm_build_331 = 2 * time.Second
+)
+
+type dm_build_332 struct {
+ dm_build_333 *net.TCPConn
+ dm_build_334 *tls.Conn
+ dm_build_335 *Dm_build_0
+ dm_build_336 *DmConnection
+ dm_build_337 security.Cipher
+ dm_build_338 bool
+ dm_build_339 bool
+ dm_build_340 *security.DhKey
+
+ dm_build_341 bool
+ dm_build_342 string
+ dm_build_343 bool
+}
+
+func dm_build_344(dm_build_345 *DmConnection) (*dm_build_332, error) {
+ dm_build_346, dm_build_347 := dm_build_349(dm_build_345.dmConnector.host+":"+strconv.Itoa(int(dm_build_345.dmConnector.port)), time.Duration(dm_build_345.dmConnector.socketTimeout)*time.Second)
+ if dm_build_347 != nil {
+ return nil, dm_build_347
+ }
+
+ dm_build_348 := dm_build_332{}
+ dm_build_348.dm_build_333 = dm_build_346
+ dm_build_348.dm_build_335 = Dm_build_3(Dm_build_604)
+ dm_build_348.dm_build_336 = dm_build_345
+ dm_build_348.dm_build_338 = false
+ dm_build_348.dm_build_339 = false
+ dm_build_348.dm_build_341 = false
+ dm_build_348.dm_build_342 = ""
+ dm_build_348.dm_build_343 = false
+ dm_build_345.Access = &dm_build_348
+
+ return &dm_build_348, nil
+}
+
+func dm_build_349(dm_build_350 string, dm_build_351 time.Duration) (*net.TCPConn, error) {
+ dm_build_352, dm_build_353 := net.DialTimeout("tcp", dm_build_350, dm_build_351)
+ if dm_build_353 != nil {
+ return nil, ECGO_COMMUNITION_ERROR.addDetail("\tdial address: " + dm_build_350).throw()
+ }
+
+ if tcpConn, ok := dm_build_352.(*net.TCPConn); ok {
+
+ tcpConn.SetKeepAlive(true)
+ tcpConn.SetKeepAlivePeriod(Dm_build_331)
+ tcpConn.SetNoDelay(true)
+
+ return tcpConn, nil
+ }
+
+ return nil, nil
+}
+
+func (dm_build_355 *dm_build_332) dm_build_354(dm_build_356 dm_build_725) bool {
+ var dm_build_357 = dm_build_355.dm_build_336.dmConnector.compress
+ if dm_build_356.dm_build_740() == Dm_build_632 || dm_build_357 == Dm_build_681 {
+ return false
+ }
+
+ if dm_build_357 == Dm_build_679 {
+ return true
+ } else if dm_build_357 == Dm_build_680 {
+ return !dm_build_355.dm_build_336.Local && dm_build_356.dm_build_738() > Dm_build_678
+ }
+
+ return false
+}
+
+func (dm_build_359 *dm_build_332) dm_build_358(dm_build_360 dm_build_725) bool {
+ var dm_build_361 = dm_build_359.dm_build_336.dmConnector.compress
+ if dm_build_360.dm_build_740() == Dm_build_632 || dm_build_361 == Dm_build_681 {
+ return false
+ }
+
+ if dm_build_361 == Dm_build_679 {
+ return true
+ } else if dm_build_361 == Dm_build_680 {
+ return dm_build_359.dm_build_335.Dm_build_263(Dm_build_640) == 1
+ }
+
+ return false
+}
+
+func (dm_build_363 *dm_build_332) dm_build_362(dm_build_364 dm_build_725) (err error) {
+ defer func() {
+ if p := recover(); p != nil {
+ if _, ok := p.(string); ok {
+ err = ECGO_COMMUNITION_ERROR.addDetail("\t" + p.(string)).throw()
+ } else {
+ panic(p)
+ }
+ }
+ }()
+
+ dm_build_366 := dm_build_364.dm_build_738()
+
+ if dm_build_366 > 0 {
+
+ if dm_build_363.dm_build_354(dm_build_364) {
+ var retBytes, err = Compress(dm_build_363.dm_build_335, Dm_build_633, int(dm_build_366), int(dm_build_363.dm_build_336.dmConnector.compressID))
+ if err != nil {
+ return err
+ }
+
+ dm_build_363.dm_build_335.Dm_build_14(Dm_build_633)
+
+ dm_build_363.dm_build_335.Dm_build_51(dm_build_366)
+
+ dm_build_363.dm_build_335.Dm_build_79(retBytes)
+
+ dm_build_364.dm_build_739(int32(len(retBytes)) + ULINT_SIZE)
+
+ dm_build_363.dm_build_335.Dm_build_183(Dm_build_640, 1)
+ }
+
+ if dm_build_363.dm_build_339 {
+ dm_build_366 = dm_build_364.dm_build_738()
+ var retBytes = dm_build_363.dm_build_337.Encrypt(dm_build_363.dm_build_335.Dm_build_290(Dm_build_633, int(dm_build_366)), true)
+
+ dm_build_363.dm_build_335.Dm_build_14(Dm_build_633)
+
+ dm_build_363.dm_build_335.Dm_build_79(retBytes)
+
+ dm_build_364.dm_build_739(int32(len(retBytes)))
+ }
+ }
+
+ if dm_build_363.dm_build_335.Dm_build_12() > Dm_build_605 {
+ return ECGO_MSG_TOO_LONG.throw()
+ }
+
+ dm_build_364.dm_build_734()
+ if dm_build_363.dm_build_594(dm_build_364) {
+ if dm_build_363.dm_build_334 != nil {
+ dm_build_363.dm_build_335.Dm_build_17(0)
+ dm_build_363.dm_build_335.Dm_build_36(dm_build_363.dm_build_334)
+ }
+ } else {
+ dm_build_363.dm_build_335.Dm_build_17(0)
+ dm_build_363.dm_build_335.Dm_build_36(dm_build_363.dm_build_333)
+ }
+ return nil
+}
+
+func (dm_build_368 *dm_build_332) dm_build_367(dm_build_369 dm_build_725) (err error) {
+ defer func() {
+ if p := recover(); p != nil {
+ if _, ok := p.(string); ok {
+ err = ECGO_COMMUNITION_ERROR.addDetail("\t" + p.(string)).throw()
+ } else {
+ panic(p)
+ }
+ }
+ }()
+
+ dm_build_371 := int32(0)
+ if dm_build_368.dm_build_594(dm_build_369) {
+ if dm_build_368.dm_build_334 != nil {
+ dm_build_368.dm_build_335.Dm_build_14(0)
+ dm_build_368.dm_build_335.Dm_build_30(dm_build_368.dm_build_334, Dm_build_633)
+ dm_build_371 = dm_build_369.dm_build_738()
+ if dm_build_371 > 0 {
+ dm_build_368.dm_build_335.Dm_build_30(dm_build_368.dm_build_334, int(dm_build_371))
+ }
+ }
+ } else {
+
+ dm_build_368.dm_build_335.Dm_build_14(0)
+ dm_build_368.dm_build_335.Dm_build_30(dm_build_368.dm_build_333, Dm_build_633)
+ dm_build_371 = dm_build_369.dm_build_738()
+
+ if dm_build_371 > 0 {
+ dm_build_368.dm_build_335.Dm_build_30(dm_build_368.dm_build_333, int(dm_build_371))
+ }
+ }
+
+ dm_build_369.dm_build_735()
+
+ dm_build_371 = dm_build_369.dm_build_738()
+ if dm_build_371 <= 0 {
+ return nil
+ }
+
+ if dm_build_368.dm_build_339 {
+ ebytes := dm_build_368.dm_build_335.Dm_build_290(Dm_build_633, int(dm_build_371))
+ bytes, err := dm_build_368.dm_build_337.Decrypt(ebytes, true)
+ if err != nil {
+ return err
+ }
+ dm_build_368.dm_build_335.Dm_build_14(Dm_build_633)
+ dm_build_368.dm_build_335.Dm_build_79(bytes)
+ dm_build_369.dm_build_739(int32(len(bytes)))
+ }
+
+ if dm_build_368.dm_build_358(dm_build_369) {
+
+ dm_build_371 = dm_build_369.dm_build_738()
+ cbytes := dm_build_368.dm_build_335.Dm_build_290(Dm_build_633+ULINT_SIZE, int(dm_build_371-ULINT_SIZE))
+ bytes, err := UnCompress(cbytes, int(dm_build_368.dm_build_336.dmConnector.compressID))
+ if err != nil {
+ return err
+ }
+ dm_build_368.dm_build_335.Dm_build_14(Dm_build_633)
+ dm_build_368.dm_build_335.Dm_build_79(bytes)
+ dm_build_369.dm_build_739(int32(len(bytes)))
+ }
+ return nil
+}
+
+func (dm_build_373 *dm_build_332) dm_build_372(dm_build_374 dm_build_725) (dm_build_375 interface{}, dm_build_376 error) {
+ dm_build_376 = dm_build_374.dm_build_729(dm_build_374)
+ if dm_build_376 != nil {
+ return nil, dm_build_376
+ }
+
+ dm_build_376 = dm_build_373.dm_build_362(dm_build_374)
+ if dm_build_376 != nil {
+ return nil, dm_build_376
+ }
+
+ dm_build_376 = dm_build_373.dm_build_367(dm_build_374)
+ if dm_build_376 != nil {
+ return nil, dm_build_376
+ }
+
+ return dm_build_374.dm_build_733(dm_build_374)
+}
+
+func (dm_build_378 *dm_build_332) dm_build_377() (*dm_build_1162, error) {
+
+ Dm_build_379 := dm_build_1168(dm_build_378)
+ _, dm_build_380 := dm_build_378.dm_build_372(Dm_build_379)
+ if dm_build_380 != nil {
+ return nil, dm_build_380
+ }
+
+ return Dm_build_379, nil
+}
+
+func (dm_build_382 *dm_build_332) dm_build_381() error {
+
+ dm_build_383 := dm_build_1030(dm_build_382)
+ _, dm_build_384 := dm_build_382.dm_build_372(dm_build_383)
+ if dm_build_384 != nil {
+ return dm_build_384
+ }
+
+ return nil
+}
+
+func (dm_build_386 *dm_build_332) dm_build_385() error {
+
+ var dm_build_387 *dm_build_1162
+ var err error
+ if dm_build_387, err = dm_build_386.dm_build_377(); err != nil {
+ return err
+ }
+
+ if dm_build_386.dm_build_336.sslEncrypt == 2 {
+ if err = dm_build_386.dm_build_590(false); err != nil {
+ return ECGO_INIT_SSL_FAILED.addDetail("\n" + err.Error()).throw()
+ }
+ } else if dm_build_386.dm_build_336.sslEncrypt == 1 {
+ if err = dm_build_386.dm_build_590(true); err != nil {
+ return ECGO_INIT_SSL_FAILED.addDetail("\n" + err.Error()).throw()
+ }
+ }
+
+ if dm_build_386.dm_build_339 || dm_build_386.dm_build_338 {
+ k, err := dm_build_386.dm_build_580()
+ if err != nil {
+ return err
+ }
+ sessionKey := security.ComputeSessionKey(k, dm_build_387.Dm_build_1166)
+ encryptType := dm_build_387.dm_build_1164
+ hashType := int(dm_build_387.Dm_build_1165)
+ if encryptType == -1 {
+ encryptType = security.DES_CFB
+ }
+ if hashType == -1 {
+ hashType = security.MD5
+ }
+ err = dm_build_386.dm_build_583(encryptType, sessionKey, dm_build_386.dm_build_336.dmConnector.cipherPath, hashType)
+ if err != nil {
+ return err
+ }
+ }
+
+ if err := dm_build_386.dm_build_381(); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (dm_build_390 *dm_build_332) Dm_build_389(dm_build_391 *DmStatement) error {
+ dm_build_392 := dm_build_1191(dm_build_390, dm_build_391)
+ _, dm_build_393 := dm_build_390.dm_build_372(dm_build_392)
+ if dm_build_393 != nil {
+ return dm_build_393
+ }
+
+ return nil
+}
+
+func (dm_build_395 *dm_build_332) Dm_build_394(dm_build_396 int32) error {
+ dm_build_397 := dm_build_1201(dm_build_395, dm_build_396)
+ _, dm_build_398 := dm_build_395.dm_build_372(dm_build_397)
+ if dm_build_398 != nil {
+ return dm_build_398
+ }
+
+ return nil
+}
+
+func (dm_build_400 *dm_build_332) Dm_build_399(dm_build_401 *DmStatement, dm_build_402 bool, dm_build_403 int16) (*execRetInfo, error) {
+ dm_build_404 := dm_build_1068(dm_build_400, dm_build_401, dm_build_402, dm_build_403)
+ dm_build_405, dm_build_406 := dm_build_400.dm_build_372(dm_build_404)
+ if dm_build_406 != nil {
+ return nil, dm_build_406
+ }
+ return dm_build_405.(*execRetInfo), nil
+}
+
+func (dm_build_408 *dm_build_332) Dm_build_407(dm_build_409 *DmStatement, dm_build_410 int16) (*execRetInfo, error) {
+ return dm_build_408.Dm_build_399(dm_build_409, false, Dm_build_685)
+}
+
+func (dm_build_412 *dm_build_332) Dm_build_411(dm_build_413 *DmStatement, dm_build_414 []OptParameter) (*execRetInfo, error) {
+ dm_build_415, dm_build_416 := dm_build_412.dm_build_372(dm_build_827(dm_build_412, dm_build_413, dm_build_414))
+ if dm_build_416 != nil {
+ return nil, dm_build_416
+ }
+
+ return dm_build_415.(*execRetInfo), nil
+}
+
+func (dm_build_418 *dm_build_332) Dm_build_417(dm_build_419 *DmStatement, dm_build_420 int16) (*execRetInfo, error) {
+ return dm_build_418.Dm_build_399(dm_build_419, true, dm_build_420)
+}
+
+func (dm_build_422 *dm_build_332) Dm_build_421(dm_build_423 *DmStatement, dm_build_424 [][]interface{}) (*execRetInfo, error) {
+ dm_build_425 := dm_build_850(dm_build_422, dm_build_423, dm_build_424)
+ dm_build_426, dm_build_427 := dm_build_422.dm_build_372(dm_build_425)
+ if dm_build_427 != nil {
+ return nil, dm_build_427
+ }
+ return dm_build_426.(*execRetInfo), nil
+}
+
+func (dm_build_429 *dm_build_332) Dm_build_428(dm_build_430 *DmStatement, dm_build_431 [][]interface{}, dm_build_432 bool) (*execRetInfo, error) {
+ var dm_build_433, dm_build_434 = 0, 0
+ var dm_build_435 = len(dm_build_431)
+ var dm_build_436 [][]interface{}
+ var dm_build_437 = NewExceInfo()
+ dm_build_437.updateCounts = make([]int64, dm_build_435)
+ var dm_build_438 = false
+ for dm_build_433 < dm_build_435 {
+ for dm_build_434 = dm_build_433; dm_build_434 < dm_build_435; dm_build_434++ {
+ paramData := dm_build_431[dm_build_434]
+ bindData := make([]interface{}, dm_build_430.paramCount)
+ dm_build_438 = false
+ for icol := 0; icol < int(dm_build_430.paramCount); icol++ {
+ if dm_build_430.params[icol].ioType == IO_TYPE_OUT {
+ continue
+ }
+ if dm_build_429.dm_build_563(bindData, paramData, icol) {
+ dm_build_438 = true
+ break
+ }
+ }
+
+ if dm_build_438 {
+ break
+ }
+ dm_build_436 = append(dm_build_436, bindData)
+ }
+
+ if dm_build_434 != dm_build_433 {
+ tmpExecInfo, err := dm_build_429.Dm_build_421(dm_build_430, dm_build_436)
+ if err != nil {
+ return nil, err
+ }
+ dm_build_436 = dm_build_436[0:0]
+ dm_build_437.union(tmpExecInfo, dm_build_433, dm_build_434-dm_build_433)
+ }
+
+ if dm_build_434 < dm_build_435 {
+ tmpExecInfo, err := dm_build_429.Dm_build_439(dm_build_430, dm_build_431[dm_build_434], dm_build_432)
+ if err != nil {
+ return nil, err
+ }
+
+ dm_build_432 = true
+ dm_build_437.union(tmpExecInfo, dm_build_434, 1)
+ }
+
+ dm_build_433 = dm_build_434 + 1
+ }
+ for _, i := range dm_build_437.updateCounts {
+ if i > 0 {
+ dm_build_437.updateCount += i
+ }
+ }
+ return dm_build_437, nil
+}
+
+func (dm_build_440 *dm_build_332) Dm_build_439(dm_build_441 *DmStatement, dm_build_442 []interface{}, dm_build_443 bool) (*execRetInfo, error) {
+
+ var dm_build_444 = make([]interface{}, dm_build_441.paramCount)
+ for icol := 0; icol < int(dm_build_441.paramCount); icol++ {
+ if dm_build_441.params[icol].ioType == IO_TYPE_OUT {
+ continue
+ }
+ if dm_build_440.dm_build_563(dm_build_444, dm_build_442, icol) {
+
+ if !dm_build_443 {
+ preExecute := dm_build_1058(dm_build_440, dm_build_441, dm_build_441.params)
+ dm_build_440.dm_build_372(preExecute)
+ dm_build_443 = true
+ }
+
+ dm_build_440.dm_build_569(dm_build_441, dm_build_441.params[icol], icol, dm_build_442[icol].(iOffRowBinder))
+ dm_build_444[icol] = ParamDataEnum_OFF_ROW
+ }
+ }
+
+ var dm_build_445 = make([][]interface{}, 1, 1)
+ dm_build_445[0] = dm_build_444
+
+ dm_build_446 := dm_build_850(dm_build_440, dm_build_441, dm_build_445)
+ dm_build_447, dm_build_448 := dm_build_440.dm_build_372(dm_build_446)
+ if dm_build_448 != nil {
+ return nil, dm_build_448
+ }
+ return dm_build_447.(*execRetInfo), nil
+}
+
+func (dm_build_450 *dm_build_332) Dm_build_449(dm_build_451 *DmStatement, dm_build_452 int16) (*execRetInfo, error) {
+ dm_build_453 := dm_build_1045(dm_build_450, dm_build_451, dm_build_452)
+
+ dm_build_454, dm_build_455 := dm_build_450.dm_build_372(dm_build_453)
+ if dm_build_455 != nil {
+ return nil, dm_build_455
+ }
+ return dm_build_454.(*execRetInfo), nil
+}
+
+func (dm_build_457 *dm_build_332) Dm_build_456(dm_build_458 *innerRows, dm_build_459 int64) (*execRetInfo, error) {
+ dm_build_460 := dm_build_950(dm_build_457, dm_build_458, dm_build_459, INT64_MAX)
+ dm_build_461, dm_build_462 := dm_build_457.dm_build_372(dm_build_460)
+ if dm_build_462 != nil {
+ return nil, dm_build_462
+ }
+ return dm_build_461.(*execRetInfo), nil
+}
+
+func (dm_build_464 *dm_build_332) Commit() error {
+ dm_build_465 := dm_build_813(dm_build_464)
+ _, dm_build_466 := dm_build_464.dm_build_372(dm_build_465)
+ if dm_build_466 != nil {
+ return dm_build_466
+ }
+
+ return nil
+}
+
+func (dm_build_468 *dm_build_332) Rollback() error {
+ dm_build_469 := dm_build_1106(dm_build_468)
+ _, dm_build_470 := dm_build_468.dm_build_372(dm_build_469)
+ if dm_build_470 != nil {
+ return dm_build_470
+ }
+
+ return nil
+}
+
+func (dm_build_472 *dm_build_332) Dm_build_471(dm_build_473 *DmConnection) error {
+ dm_build_474 := dm_build_1111(dm_build_472, dm_build_473.IsoLevel)
+ _, dm_build_475 := dm_build_472.dm_build_372(dm_build_474)
+ if dm_build_475 != nil {
+ return dm_build_475
+ }
+
+ return nil
+}
+
+func (dm_build_477 *dm_build_332) Dm_build_476(dm_build_478 *DmStatement, dm_build_479 string) error {
+ dm_build_480 := dm_build_818(dm_build_477, dm_build_478, dm_build_479)
+ _, dm_build_481 := dm_build_477.dm_build_372(dm_build_480)
+ if dm_build_481 != nil {
+ return dm_build_481
+ }
+
+ return nil
+}
+
+func (dm_build_483 *dm_build_332) Dm_build_482(dm_build_484 []uint32) ([]int64, error) {
+ dm_build_485 := dm_build_1209(dm_build_483, dm_build_484)
+ dm_build_486, dm_build_487 := dm_build_483.dm_build_372(dm_build_485)
+ if dm_build_487 != nil {
+ return nil, dm_build_487
+ }
+ return dm_build_486.([]int64), nil
+}
+
+func (dm_build_489 *dm_build_332) Close() error {
+ if dm_build_489.dm_build_343 {
+ return nil
+ }
+
+ dm_build_490 := dm_build_489.dm_build_333.Close()
+ if dm_build_490 != nil {
+ return dm_build_490
+ }
+
+ dm_build_489.dm_build_336 = nil
+ dm_build_489.dm_build_343 = true
+ return nil
+}
+
+func (dm_build_492 *dm_build_332) dm_build_491(dm_build_493 *lob) (int64, error) {
+ dm_build_494 := dm_build_981(dm_build_492, dm_build_493)
+ dm_build_495, dm_build_496 := dm_build_492.dm_build_372(dm_build_494)
+ if dm_build_496 != nil {
+ return 0, dm_build_496
+ }
+ return dm_build_495.(int64), nil
+}
+
+func (dm_build_498 *dm_build_332) dm_build_497(dm_build_499 *lob, dm_build_500 int32, dm_build_501 int32) ([]byte, error) {
+ dm_build_502 := dm_build_968(dm_build_498, dm_build_499, int(dm_build_500), int(dm_build_501))
+ dm_build_503, dm_build_504 := dm_build_498.dm_build_372(dm_build_502)
+ if dm_build_504 != nil {
+ return nil, dm_build_504
+ }
+ return dm_build_503.([]byte), nil
+}
+
+func (dm_build_506 *dm_build_332) dm_build_505(dm_build_507 *DmBlob, dm_build_508 int32, dm_build_509 int32) ([]byte, error) {
+ var dm_build_510 = make([]byte, dm_build_509)
+ var dm_build_511 int32 = 0
+ var dm_build_512 int32 = 0
+ var dm_build_513 []byte
+ var dm_build_514 error
+ for dm_build_511 < dm_build_509 {
+ dm_build_512 = dm_build_509 - dm_build_511
+ if dm_build_512 > Dm_build_718 {
+ dm_build_512 = Dm_build_718
+ }
+ dm_build_513, dm_build_514 = dm_build_506.dm_build_497(&dm_build_507.lob, dm_build_508, dm_build_512)
+ if dm_build_514 != nil {
+ return nil, dm_build_514
+ }
+ if dm_build_513 == nil || len(dm_build_513) == 0 {
+ break
+ }
+ Dm_build_1220.Dm_build_1276(dm_build_510, int(dm_build_511), dm_build_513, 0, len(dm_build_513))
+ dm_build_511 += int32(len(dm_build_513))
+ dm_build_508 += int32(len(dm_build_513))
+ if dm_build_507.readOver {
+ break
+ }
+ }
+ return dm_build_510, nil
+}
+
+func (dm_build_516 *dm_build_332) dm_build_515(dm_build_517 *DmClob, dm_build_518 int32, dm_build_519 int32) (string, error) {
+ var dm_build_520 bytes.Buffer
+ var dm_build_521 int32 = 0
+ var dm_build_522 int32 = 0
+ var dm_build_523 []byte
+ var dm_build_524 string
+ var dm_build_525 error
+ for dm_build_521 < dm_build_519 {
+ dm_build_522 = dm_build_519 - dm_build_521
+ if dm_build_522 > Dm_build_718/2 {
+ dm_build_522 = Dm_build_718 / 2
+ }
+ dm_build_523, dm_build_525 = dm_build_516.dm_build_497(&dm_build_517.lob, dm_build_518, dm_build_522)
+ if dm_build_525 != nil {
+ return "", dm_build_525
+ }
+ if dm_build_523 == nil || len(dm_build_523) == 0 {
+ break
+ }
+ dm_build_524 = Dm_build_1220.Dm_build_1377(dm_build_523, 0, len(dm_build_523), dm_build_517.serverEncoding, dm_build_516.dm_build_336)
+
+ dm_build_520.WriteString(dm_build_524)
+ dm_build_521 += int32(len(dm_build_524))
+ dm_build_518 += int32(len(dm_build_524))
+ if dm_build_517.readOver {
+ break
+ }
+ }
+ return dm_build_520.String(), nil
+}
+
+func (dm_build_527 *dm_build_332) dm_build_526(dm_build_528 *DmClob, dm_build_529 int, dm_build_530 string, dm_build_531 string) (int, error) {
+ var dm_build_532 = Dm_build_1220.Dm_build_1433(dm_build_530, dm_build_531, dm_build_527.dm_build_336)
+ var dm_build_533 = 0
+ var dm_build_534 = len(dm_build_532)
+ var dm_build_535 = 0
+ var dm_build_536 = 0
+ var dm_build_537 = 0
+ var dm_build_538 = dm_build_534/Dm_build_717 + 1
+ var dm_build_539 byte = 0
+ var dm_build_540 byte = 0x01
+ var dm_build_541 byte = 0x02
+ for i := 0; i < dm_build_538; i++ {
+ dm_build_539 = 0
+ if i == 0 {
+ dm_build_539 |= dm_build_540
+ }
+ if i == dm_build_538-1 {
+ dm_build_539 |= dm_build_541
+ }
+ dm_build_537 = dm_build_534 - dm_build_536
+ if dm_build_537 > Dm_build_717 {
+ dm_build_537 = Dm_build_717
+ }
+
+ setLobData := dm_build_1125(dm_build_527, &dm_build_528.lob, dm_build_539, dm_build_529, dm_build_532, dm_build_533, dm_build_537)
+ ret, err := dm_build_527.dm_build_372(setLobData)
+ if err != nil {
+ return 0, err
+ }
+ tmp := ret.(int32)
+ if err != nil {
+ return -1, err
+ }
+ if tmp <= 0 {
+ return dm_build_535, nil
+ } else {
+ dm_build_529 += int(tmp)
+ dm_build_535 += int(tmp)
+ dm_build_536 += dm_build_537
+ dm_build_533 += dm_build_537
+ }
+ }
+ return dm_build_535, nil
+}
+
+func (dm_build_543 *dm_build_332) dm_build_542(dm_build_544 *DmBlob, dm_build_545 int, dm_build_546 []byte) (int, error) {
+ var dm_build_547 = 0
+ var dm_build_548 = len(dm_build_546)
+ var dm_build_549 = 0
+ var dm_build_550 = 0
+ var dm_build_551 = 0
+ var dm_build_552 = dm_build_548/Dm_build_717 + 1
+ var dm_build_553 byte = 0
+ var dm_build_554 byte = 0x01
+ var dm_build_555 byte = 0x02
+ for i := 0; i < dm_build_552; i++ {
+ dm_build_553 = 0
+ if i == 0 {
+ dm_build_553 |= dm_build_554
+ }
+ if i == dm_build_552-1 {
+ dm_build_553 |= dm_build_555
+ }
+ dm_build_551 = dm_build_548 - dm_build_550
+ if dm_build_551 > Dm_build_717 {
+ dm_build_551 = Dm_build_717
+ }
+
+ setLobData := dm_build_1125(dm_build_543, &dm_build_544.lob, dm_build_553, dm_build_545, dm_build_546, dm_build_547, dm_build_551)
+ ret, err := dm_build_543.dm_build_372(setLobData)
+ if err != nil {
+ return 0, err
+ }
+ tmp := ret.(int32)
+ if tmp <= 0 {
+ return dm_build_549, nil
+ } else {
+ dm_build_545 += int(tmp)
+ dm_build_549 += int(tmp)
+ dm_build_550 += dm_build_551
+ dm_build_547 += dm_build_551
+ }
+ }
+ return dm_build_549, nil
+}
+
+func (dm_build_557 *dm_build_332) dm_build_556(dm_build_558 *lob, dm_build_559 int) (int64, error) {
+ dm_build_560 := dm_build_992(dm_build_557, dm_build_558, dm_build_559)
+ dm_build_561, dm_build_562 := dm_build_557.dm_build_372(dm_build_560)
+ if dm_build_562 != nil {
+ return dm_build_558.length, dm_build_562
+ }
+ return dm_build_561.(int64), nil
+}
+
+func (dm_build_564 *dm_build_332) dm_build_563(dm_build_565 []interface{}, dm_build_566 []interface{}, dm_build_567 int) bool {
+ var dm_build_568 = false
+ if dm_build_567 >= len(dm_build_566) || dm_build_566[dm_build_567] == nil {
+ dm_build_565[dm_build_567] = ParamDataEnum_Null
+ } else if binder, ok := dm_build_566[dm_build_567].(iOffRowBinder); ok {
+ dm_build_568 = true
+ dm_build_565[dm_build_567] = ParamDataEnum_OFF_ROW
+ var lob lob
+ if l, ok := binder.getObj().(DmBlob); ok {
+ lob = l.lob
+ } else if l, ok := binder.getObj().(DmClob); ok {
+ lob = l.lob
+ }
+ if &lob != nil && lob.canOptimized(dm_build_564.dm_build_336) {
+ dm_build_565[dm_build_567] = &lobCtl{lob.buildCtlData()}
+ dm_build_568 = false
+ }
+ } else {
+ dm_build_565[dm_build_567] = dm_build_566[dm_build_567]
+ }
+ return dm_build_568
+}
+
+func (dm_build_570 *dm_build_332) dm_build_569(dm_build_571 *DmStatement, dm_build_572 parameter, dm_build_573 int, dm_build_574 iOffRowBinder) error {
+ var dm_build_575 = Dm_build_1503()
+ dm_build_574.read(dm_build_575)
+ var dm_build_576 = 0
+ for !dm_build_574.isReadOver() || dm_build_575.Dm_build_1504() > 0 {
+ if !dm_build_574.isReadOver() && dm_build_575.Dm_build_1504() < Dm_build_717 {
+ dm_build_574.read(dm_build_575)
+ }
+ if dm_build_575.Dm_build_1504() > Dm_build_717 {
+ dm_build_576 = Dm_build_717
+ } else {
+ dm_build_576 = dm_build_575.Dm_build_1504()
+ }
+
+ putData := dm_build_1096(dm_build_570, dm_build_571, int16(dm_build_573), dm_build_575, int32(dm_build_576))
+ _, err := dm_build_570.dm_build_372(putData)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (dm_build_578 *dm_build_332) dm_build_577() ([]byte, error) {
+ var dm_build_579 error
+ if dm_build_578.dm_build_340 == nil {
+ if dm_build_578.dm_build_340, dm_build_579 = security.NewClientKeyPair(); dm_build_579 != nil {
+ return nil, dm_build_579
+ }
+ }
+ return security.Bn2Bytes(dm_build_578.dm_build_340.GetY(), security.DH_KEY_LENGTH), nil
+}
+
+func (dm_build_581 *dm_build_332) dm_build_580() (*security.DhKey, error) {
+ var dm_build_582 error
+ if dm_build_581.dm_build_340 == nil {
+ if dm_build_581.dm_build_340, dm_build_582 = security.NewClientKeyPair(); dm_build_582 != nil {
+ return nil, dm_build_582
+ }
+ }
+ return dm_build_581.dm_build_340, nil
+}
+
+func (dm_build_584 *dm_build_332) dm_build_583(dm_build_585 int, dm_build_586 []byte, dm_build_587 string, dm_build_588 int) (dm_build_589 error) {
+ if dm_build_585 > 0 && dm_build_585 < security.MIN_EXTERNAL_CIPHER_ID && dm_build_586 != nil {
+ dm_build_584.dm_build_337, dm_build_589 = security.NewSymmCipher(dm_build_585, dm_build_586)
+ } else if dm_build_585 >= security.MIN_EXTERNAL_CIPHER_ID {
+ if dm_build_584.dm_build_337, dm_build_589 = security.NewThirdPartCipher(dm_build_585, dm_build_586, dm_build_587, dm_build_588); dm_build_589 != nil {
+ dm_build_589 = THIRD_PART_CIPHER_INIT_FAILED.addDetailln(dm_build_589.Error()).throw()
+ }
+ }
+ return
+}
+
+func (dm_build_591 *dm_build_332) dm_build_590(dm_build_592 bool) (dm_build_593 error) {
+ if dm_build_591.dm_build_334, dm_build_593 = security.NewTLSFromTCP(dm_build_591.dm_build_333, dm_build_591.dm_build_336.dmConnector.sslCertPath, dm_build_591.dm_build_336.dmConnector.sslKeyPath, dm_build_591.dm_build_336.dmConnector.user); dm_build_593 != nil {
+ return
+ }
+ if !dm_build_592 {
+ dm_build_591.dm_build_334 = nil
+ }
+ return
+}
+
+func (dm_build_595 *dm_build_332) dm_build_594(dm_build_596 dm_build_725) bool {
+ return dm_build_596.dm_build_740() != Dm_build_632 && dm_build_595.dm_build_336.sslEncrypt == 1
+}
diff --git a/dmr/b.go b/dmr/b.go
new file mode 100644
index 0000000..aaacc76
--- /dev/null
+++ b/dmr/b.go
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+type ArrayDescriptor struct {
+ m_typeDesc *TypeDescriptor
+}
+
+func newArrayDescriptor(fulName string, conn *DmConnection) (*ArrayDescriptor, error) {
+
+ ad := new(ArrayDescriptor)
+
+ if fulName == "" {
+ return nil, ECGO_INVALID_COMPLEX_TYPE_NAME.throw()
+ }
+
+ ad.m_typeDesc = newTypeDescriptorWithFulName(fulName, conn)
+ err := ad.m_typeDesc.parseDescByName()
+ if err != nil {
+ return nil, err
+ }
+
+ return ad, nil
+}
+
+func newArrayDescriptorByTypeDescriptor(desc *TypeDescriptor) *ArrayDescriptor {
+ ad := new(ArrayDescriptor)
+ ad.m_typeDesc = desc
+ return ad
+}
+
+func (ad *ArrayDescriptor) getMDesc() *TypeDescriptor {
+ return ad.m_typeDesc
+}
+
+func (ad *ArrayDescriptor) getItemDesc() *TypeDescriptor {
+ return ad.m_typeDesc.m_arrObj
+}
+
+func (ad *ArrayDescriptor) getLength() int {
+ return ad.m_typeDesc.m_length
+}
diff --git a/dmr/c.go b/dmr/c.go
new file mode 100644
index 0000000..767aa35
--- /dev/null
+++ b/dmr/c.go
@@ -0,0 +1,484 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "io"
+ "math"
+)
+
+type Dm_build_0 struct {
+ dm_build_1 []byte
+ dm_build_2 int
+}
+
+func Dm_build_3(dm_build_4 int) *Dm_build_0 {
+ return &Dm_build_0{make([]byte, 0, dm_build_4), 0}
+}
+
+func Dm_build_5(dm_build_6 []byte) *Dm_build_0 {
+ return &Dm_build_0{dm_build_6, 0}
+}
+
+func (dm_build_8 *Dm_build_0) dm_build_7(dm_build_9 int) *Dm_build_0 {
+
+ dm_build_10 := len(dm_build_8.dm_build_1)
+ dm_build_11 := cap(dm_build_8.dm_build_1)
+
+ if dm_build_10+dm_build_9 <= dm_build_11 {
+ dm_build_8.dm_build_1 = dm_build_8.dm_build_1[:dm_build_10+dm_build_9]
+ } else {
+ remain := dm_build_9 + dm_build_10 - dm_build_11
+ nbuf := make([]byte, dm_build_9+dm_build_10, 2*dm_build_11+remain)
+ copy(nbuf, dm_build_8.dm_build_1)
+ dm_build_8.dm_build_1 = nbuf
+ }
+
+ return dm_build_8
+}
+
+func (dm_build_13 *Dm_build_0) Dm_build_12() int {
+ return len(dm_build_13.dm_build_1)
+}
+
+func (dm_build_15 *Dm_build_0) Dm_build_14(dm_build_16 int) *Dm_build_0 {
+ for i := dm_build_16; i < len(dm_build_15.dm_build_1); i++ {
+ dm_build_15.dm_build_1[i] = 0
+ }
+ dm_build_15.dm_build_1 = dm_build_15.dm_build_1[:dm_build_16]
+ return dm_build_15
+}
+
+func (dm_build_18 *Dm_build_0) Dm_build_17(dm_build_19 int) *Dm_build_0 {
+ dm_build_18.dm_build_2 = dm_build_19
+ return dm_build_18
+}
+
+func (dm_build_21 *Dm_build_0) Dm_build_20() int {
+ return dm_build_21.dm_build_2
+}
+
+func (dm_build_23 *Dm_build_0) Dm_build_22(dm_build_24 bool) int {
+ return len(dm_build_23.dm_build_1) - dm_build_23.dm_build_2
+}
+
+func (dm_build_26 *Dm_build_0) Dm_build_25(dm_build_27 int, dm_build_28 bool, dm_build_29 bool) *Dm_build_0 {
+
+ if dm_build_28 {
+ if dm_build_29 {
+ dm_build_26.dm_build_7(dm_build_27)
+ } else {
+ dm_build_26.dm_build_1 = dm_build_26.dm_build_1[:len(dm_build_26.dm_build_1)-dm_build_27]
+ }
+ } else {
+ if dm_build_29 {
+ dm_build_26.dm_build_2 += dm_build_27
+ } else {
+ dm_build_26.dm_build_2 -= dm_build_27
+ }
+ }
+
+ return dm_build_26
+}
+
+func (dm_build_31 *Dm_build_0) Dm_build_30(dm_build_32 io.Reader, dm_build_33 int) int {
+ dm_build_34 := len(dm_build_31.dm_build_1)
+ dm_build_31.dm_build_7(dm_build_33)
+ dm_build_35 := 0
+ for dm_build_33 > 0 {
+ n, err := dm_build_32.Read(dm_build_31.dm_build_1[dm_build_34+dm_build_35:])
+ if n > 0 && err == io.EOF {
+ dm_build_35 += n
+ dm_build_31.dm_build_1 = dm_build_31.dm_build_1[:dm_build_34+dm_build_35]
+ return dm_build_35
+ } else if n > 0 && err == nil {
+ dm_build_33 -= n
+ dm_build_35 += n
+ } else if n == 0 && err != nil {
+ panic("load err")
+ }
+ }
+
+ return dm_build_35
+}
+
+func (dm_build_37 *Dm_build_0) Dm_build_36(dm_build_38 io.Writer) *Dm_build_0 {
+ dm_build_38.Write(dm_build_37.dm_build_1)
+ return dm_build_37
+}
+
+func (dm_build_40 *Dm_build_0) Dm_build_39(dm_build_41 bool) int {
+ dm_build_42 := len(dm_build_40.dm_build_1)
+ dm_build_40.dm_build_7(1)
+
+ if dm_build_41 {
+ return copy(dm_build_40.dm_build_1[dm_build_42:], []byte{1})
+ } else {
+ return copy(dm_build_40.dm_build_1[dm_build_42:], []byte{0})
+ }
+}
+
+func (dm_build_44 *Dm_build_0) Dm_build_43(dm_build_45 byte) int {
+ dm_build_46 := len(dm_build_44.dm_build_1)
+ dm_build_44.dm_build_7(1)
+
+ return copy(dm_build_44.dm_build_1[dm_build_46:], Dm_build_1220.Dm_build_1398(dm_build_45))
+}
+
+func (dm_build_48 *Dm_build_0) Dm_build_47(dm_build_49 int16) int {
+ dm_build_50 := len(dm_build_48.dm_build_1)
+ dm_build_48.dm_build_7(2)
+
+ return copy(dm_build_48.dm_build_1[dm_build_50:], Dm_build_1220.Dm_build_1401(dm_build_49))
+}
+
+func (dm_build_52 *Dm_build_0) Dm_build_51(dm_build_53 int32) int {
+ dm_build_54 := len(dm_build_52.dm_build_1)
+ dm_build_52.dm_build_7(4)
+
+ return copy(dm_build_52.dm_build_1[dm_build_54:], Dm_build_1220.Dm_build_1404(dm_build_53))
+}
+
+func (dm_build_56 *Dm_build_0) Dm_build_55(dm_build_57 uint8) int {
+ dm_build_58 := len(dm_build_56.dm_build_1)
+ dm_build_56.dm_build_7(1)
+
+ return copy(dm_build_56.dm_build_1[dm_build_58:], Dm_build_1220.Dm_build_1416(dm_build_57))
+}
+
+func (dm_build_60 *Dm_build_0) Dm_build_59(dm_build_61 uint16) int {
+ dm_build_62 := len(dm_build_60.dm_build_1)
+ dm_build_60.dm_build_7(2)
+
+ return copy(dm_build_60.dm_build_1[dm_build_62:], Dm_build_1220.Dm_build_1419(dm_build_61))
+}
+
+func (dm_build_64 *Dm_build_0) Dm_build_63(dm_build_65 uint32) int {
+ dm_build_66 := len(dm_build_64.dm_build_1)
+ dm_build_64.dm_build_7(4)
+
+ return copy(dm_build_64.dm_build_1[dm_build_66:], Dm_build_1220.Dm_build_1422(dm_build_65))
+}
+
+func (dm_build_68 *Dm_build_0) Dm_build_67(dm_build_69 uint64) int {
+ dm_build_70 := len(dm_build_68.dm_build_1)
+ dm_build_68.dm_build_7(8)
+
+ return copy(dm_build_68.dm_build_1[dm_build_70:], Dm_build_1220.Dm_build_1425(dm_build_69))
+}
+
+func (dm_build_72 *Dm_build_0) Dm_build_71(dm_build_73 float32) int {
+ dm_build_74 := len(dm_build_72.dm_build_1)
+ dm_build_72.dm_build_7(4)
+
+ return copy(dm_build_72.dm_build_1[dm_build_74:], Dm_build_1220.Dm_build_1422(math.Float32bits(dm_build_73)))
+}
+
+func (dm_build_76 *Dm_build_0) Dm_build_75(dm_build_77 float64) int {
+ dm_build_78 := len(dm_build_76.dm_build_1)
+ dm_build_76.dm_build_7(8)
+
+ return copy(dm_build_76.dm_build_1[dm_build_78:], Dm_build_1220.Dm_build_1425(math.Float64bits(dm_build_77)))
+}
+
+func (dm_build_80 *Dm_build_0) Dm_build_79(dm_build_81 []byte) int {
+ dm_build_82 := len(dm_build_80.dm_build_1)
+ dm_build_80.dm_build_7(len(dm_build_81))
+ return copy(dm_build_80.dm_build_1[dm_build_82:], dm_build_81)
+}
+
+func (dm_build_84 *Dm_build_0) Dm_build_83(dm_build_85 []byte) int {
+ return dm_build_84.Dm_build_51(int32(len(dm_build_85))) + dm_build_84.Dm_build_79(dm_build_85)
+}
+
+func (dm_build_87 *Dm_build_0) Dm_build_86(dm_build_88 []byte) int {
+ return dm_build_87.Dm_build_55(uint8(len(dm_build_88))) + dm_build_87.Dm_build_79(dm_build_88)
+}
+
+func (dm_build_90 *Dm_build_0) Dm_build_89(dm_build_91 []byte) int {
+ return dm_build_90.Dm_build_59(uint16(len(dm_build_91))) + dm_build_90.Dm_build_79(dm_build_91)
+}
+
+func (dm_build_93 *Dm_build_0) Dm_build_92(dm_build_94 []byte) int {
+ return dm_build_93.Dm_build_79(dm_build_94) + dm_build_93.Dm_build_43(0)
+}
+
+func (dm_build_96 *Dm_build_0) Dm_build_95(dm_build_97 string, dm_build_98 string, dm_build_99 *DmConnection) int {
+ dm_build_100 := Dm_build_1220.Dm_build_1433(dm_build_97, dm_build_98, dm_build_99)
+ return dm_build_96.Dm_build_83(dm_build_100)
+}
+
+func (dm_build_102 *Dm_build_0) Dm_build_101(dm_build_103 string, dm_build_104 string, dm_build_105 *DmConnection) int {
+ dm_build_106 := Dm_build_1220.Dm_build_1433(dm_build_103, dm_build_104, dm_build_105)
+ return dm_build_102.Dm_build_86(dm_build_106)
+}
+
+func (dm_build_108 *Dm_build_0) Dm_build_107(dm_build_109 string, dm_build_110 string, dm_build_111 *DmConnection) int {
+ dm_build_112 := Dm_build_1220.Dm_build_1433(dm_build_109, dm_build_110, dm_build_111)
+ return dm_build_108.Dm_build_89(dm_build_112)
+}
+
+func (dm_build_114 *Dm_build_0) Dm_build_113(dm_build_115 string, dm_build_116 string, dm_build_117 *DmConnection) int {
+ dm_build_118 := Dm_build_1220.Dm_build_1433(dm_build_115, dm_build_116, dm_build_117)
+ return dm_build_114.Dm_build_92(dm_build_118)
+}
+
+func (dm_build_120 *Dm_build_0) Dm_build_119() byte {
+ dm_build_121 := Dm_build_1220.Dm_build_1313(dm_build_120.dm_build_1, dm_build_120.dm_build_2)
+ dm_build_120.dm_build_2++
+ return dm_build_121
+}
+
+func (dm_build_123 *Dm_build_0) Dm_build_122() int16 {
+ dm_build_124 := Dm_build_1220.Dm_build_1317(dm_build_123.dm_build_1, dm_build_123.dm_build_2)
+ dm_build_123.dm_build_2 += 2
+ return dm_build_124
+}
+
+func (dm_build_126 *Dm_build_0) Dm_build_125() int32 {
+ dm_build_127 := Dm_build_1220.Dm_build_1322(dm_build_126.dm_build_1, dm_build_126.dm_build_2)
+ dm_build_126.dm_build_2 += 4
+ return dm_build_127
+}
+
+func (dm_build_129 *Dm_build_0) Dm_build_128() int64 {
+ dm_build_130 := Dm_build_1220.Dm_build_1327(dm_build_129.dm_build_1, dm_build_129.dm_build_2)
+ dm_build_129.dm_build_2 += 8
+ return dm_build_130
+}
+
+func (dm_build_132 *Dm_build_0) Dm_build_131() float32 {
+ dm_build_133 := Dm_build_1220.Dm_build_1332(dm_build_132.dm_build_1, dm_build_132.dm_build_2)
+ dm_build_132.dm_build_2 += 4
+ return dm_build_133
+}
+
+func (dm_build_135 *Dm_build_0) Dm_build_134() float64 {
+ dm_build_136 := Dm_build_1220.Dm_build_1336(dm_build_135.dm_build_1, dm_build_135.dm_build_2)
+ dm_build_135.dm_build_2 += 8
+ return dm_build_136
+}
+
+func (dm_build_138 *Dm_build_0) Dm_build_137() uint8 {
+ dm_build_139 := Dm_build_1220.Dm_build_1340(dm_build_138.dm_build_1, dm_build_138.dm_build_2)
+ dm_build_138.dm_build_2 += 1
+ return dm_build_139
+}
+
+func (dm_build_141 *Dm_build_0) Dm_build_140() uint16 {
+ dm_build_142 := Dm_build_1220.Dm_build_1344(dm_build_141.dm_build_1, dm_build_141.dm_build_2)
+ dm_build_141.dm_build_2 += 2
+ return dm_build_142
+}
+
+func (dm_build_144 *Dm_build_0) Dm_build_143() uint32 {
+ dm_build_145 := Dm_build_1220.Dm_build_1349(dm_build_144.dm_build_1, dm_build_144.dm_build_2)
+ dm_build_144.dm_build_2 += 4
+ return dm_build_145
+}
+
+func (dm_build_147 *Dm_build_0) Dm_build_146(dm_build_148 int) []byte {
+ dm_build_149 := Dm_build_1220.Dm_build_1371(dm_build_147.dm_build_1, dm_build_147.dm_build_2, dm_build_148)
+ dm_build_147.dm_build_2 += dm_build_148
+ return dm_build_149
+}
+
+func (dm_build_151 *Dm_build_0) Dm_build_150() []byte {
+ return dm_build_151.Dm_build_146(int(dm_build_151.Dm_build_125()))
+}
+
+func (dm_build_153 *Dm_build_0) Dm_build_152() []byte {
+ return dm_build_153.Dm_build_146(int(dm_build_153.Dm_build_119()))
+}
+
+func (dm_build_155 *Dm_build_0) Dm_build_154() []byte {
+ return dm_build_155.Dm_build_146(int(dm_build_155.Dm_build_122()))
+}
+
+func (dm_build_157 *Dm_build_0) Dm_build_156(dm_build_158 int) []byte {
+ return dm_build_157.Dm_build_146(dm_build_158)
+}
+
+func (dm_build_160 *Dm_build_0) Dm_build_159() []byte {
+ dm_build_161 := 0
+ for dm_build_160.Dm_build_119() != 0 {
+ dm_build_161++
+ }
+ dm_build_160.Dm_build_25(dm_build_161, false, false)
+ return dm_build_160.Dm_build_146(dm_build_161)
+}
+
+func (dm_build_163 *Dm_build_0) Dm_build_162(dm_build_164 int, dm_build_165 string, dm_build_166 *DmConnection) string {
+ return Dm_build_1220.Dm_build_1470(dm_build_163.Dm_build_146(dm_build_164), dm_build_165, dm_build_166)
+}
+
+func (dm_build_168 *Dm_build_0) Dm_build_167(dm_build_169 string, dm_build_170 *DmConnection) string {
+ return Dm_build_1220.Dm_build_1470(dm_build_168.Dm_build_150(), dm_build_169, dm_build_170)
+}
+
+func (dm_build_172 *Dm_build_0) Dm_build_171(dm_build_173 string, dm_build_174 *DmConnection) string {
+ return Dm_build_1220.Dm_build_1470(dm_build_172.Dm_build_152(), dm_build_173, dm_build_174)
+}
+
+func (dm_build_176 *Dm_build_0) Dm_build_175(dm_build_177 string, dm_build_178 *DmConnection) string {
+ return Dm_build_1220.Dm_build_1470(dm_build_176.Dm_build_154(), dm_build_177, dm_build_178)
+}
+
+func (dm_build_180 *Dm_build_0) Dm_build_179(dm_build_181 string, dm_build_182 *DmConnection) string {
+ return Dm_build_1220.Dm_build_1470(dm_build_180.Dm_build_159(), dm_build_181, dm_build_182)
+}
+
+func (dm_build_184 *Dm_build_0) Dm_build_183(dm_build_185 int, dm_build_186 byte) int {
+ return dm_build_184.Dm_build_219(dm_build_185, Dm_build_1220.Dm_build_1398(dm_build_186))
+}
+
+func (dm_build_188 *Dm_build_0) Dm_build_187(dm_build_189 int, dm_build_190 int16) int {
+ return dm_build_188.Dm_build_219(dm_build_189, Dm_build_1220.Dm_build_1401(dm_build_190))
+}
+
+func (dm_build_192 *Dm_build_0) Dm_build_191(dm_build_193 int, dm_build_194 int32) int {
+ return dm_build_192.Dm_build_219(dm_build_193, Dm_build_1220.Dm_build_1404(dm_build_194))
+}
+
+func (dm_build_196 *Dm_build_0) Dm_build_195(dm_build_197 int, dm_build_198 int64) int {
+ return dm_build_196.Dm_build_219(dm_build_197, Dm_build_1220.Dm_build_1407(dm_build_198))
+}
+
+func (dm_build_200 *Dm_build_0) Dm_build_199(dm_build_201 int, dm_build_202 float32) int {
+ return dm_build_200.Dm_build_219(dm_build_201, Dm_build_1220.Dm_build_1410(dm_build_202))
+}
+
+func (dm_build_204 *Dm_build_0) Dm_build_203(dm_build_205 int, dm_build_206 float64) int {
+ return dm_build_204.Dm_build_219(dm_build_205, Dm_build_1220.Dm_build_1413(dm_build_206))
+}
+
+func (dm_build_208 *Dm_build_0) Dm_build_207(dm_build_209 int, dm_build_210 uint8) int {
+ return dm_build_208.Dm_build_219(dm_build_209, Dm_build_1220.Dm_build_1416(dm_build_210))
+}
+
+func (dm_build_212 *Dm_build_0) Dm_build_211(dm_build_213 int, dm_build_214 uint16) int {
+ return dm_build_212.Dm_build_219(dm_build_213, Dm_build_1220.Dm_build_1419(dm_build_214))
+}
+
+func (dm_build_216 *Dm_build_0) Dm_build_215(dm_build_217 int, dm_build_218 uint32) int {
+ return dm_build_216.Dm_build_219(dm_build_217, Dm_build_1220.Dm_build_1422(dm_build_218))
+}
+
+func (dm_build_220 *Dm_build_0) Dm_build_219(dm_build_221 int, dm_build_222 []byte) int {
+ return copy(dm_build_220.dm_build_1[dm_build_221:], dm_build_222)
+}
+
+func (dm_build_224 *Dm_build_0) Dm_build_223(dm_build_225 int, dm_build_226 []byte) int {
+ return dm_build_224.Dm_build_191(dm_build_225, int32(len(dm_build_226))) + dm_build_224.Dm_build_219(dm_build_225+4, dm_build_226)
+}
+
+func (dm_build_228 *Dm_build_0) Dm_build_227(dm_build_229 int, dm_build_230 []byte) int {
+ return dm_build_228.Dm_build_183(dm_build_229, byte(len(dm_build_230))) + dm_build_228.Dm_build_219(dm_build_229+1, dm_build_230)
+}
+
+func (dm_build_232 *Dm_build_0) Dm_build_231(dm_build_233 int, dm_build_234 []byte) int {
+ return dm_build_232.Dm_build_187(dm_build_233, int16(len(dm_build_234))) + dm_build_232.Dm_build_219(dm_build_233+2, dm_build_234)
+}
+
+func (dm_build_236 *Dm_build_0) Dm_build_235(dm_build_237 int, dm_build_238 []byte) int {
+ return dm_build_236.Dm_build_219(dm_build_237, dm_build_238) + dm_build_236.Dm_build_183(dm_build_237+len(dm_build_238), 0)
+}
+
+func (dm_build_240 *Dm_build_0) Dm_build_239(dm_build_241 int, dm_build_242 string, dm_build_243 string, dm_build_244 *DmConnection) int {
+ return dm_build_240.Dm_build_223(dm_build_241, Dm_build_1220.Dm_build_1433(dm_build_242, dm_build_243, dm_build_244))
+}
+
+func (dm_build_246 *Dm_build_0) Dm_build_245(dm_build_247 int, dm_build_248 string, dm_build_249 string, dm_build_250 *DmConnection) int {
+ return dm_build_246.Dm_build_227(dm_build_247, Dm_build_1220.Dm_build_1433(dm_build_248, dm_build_249, dm_build_250))
+}
+
+func (dm_build_252 *Dm_build_0) Dm_build_251(dm_build_253 int, dm_build_254 string, dm_build_255 string, dm_build_256 *DmConnection) int {
+ return dm_build_252.Dm_build_231(dm_build_253, Dm_build_1220.Dm_build_1433(dm_build_254, dm_build_255, dm_build_256))
+}
+
+func (dm_build_258 *Dm_build_0) Dm_build_257(dm_build_259 int, dm_build_260 string, dm_build_261 string, dm_build_262 *DmConnection) int {
+ return dm_build_258.Dm_build_235(dm_build_259, Dm_build_1220.Dm_build_1433(dm_build_260, dm_build_261, dm_build_262))
+}
+
+func (dm_build_264 *Dm_build_0) Dm_build_263(dm_build_265 int) byte {
+ return Dm_build_1220.Dm_build_1438(dm_build_264.Dm_build_290(dm_build_265, 1))
+}
+
+func (dm_build_267 *Dm_build_0) Dm_build_266(dm_build_268 int) int16 {
+ return Dm_build_1220.Dm_build_1441(dm_build_267.Dm_build_290(dm_build_268, 2))
+}
+
+func (dm_build_270 *Dm_build_0) Dm_build_269(dm_build_271 int) int32 {
+ return Dm_build_1220.Dm_build_1444(dm_build_270.Dm_build_290(dm_build_271, 4))
+}
+
+func (dm_build_273 *Dm_build_0) Dm_build_272(dm_build_274 int) int64 {
+ return Dm_build_1220.Dm_build_1447(dm_build_273.Dm_build_290(dm_build_274, 8))
+}
+
+func (dm_build_276 *Dm_build_0) Dm_build_275(dm_build_277 int) float32 {
+ return Dm_build_1220.Dm_build_1450(dm_build_276.Dm_build_290(dm_build_277, 4))
+}
+
+func (dm_build_279 *Dm_build_0) Dm_build_278(dm_build_280 int) float64 {
+ return Dm_build_1220.Dm_build_1453(dm_build_279.Dm_build_290(dm_build_280, 8))
+}
+
+func (dm_build_282 *Dm_build_0) Dm_build_281(dm_build_283 int) uint8 {
+ return Dm_build_1220.Dm_build_1456(dm_build_282.Dm_build_290(dm_build_283, 1))
+}
+
+func (dm_build_285 *Dm_build_0) Dm_build_284(dm_build_286 int) uint16 {
+ return Dm_build_1220.Dm_build_1459(dm_build_285.Dm_build_290(dm_build_286, 2))
+}
+
+func (dm_build_288 *Dm_build_0) Dm_build_287(dm_build_289 int) uint32 {
+ return Dm_build_1220.Dm_build_1462(dm_build_288.Dm_build_290(dm_build_289, 4))
+}
+
+func (dm_build_291 *Dm_build_0) Dm_build_290(dm_build_292 int, dm_build_293 int) []byte {
+ return dm_build_291.dm_build_1[dm_build_292 : dm_build_292+dm_build_293]
+}
+
+func (dm_build_295 *Dm_build_0) Dm_build_294(dm_build_296 int) []byte {
+ dm_build_297 := dm_build_295.Dm_build_269(dm_build_296)
+ return dm_build_295.Dm_build_290(dm_build_296+4, int(dm_build_297))
+}
+
+func (dm_build_299 *Dm_build_0) Dm_build_298(dm_build_300 int) []byte {
+ dm_build_301 := dm_build_299.Dm_build_263(dm_build_300)
+ return dm_build_299.Dm_build_290(dm_build_300+1, int(dm_build_301))
+}
+
+func (dm_build_303 *Dm_build_0) Dm_build_302(dm_build_304 int) []byte {
+ dm_build_305 := dm_build_303.Dm_build_266(dm_build_304)
+ return dm_build_303.Dm_build_290(dm_build_304+2, int(dm_build_305))
+}
+
+func (dm_build_307 *Dm_build_0) Dm_build_306(dm_build_308 int) []byte {
+ dm_build_309 := 0
+ for dm_build_307.Dm_build_263(dm_build_308) != 0 {
+ dm_build_308++
+ dm_build_309++
+ }
+
+ return dm_build_307.Dm_build_290(dm_build_308-dm_build_309, int(dm_build_309))
+}
+
+func (dm_build_311 *Dm_build_0) Dm_build_310(dm_build_312 int, dm_build_313 string, dm_build_314 *DmConnection) string {
+ return Dm_build_1220.Dm_build_1470(dm_build_311.Dm_build_294(dm_build_312), dm_build_313, dm_build_314)
+}
+
+func (dm_build_316 *Dm_build_0) Dm_build_315(dm_build_317 int, dm_build_318 string, dm_build_319 *DmConnection) string {
+ return Dm_build_1220.Dm_build_1470(dm_build_316.Dm_build_298(dm_build_317), dm_build_318, dm_build_319)
+}
+
+func (dm_build_321 *Dm_build_0) Dm_build_320(dm_build_322 int, dm_build_323 string, dm_build_324 *DmConnection) string {
+ return Dm_build_1220.Dm_build_1470(dm_build_321.Dm_build_302(dm_build_322), dm_build_323, dm_build_324)
+}
+
+func (dm_build_326 *Dm_build_0) Dm_build_325(dm_build_327 int, dm_build_328 string, dm_build_329 *DmConnection) string {
+ return Dm_build_1220.Dm_build_1470(dm_build_326.Dm_build_306(dm_build_327), dm_build_328, dm_build_329)
+}
diff --git a/dmr/d.go b/dmr/d.go
new file mode 100644
index 0000000..38866c7
--- /dev/null
+++ b/dmr/d.go
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "container/list"
+ "io"
+)
+
+type Dm_build_1499 struct {
+ dm_build_1500 *list.List
+ dm_build_1501 *dm_build_1553
+ dm_build_1502 int
+}
+
+func Dm_build_1503() *Dm_build_1499 {
+ return &Dm_build_1499{
+ dm_build_1500: list.New(),
+ dm_build_1502: 0,
+ }
+}
+
+func (dm_build_1505 *Dm_build_1499) Dm_build_1504() int {
+ return dm_build_1505.dm_build_1502
+}
+
+func (dm_build_1507 *Dm_build_1499) Dm_build_1506(dm_build_1508 *Dm_build_0, dm_build_1509 int) int {
+ var dm_build_1510 = 0
+ var dm_build_1511 = 0
+ for dm_build_1510 < dm_build_1509 && dm_build_1507.dm_build_1501 != nil {
+ dm_build_1511 = dm_build_1507.dm_build_1501.dm_build_1561(dm_build_1508, dm_build_1509-dm_build_1510)
+ if dm_build_1507.dm_build_1501.dm_build_1556 == 0 {
+ dm_build_1507.dm_build_1543()
+ }
+ dm_build_1510 += dm_build_1511
+ dm_build_1507.dm_build_1502 -= dm_build_1511
+ }
+ return dm_build_1510
+}
+
+func (dm_build_1513 *Dm_build_1499) Dm_build_1512(dm_build_1514 []byte, dm_build_1515 int, dm_build_1516 int) int {
+ var dm_build_1517 = 0
+ var dm_build_1518 = 0
+ for dm_build_1517 < dm_build_1516 && dm_build_1513.dm_build_1501 != nil {
+ dm_build_1518 = dm_build_1513.dm_build_1501.dm_build_1565(dm_build_1514, dm_build_1515, dm_build_1516-dm_build_1517)
+ if dm_build_1513.dm_build_1501.dm_build_1556 == 0 {
+ dm_build_1513.dm_build_1543()
+ }
+ dm_build_1517 += dm_build_1518
+ dm_build_1513.dm_build_1502 -= dm_build_1518
+ dm_build_1515 += dm_build_1518
+ }
+ return dm_build_1517
+}
+
+func (dm_build_1520 *Dm_build_1499) Dm_build_1519(dm_build_1521 io.Writer, dm_build_1522 int) int {
+ var dm_build_1523 = 0
+ var dm_build_1524 = 0
+ for dm_build_1523 < dm_build_1522 && dm_build_1520.dm_build_1501 != nil {
+ dm_build_1524 = dm_build_1520.dm_build_1501.dm_build_1570(dm_build_1521, dm_build_1522-dm_build_1523)
+ if dm_build_1520.dm_build_1501.dm_build_1556 == 0 {
+ dm_build_1520.dm_build_1543()
+ }
+ dm_build_1523 += dm_build_1524
+ dm_build_1520.dm_build_1502 -= dm_build_1524
+ }
+ return dm_build_1523
+}
+
+func (dm_build_1526 *Dm_build_1499) Dm_build_1525(dm_build_1527 []byte, dm_build_1528 int, dm_build_1529 int) {
+ if dm_build_1529 == 0 {
+ return
+ }
+ var dm_build_1530 = dm_build_1557(dm_build_1527, dm_build_1528, dm_build_1529)
+ if dm_build_1526.dm_build_1501 == nil {
+ dm_build_1526.dm_build_1501 = dm_build_1530
+ } else {
+ dm_build_1526.dm_build_1500.PushBack(dm_build_1530)
+ }
+ dm_build_1526.dm_build_1502 += dm_build_1529
+}
+
+func (dm_build_1532 *Dm_build_1499) dm_build_1531(dm_build_1533 int) byte {
+ var dm_build_1534 = dm_build_1533
+ var dm_build_1535 = dm_build_1532.dm_build_1501
+ for dm_build_1534 > 0 && dm_build_1535 != nil {
+ if dm_build_1535.dm_build_1556 == 0 {
+ continue
+ }
+ if dm_build_1534 > dm_build_1535.dm_build_1556-1 {
+ dm_build_1534 -= dm_build_1535.dm_build_1556
+ dm_build_1535 = dm_build_1532.dm_build_1500.Front().Value.(*dm_build_1553)
+ } else {
+ break
+ }
+ }
+ return dm_build_1535.dm_build_1574(dm_build_1534)
+}
+func (dm_build_1537 *Dm_build_1499) Dm_build_1536(dm_build_1538 *Dm_build_1499) {
+ if dm_build_1538.dm_build_1502 == 0 {
+ return
+ }
+ var dm_build_1539 = dm_build_1538.dm_build_1501
+ for dm_build_1539 != nil {
+ dm_build_1537.dm_build_1540(dm_build_1539)
+ dm_build_1538.dm_build_1543()
+ dm_build_1539 = dm_build_1538.dm_build_1501
+ }
+ dm_build_1538.dm_build_1502 = 0
+}
+func (dm_build_1541 *Dm_build_1499) dm_build_1540(dm_build_1542 *dm_build_1553) {
+ if dm_build_1542.dm_build_1556 == 0 {
+ return
+ }
+ if dm_build_1541.dm_build_1501 == nil {
+ dm_build_1541.dm_build_1501 = dm_build_1542
+ } else {
+ dm_build_1541.dm_build_1500.PushBack(dm_build_1542)
+ }
+ dm_build_1541.dm_build_1502 += dm_build_1542.dm_build_1556
+}
+
+func (dm_build_1544 *Dm_build_1499) dm_build_1543() {
+ var dm_build_1545 = dm_build_1544.dm_build_1500.Front()
+ if dm_build_1545 == nil {
+ dm_build_1544.dm_build_1501 = nil
+ } else {
+ dm_build_1544.dm_build_1501 = dm_build_1545.Value.(*dm_build_1553)
+ dm_build_1544.dm_build_1500.Remove(dm_build_1545)
+ }
+}
+
+func (dm_build_1547 *Dm_build_1499) Dm_build_1546() []byte {
+ var dm_build_1548 = make([]byte, dm_build_1547.dm_build_1502)
+ var dm_build_1549 = dm_build_1547.dm_build_1501
+ var dm_build_1550 = 0
+ var dm_build_1551 = len(dm_build_1548)
+ var dm_build_1552 = 0
+ for dm_build_1549 != nil {
+ if dm_build_1549.dm_build_1556 > 0 {
+ if dm_build_1551 > dm_build_1549.dm_build_1556 {
+ dm_build_1552 = dm_build_1549.dm_build_1556
+ } else {
+ dm_build_1552 = dm_build_1551
+ }
+ copy(dm_build_1548[dm_build_1550:dm_build_1550+dm_build_1552], dm_build_1549.dm_build_1554[dm_build_1549.dm_build_1555:dm_build_1549.dm_build_1555+dm_build_1552])
+ dm_build_1550 += dm_build_1552
+ dm_build_1551 -= dm_build_1552
+ }
+ if dm_build_1547.dm_build_1500.Front() == nil {
+ dm_build_1549 = nil
+ } else {
+ dm_build_1549 = dm_build_1547.dm_build_1500.Front().Value.(*dm_build_1553)
+ }
+ }
+ return dm_build_1548
+}
+
+type dm_build_1553 struct {
+ dm_build_1554 []byte
+ dm_build_1555 int
+ dm_build_1556 int
+}
+
+func dm_build_1557(dm_build_1558 []byte, dm_build_1559 int, dm_build_1560 int) *dm_build_1553 {
+ return &dm_build_1553{
+ dm_build_1558,
+ dm_build_1559,
+ dm_build_1560,
+ }
+}
+
+func (dm_build_1562 *dm_build_1553) dm_build_1561(dm_build_1563 *Dm_build_0, dm_build_1564 int) int {
+ if dm_build_1562.dm_build_1556 <= dm_build_1564 {
+ dm_build_1564 = dm_build_1562.dm_build_1556
+ }
+ dm_build_1563.Dm_build_79(dm_build_1562.dm_build_1554[dm_build_1562.dm_build_1555 : dm_build_1562.dm_build_1555+dm_build_1564])
+ dm_build_1562.dm_build_1555 += dm_build_1564
+ dm_build_1562.dm_build_1556 -= dm_build_1564
+ return dm_build_1564
+}
+
+func (dm_build_1566 *dm_build_1553) dm_build_1565(dm_build_1567 []byte, dm_build_1568 int, dm_build_1569 int) int {
+ if dm_build_1566.dm_build_1556 <= dm_build_1569 {
+ dm_build_1569 = dm_build_1566.dm_build_1556
+ }
+ copy(dm_build_1567[dm_build_1568:dm_build_1568+dm_build_1569], dm_build_1566.dm_build_1554[dm_build_1566.dm_build_1555:dm_build_1566.dm_build_1555+dm_build_1569])
+ dm_build_1566.dm_build_1555 += dm_build_1569
+ dm_build_1566.dm_build_1556 -= dm_build_1569
+ return dm_build_1569
+}
+
+func (dm_build_1571 *dm_build_1553) dm_build_1570(dm_build_1572 io.Writer, dm_build_1573 int) int {
+ if dm_build_1571.dm_build_1556 <= dm_build_1573 {
+ dm_build_1573 = dm_build_1571.dm_build_1556
+ }
+ dm_build_1572.Write(dm_build_1571.dm_build_1554[dm_build_1571.dm_build_1555 : dm_build_1571.dm_build_1555+dm_build_1573])
+ dm_build_1571.dm_build_1555 += dm_build_1573
+ dm_build_1571.dm_build_1556 -= dm_build_1573
+ return dm_build_1573
+}
+func (dm_build_1575 *dm_build_1553) dm_build_1574(dm_build_1576 int) byte {
+ return dm_build_1575.dm_build_1554[dm_build_1575.dm_build_1555+dm_build_1576]
+}
diff --git a/dmr/e.go b/dmr/e.go
new file mode 100644
index 0000000..eb3b84a
--- /dev/null
+++ b/dmr/e.go
@@ -0,0 +1,543 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "bytes"
+ "golang.org/x/text/encoding"
+ "golang.org/x/text/encoding/ianaindex"
+ "golang.org/x/text/transform"
+ "io"
+ "io/ioutil"
+ "math"
+)
+
+type dm_build_1219 struct{}
+
+var Dm_build_1220 = &dm_build_1219{}
+
+func (Dm_build_1222 *dm_build_1219) Dm_build_1221(dm_build_1223 []byte, dm_build_1224 int, dm_build_1225 byte) int {
+ dm_build_1223[dm_build_1224] = dm_build_1225
+ return 1
+}
+
+func (Dm_build_1227 *dm_build_1219) Dm_build_1226(dm_build_1228 []byte, dm_build_1229 int, dm_build_1230 int8) int {
+ dm_build_1228[dm_build_1229] = byte(dm_build_1230)
+ return 1
+}
+
+func (Dm_build_1232 *dm_build_1219) Dm_build_1231(dm_build_1233 []byte, dm_build_1234 int, dm_build_1235 int16) int {
+ dm_build_1233[dm_build_1234] = byte(dm_build_1235)
+ dm_build_1234++
+ dm_build_1233[dm_build_1234] = byte(dm_build_1235 >> 8)
+ return 2
+}
+
+func (Dm_build_1237 *dm_build_1219) Dm_build_1236(dm_build_1238 []byte, dm_build_1239 int, dm_build_1240 int32) int {
+ dm_build_1238[dm_build_1239] = byte(dm_build_1240)
+ dm_build_1239++
+ dm_build_1238[dm_build_1239] = byte(dm_build_1240 >> 8)
+ dm_build_1239++
+ dm_build_1238[dm_build_1239] = byte(dm_build_1240 >> 16)
+ dm_build_1239++
+ dm_build_1238[dm_build_1239] = byte(dm_build_1240 >> 24)
+ dm_build_1239++
+ return 4
+}
+
+func (Dm_build_1242 *dm_build_1219) Dm_build_1241(dm_build_1243 []byte, dm_build_1244 int, dm_build_1245 int64) int {
+ dm_build_1243[dm_build_1244] = byte(dm_build_1245)
+ dm_build_1244++
+ dm_build_1243[dm_build_1244] = byte(dm_build_1245 >> 8)
+ dm_build_1244++
+ dm_build_1243[dm_build_1244] = byte(dm_build_1245 >> 16)
+ dm_build_1244++
+ dm_build_1243[dm_build_1244] = byte(dm_build_1245 >> 24)
+ dm_build_1244++
+ dm_build_1243[dm_build_1244] = byte(dm_build_1245 >> 32)
+ dm_build_1244++
+ dm_build_1243[dm_build_1244] = byte(dm_build_1245 >> 40)
+ dm_build_1244++
+ dm_build_1243[dm_build_1244] = byte(dm_build_1245 >> 48)
+ dm_build_1244++
+ dm_build_1243[dm_build_1244] = byte(dm_build_1245 >> 56)
+ return 8
+}
+
+func (Dm_build_1247 *dm_build_1219) Dm_build_1246(dm_build_1248 []byte, dm_build_1249 int, dm_build_1250 float32) int {
+ return Dm_build_1247.Dm_build_1266(dm_build_1248, dm_build_1249, math.Float32bits(dm_build_1250))
+}
+
+func (Dm_build_1252 *dm_build_1219) Dm_build_1251(dm_build_1253 []byte, dm_build_1254 int, dm_build_1255 float64) int {
+ return Dm_build_1252.Dm_build_1271(dm_build_1253, dm_build_1254, math.Float64bits(dm_build_1255))
+}
+
+func (Dm_build_1257 *dm_build_1219) Dm_build_1256(dm_build_1258 []byte, dm_build_1259 int, dm_build_1260 uint8) int {
+ dm_build_1258[dm_build_1259] = byte(dm_build_1260)
+ return 1
+}
+
+func (Dm_build_1262 *dm_build_1219) Dm_build_1261(dm_build_1263 []byte, dm_build_1264 int, dm_build_1265 uint16) int {
+ dm_build_1263[dm_build_1264] = byte(dm_build_1265)
+ dm_build_1264++
+ dm_build_1263[dm_build_1264] = byte(dm_build_1265 >> 8)
+ return 2
+}
+
+func (Dm_build_1267 *dm_build_1219) Dm_build_1266(dm_build_1268 []byte, dm_build_1269 int, dm_build_1270 uint32) int {
+ dm_build_1268[dm_build_1269] = byte(dm_build_1270)
+ dm_build_1269++
+ dm_build_1268[dm_build_1269] = byte(dm_build_1270 >> 8)
+ dm_build_1269++
+ dm_build_1268[dm_build_1269] = byte(dm_build_1270 >> 16)
+ dm_build_1269++
+ dm_build_1268[dm_build_1269] = byte(dm_build_1270 >> 24)
+ return 3
+}
+
+func (Dm_build_1272 *dm_build_1219) Dm_build_1271(dm_build_1273 []byte, dm_build_1274 int, dm_build_1275 uint64) int {
+ dm_build_1273[dm_build_1274] = byte(dm_build_1275)
+ dm_build_1274++
+ dm_build_1273[dm_build_1274] = byte(dm_build_1275 >> 8)
+ dm_build_1274++
+ dm_build_1273[dm_build_1274] = byte(dm_build_1275 >> 16)
+ dm_build_1274++
+ dm_build_1273[dm_build_1274] = byte(dm_build_1275 >> 24)
+ dm_build_1274++
+ dm_build_1273[dm_build_1274] = byte(dm_build_1275 >> 32)
+ dm_build_1274++
+ dm_build_1273[dm_build_1274] = byte(dm_build_1275 >> 40)
+ dm_build_1274++
+ dm_build_1273[dm_build_1274] = byte(dm_build_1275 >> 48)
+ dm_build_1274++
+ dm_build_1273[dm_build_1274] = byte(dm_build_1275 >> 56)
+ return 3
+}
+
+func (Dm_build_1277 *dm_build_1219) Dm_build_1276(dm_build_1278 []byte, dm_build_1279 int, dm_build_1280 []byte, dm_build_1281 int, dm_build_1282 int) int {
+ copy(dm_build_1278[dm_build_1279:dm_build_1279+dm_build_1282], dm_build_1280[dm_build_1281:dm_build_1281+dm_build_1282])
+ return dm_build_1282
+}
+
+func (Dm_build_1284 *dm_build_1219) Dm_build_1283(dm_build_1285 []byte, dm_build_1286 int, dm_build_1287 []byte, dm_build_1288 int, dm_build_1289 int) int {
+ dm_build_1286 += Dm_build_1284.Dm_build_1266(dm_build_1285, dm_build_1286, uint32(dm_build_1289))
+ return 4 + Dm_build_1284.Dm_build_1276(dm_build_1285, dm_build_1286, dm_build_1287, dm_build_1288, dm_build_1289)
+}
+
+func (Dm_build_1291 *dm_build_1219) Dm_build_1290(dm_build_1292 []byte, dm_build_1293 int, dm_build_1294 []byte, dm_build_1295 int, dm_build_1296 int) int {
+ dm_build_1293 += Dm_build_1291.Dm_build_1261(dm_build_1292, dm_build_1293, uint16(dm_build_1296))
+ return 2 + Dm_build_1291.Dm_build_1276(dm_build_1292, dm_build_1293, dm_build_1294, dm_build_1295, dm_build_1296)
+}
+
+func (Dm_build_1298 *dm_build_1219) Dm_build_1297(dm_build_1299 []byte, dm_build_1300 int, dm_build_1301 string, dm_build_1302 string, dm_build_1303 *DmConnection) int {
+ dm_build_1304 := Dm_build_1298.Dm_build_1433(dm_build_1301, dm_build_1302, dm_build_1303)
+ dm_build_1300 += Dm_build_1298.Dm_build_1266(dm_build_1299, dm_build_1300, uint32(len(dm_build_1304)))
+ return 4 + Dm_build_1298.Dm_build_1276(dm_build_1299, dm_build_1300, dm_build_1304, 0, len(dm_build_1304))
+}
+
+func (Dm_build_1306 *dm_build_1219) Dm_build_1305(dm_build_1307 []byte, dm_build_1308 int, dm_build_1309 string, dm_build_1310 string, dm_build_1311 *DmConnection) int {
+ dm_build_1312 := Dm_build_1306.Dm_build_1433(dm_build_1309, dm_build_1310, dm_build_1311)
+
+ dm_build_1308 += Dm_build_1306.Dm_build_1261(dm_build_1307, dm_build_1308, uint16(len(dm_build_1312)))
+ return 2 + Dm_build_1306.Dm_build_1276(dm_build_1307, dm_build_1308, dm_build_1312, 0, len(dm_build_1312))
+}
+
+func (Dm_build_1314 *dm_build_1219) Dm_build_1313(dm_build_1315 []byte, dm_build_1316 int) byte {
+ return dm_build_1315[dm_build_1316]
+}
+
+func (Dm_build_1318 *dm_build_1219) Dm_build_1317(dm_build_1319 []byte, dm_build_1320 int) int16 {
+ var dm_build_1321 int16
+ dm_build_1321 = int16(dm_build_1319[dm_build_1320] & 0xff)
+ dm_build_1320++
+ dm_build_1321 |= int16(dm_build_1319[dm_build_1320]&0xff) << 8
+ return dm_build_1321
+}
+
+func (Dm_build_1323 *dm_build_1219) Dm_build_1322(dm_build_1324 []byte, dm_build_1325 int) int32 {
+ var dm_build_1326 int32
+ dm_build_1326 = int32(dm_build_1324[dm_build_1325] & 0xff)
+ dm_build_1325++
+ dm_build_1326 |= int32(dm_build_1324[dm_build_1325]&0xff) << 8
+ dm_build_1325++
+ dm_build_1326 |= int32(dm_build_1324[dm_build_1325]&0xff) << 16
+ dm_build_1325++
+ dm_build_1326 |= int32(dm_build_1324[dm_build_1325]&0xff) << 24
+ return dm_build_1326
+}
+
+func (Dm_build_1328 *dm_build_1219) Dm_build_1327(dm_build_1329 []byte, dm_build_1330 int) int64 {
+ var dm_build_1331 int64
+ dm_build_1331 = int64(dm_build_1329[dm_build_1330] & 0xff)
+ dm_build_1330++
+ dm_build_1331 |= int64(dm_build_1329[dm_build_1330]&0xff) << 8
+ dm_build_1330++
+ dm_build_1331 |= int64(dm_build_1329[dm_build_1330]&0xff) << 16
+ dm_build_1330++
+ dm_build_1331 |= int64(dm_build_1329[dm_build_1330]&0xff) << 24
+ dm_build_1330++
+ dm_build_1331 |= int64(dm_build_1329[dm_build_1330]&0xff) << 32
+ dm_build_1330++
+ dm_build_1331 |= int64(dm_build_1329[dm_build_1330]&0xff) << 40
+ dm_build_1330++
+ dm_build_1331 |= int64(dm_build_1329[dm_build_1330]&0xff) << 48
+ dm_build_1330++
+ dm_build_1331 |= int64(dm_build_1329[dm_build_1330]&0xff) << 56
+ return dm_build_1331
+}
+
+func (Dm_build_1333 *dm_build_1219) Dm_build_1332(dm_build_1334 []byte, dm_build_1335 int) float32 {
+ return math.Float32frombits(Dm_build_1333.Dm_build_1349(dm_build_1334, dm_build_1335))
+}
+
+func (Dm_build_1337 *dm_build_1219) Dm_build_1336(dm_build_1338 []byte, dm_build_1339 int) float64 {
+ return math.Float64frombits(Dm_build_1337.Dm_build_1354(dm_build_1338, dm_build_1339))
+}
+
+func (Dm_build_1341 *dm_build_1219) Dm_build_1340(dm_build_1342 []byte, dm_build_1343 int) uint8 {
+ return uint8(dm_build_1342[dm_build_1343] & 0xff)
+}
+
+func (Dm_build_1345 *dm_build_1219) Dm_build_1344(dm_build_1346 []byte, dm_build_1347 int) uint16 {
+ var dm_build_1348 uint16
+ dm_build_1348 = uint16(dm_build_1346[dm_build_1347] & 0xff)
+ dm_build_1347++
+ dm_build_1348 |= uint16(dm_build_1346[dm_build_1347]&0xff) << 8
+ return dm_build_1348
+}
+
+func (Dm_build_1350 *dm_build_1219) Dm_build_1349(dm_build_1351 []byte, dm_build_1352 int) uint32 {
+ var dm_build_1353 uint32
+ dm_build_1353 = uint32(dm_build_1351[dm_build_1352] & 0xff)
+ dm_build_1352++
+ dm_build_1353 |= uint32(dm_build_1351[dm_build_1352]&0xff) << 8
+ dm_build_1352++
+ dm_build_1353 |= uint32(dm_build_1351[dm_build_1352]&0xff) << 16
+ dm_build_1352++
+ dm_build_1353 |= uint32(dm_build_1351[dm_build_1352]&0xff) << 24
+ return dm_build_1353
+}
+
+func (Dm_build_1355 *dm_build_1219) Dm_build_1354(dm_build_1356 []byte, dm_build_1357 int) uint64 {
+ var dm_build_1358 uint64
+ dm_build_1358 = uint64(dm_build_1356[dm_build_1357] & 0xff)
+ dm_build_1357++
+ dm_build_1358 |= uint64(dm_build_1356[dm_build_1357]&0xff) << 8
+ dm_build_1357++
+ dm_build_1358 |= uint64(dm_build_1356[dm_build_1357]&0xff) << 16
+ dm_build_1357++
+ dm_build_1358 |= uint64(dm_build_1356[dm_build_1357]&0xff) << 24
+ dm_build_1357++
+ dm_build_1358 |= uint64(dm_build_1356[dm_build_1357]&0xff) << 32
+ dm_build_1357++
+ dm_build_1358 |= uint64(dm_build_1356[dm_build_1357]&0xff) << 40
+ dm_build_1357++
+ dm_build_1358 |= uint64(dm_build_1356[dm_build_1357]&0xff) << 48
+ dm_build_1357++
+ dm_build_1358 |= uint64(dm_build_1356[dm_build_1357]&0xff) << 56
+ return dm_build_1358
+}
+
+func (Dm_build_1360 *dm_build_1219) Dm_build_1359(dm_build_1361 []byte, dm_build_1362 int) []byte {
+ dm_build_1363 := Dm_build_1360.Dm_build_1349(dm_build_1361, dm_build_1362)
+
+ dm_build_1364 := make([]byte, dm_build_1363)
+ copy(dm_build_1364[:int(dm_build_1363)], dm_build_1361[dm_build_1362+4:dm_build_1362+4+int(dm_build_1363)])
+ return dm_build_1364
+}
+
+func (Dm_build_1366 *dm_build_1219) Dm_build_1365(dm_build_1367 []byte, dm_build_1368 int) []byte {
+ dm_build_1369 := Dm_build_1366.Dm_build_1344(dm_build_1367, dm_build_1368)
+
+ dm_build_1370 := make([]byte, dm_build_1369)
+ copy(dm_build_1370[:int(dm_build_1369)], dm_build_1367[dm_build_1368+2:dm_build_1368+2+int(dm_build_1369)])
+ return dm_build_1370
+}
+
+func (Dm_build_1372 *dm_build_1219) Dm_build_1371(dm_build_1373 []byte, dm_build_1374 int, dm_build_1375 int) []byte {
+
+ dm_build_1376 := make([]byte, dm_build_1375)
+ copy(dm_build_1376[:dm_build_1375], dm_build_1373[dm_build_1374:dm_build_1374+dm_build_1375])
+ return dm_build_1376
+}
+
+func (Dm_build_1378 *dm_build_1219) Dm_build_1377(dm_build_1379 []byte, dm_build_1380 int, dm_build_1381 int, dm_build_1382 string, dm_build_1383 *DmConnection) string {
+ return Dm_build_1378.Dm_build_1470(dm_build_1379[dm_build_1380:dm_build_1380+dm_build_1381], dm_build_1382, dm_build_1383)
+}
+
+func (Dm_build_1385 *dm_build_1219) Dm_build_1384(dm_build_1386 []byte, dm_build_1387 int, dm_build_1388 string, dm_build_1389 *DmConnection) string {
+ dm_build_1390 := Dm_build_1385.Dm_build_1349(dm_build_1386, dm_build_1387)
+ dm_build_1387 += 4
+ return Dm_build_1385.Dm_build_1377(dm_build_1386, dm_build_1387, int(dm_build_1390), dm_build_1388, dm_build_1389)
+}
+
+func (Dm_build_1392 *dm_build_1219) Dm_build_1391(dm_build_1393 []byte, dm_build_1394 int, dm_build_1395 string, dm_build_1396 *DmConnection) string {
+ dm_build_1397 := Dm_build_1392.Dm_build_1344(dm_build_1393, dm_build_1394)
+ dm_build_1394 += 2
+ return Dm_build_1392.Dm_build_1377(dm_build_1393, dm_build_1394, int(dm_build_1397), dm_build_1395, dm_build_1396)
+}
+
+func (Dm_build_1399 *dm_build_1219) Dm_build_1398(dm_build_1400 byte) []byte {
+ return []byte{dm_build_1400}
+}
+
+func (Dm_build_1402 *dm_build_1219) Dm_build_1401(dm_build_1403 int16) []byte {
+ return []byte{byte(dm_build_1403), byte(dm_build_1403 >> 8)}
+}
+
+func (Dm_build_1405 *dm_build_1219) Dm_build_1404(dm_build_1406 int32) []byte {
+ return []byte{byte(dm_build_1406), byte(dm_build_1406 >> 8), byte(dm_build_1406 >> 16), byte(dm_build_1406 >> 24)}
+}
+
+func (Dm_build_1408 *dm_build_1219) Dm_build_1407(dm_build_1409 int64) []byte {
+ return []byte{byte(dm_build_1409), byte(dm_build_1409 >> 8), byte(dm_build_1409 >> 16), byte(dm_build_1409 >> 24), byte(dm_build_1409 >> 32),
+ byte(dm_build_1409 >> 40), byte(dm_build_1409 >> 48), byte(dm_build_1409 >> 56)}
+}
+
+func (Dm_build_1411 *dm_build_1219) Dm_build_1410(dm_build_1412 float32) []byte {
+ return Dm_build_1411.Dm_build_1422(math.Float32bits(dm_build_1412))
+}
+
+func (Dm_build_1414 *dm_build_1219) Dm_build_1413(dm_build_1415 float64) []byte {
+ return Dm_build_1414.Dm_build_1425(math.Float64bits(dm_build_1415))
+}
+
+func (Dm_build_1417 *dm_build_1219) Dm_build_1416(dm_build_1418 uint8) []byte {
+ return []byte{byte(dm_build_1418)}
+}
+
+func (Dm_build_1420 *dm_build_1219) Dm_build_1419(dm_build_1421 uint16) []byte {
+ return []byte{byte(dm_build_1421), byte(dm_build_1421 >> 8)}
+}
+
+func (Dm_build_1423 *dm_build_1219) Dm_build_1422(dm_build_1424 uint32) []byte {
+ return []byte{byte(dm_build_1424), byte(dm_build_1424 >> 8), byte(dm_build_1424 >> 16), byte(dm_build_1424 >> 24)}
+}
+
+func (Dm_build_1426 *dm_build_1219) Dm_build_1425(dm_build_1427 uint64) []byte {
+ return []byte{byte(dm_build_1427), byte(dm_build_1427 >> 8), byte(dm_build_1427 >> 16), byte(dm_build_1427 >> 24), byte(dm_build_1427 >> 32), byte(dm_build_1427 >> 40), byte(dm_build_1427 >> 48), byte(dm_build_1427 >> 56)}
+}
+
+func (Dm_build_1429 *dm_build_1219) Dm_build_1428(dm_build_1430 []byte, dm_build_1431 string, dm_build_1432 *DmConnection) []byte {
+ if dm_build_1431 == "UTF-8" {
+ return dm_build_1430
+ }
+
+ if dm_build_1432 == nil {
+ if e := dm_build_1475(dm_build_1431); e != nil {
+ tmp, err := ioutil.ReadAll(
+ transform.NewReader(bytes.NewReader(dm_build_1430), e.NewEncoder()),
+ )
+ if err != nil {
+ panic("UTF8 To Charset error!")
+ }
+
+ return tmp
+ }
+
+ panic("Unsupported Charset!")
+ }
+
+ if dm_build_1432.encodeBuffer == nil {
+ dm_build_1432.encodeBuffer = bytes.NewBuffer(nil)
+ dm_build_1432.encode = dm_build_1475(dm_build_1432.getServerEncoding())
+ dm_build_1432.transformReaderDst = make([]byte, 4096)
+ dm_build_1432.transformReaderSrc = make([]byte, 4096)
+ }
+
+ if e := dm_build_1432.encode; e != nil {
+
+ dm_build_1432.encodeBuffer.Reset()
+
+ n, err := dm_build_1432.encodeBuffer.ReadFrom(
+ Dm_build_1489(bytes.NewReader(dm_build_1430), e.NewEncoder(), dm_build_1432.transformReaderDst, dm_build_1432.transformReaderSrc),
+ )
+ if err != nil {
+ panic("UTF8 To Charset error!")
+ }
+ var tmp = make([]byte, n)
+ if _, err = dm_build_1432.encodeBuffer.Read(tmp); err != nil {
+ panic("UTF8 To Charset error!")
+ }
+ return tmp
+ }
+
+ panic("Unsupported Charset!")
+}
+
+func (Dm_build_1434 *dm_build_1219) Dm_build_1433(dm_build_1435 string, dm_build_1436 string, dm_build_1437 *DmConnection) []byte {
+ return Dm_build_1434.Dm_build_1428([]byte(dm_build_1435), dm_build_1436, dm_build_1437)
+}
+
+func (Dm_build_1439 *dm_build_1219) Dm_build_1438(dm_build_1440 []byte) byte {
+ return Dm_build_1439.Dm_build_1313(dm_build_1440, 0)
+}
+
+func (Dm_build_1442 *dm_build_1219) Dm_build_1441(dm_build_1443 []byte) int16 {
+ return Dm_build_1442.Dm_build_1317(dm_build_1443, 0)
+}
+
+func (Dm_build_1445 *dm_build_1219) Dm_build_1444(dm_build_1446 []byte) int32 {
+ return Dm_build_1445.Dm_build_1322(dm_build_1446, 0)
+}
+
+func (Dm_build_1448 *dm_build_1219) Dm_build_1447(dm_build_1449 []byte) int64 {
+ return Dm_build_1448.Dm_build_1327(dm_build_1449, 0)
+}
+
+func (Dm_build_1451 *dm_build_1219) Dm_build_1450(dm_build_1452 []byte) float32 {
+ return Dm_build_1451.Dm_build_1332(dm_build_1452, 0)
+}
+
+func (Dm_build_1454 *dm_build_1219) Dm_build_1453(dm_build_1455 []byte) float64 {
+ return Dm_build_1454.Dm_build_1336(dm_build_1455, 0)
+}
+
+func (Dm_build_1457 *dm_build_1219) Dm_build_1456(dm_build_1458 []byte) uint8 {
+ return Dm_build_1457.Dm_build_1340(dm_build_1458, 0)
+}
+
+func (Dm_build_1460 *dm_build_1219) Dm_build_1459(dm_build_1461 []byte) uint16 {
+ return Dm_build_1460.Dm_build_1344(dm_build_1461, 0)
+}
+
+func (Dm_build_1463 *dm_build_1219) Dm_build_1462(dm_build_1464 []byte) uint32 {
+ return Dm_build_1463.Dm_build_1349(dm_build_1464, 0)
+}
+
+func (Dm_build_1466 *dm_build_1219) Dm_build_1465(dm_build_1467 []byte, dm_build_1468 string, dm_build_1469 *DmConnection) []byte {
+ if dm_build_1468 == "UTF-8" {
+ return dm_build_1467
+ }
+
+ if dm_build_1469 == nil {
+ if e := dm_build_1475(dm_build_1468); e != nil {
+
+ tmp, err := ioutil.ReadAll(
+ transform.NewReader(bytes.NewReader(dm_build_1467), e.NewDecoder()),
+ )
+ if err != nil {
+
+ panic("Charset To UTF8 error!")
+ }
+
+ return tmp
+ }
+
+ panic("Unsupported Charset!")
+ }
+
+ if dm_build_1469.encodeBuffer == nil {
+ dm_build_1469.encodeBuffer = bytes.NewBuffer(nil)
+ dm_build_1469.encode = dm_build_1475(dm_build_1469.getServerEncoding())
+ dm_build_1469.transformReaderDst = make([]byte, 4096)
+ dm_build_1469.transformReaderSrc = make([]byte, 4096)
+ }
+
+ if e := dm_build_1469.encode; e != nil {
+
+ dm_build_1469.encodeBuffer.Reset()
+
+ n, err := dm_build_1469.encodeBuffer.ReadFrom(
+ Dm_build_1489(bytes.NewReader(dm_build_1467), e.NewDecoder(), dm_build_1469.transformReaderDst, dm_build_1469.transformReaderSrc),
+ )
+ if err != nil {
+
+ panic("Charset To UTF8 error!")
+ }
+
+ return dm_build_1469.encodeBuffer.Next(int(n))
+ }
+
+ panic("Unsupported Charset!")
+}
+
+func (Dm_build_1471 *dm_build_1219) Dm_build_1470(dm_build_1472 []byte, dm_build_1473 string, dm_build_1474 *DmConnection) string {
+ return string(Dm_build_1471.Dm_build_1465(dm_build_1472, dm_build_1473, dm_build_1474))
+}
+
+func dm_build_1475(dm_build_1476 string) encoding.Encoding {
+ if e, err := ianaindex.MIB.Encoding(dm_build_1476); err == nil && e != nil {
+ return e
+ }
+ return nil
+}
+
+type Dm_build_1477 struct {
+ dm_build_1478 io.Reader
+ dm_build_1479 transform.Transformer
+ dm_build_1480 error
+
+ dm_build_1481 []byte
+ dm_build_1482, dm_build_1483 int
+
+ dm_build_1484 []byte
+ dm_build_1485, dm_build_1486 int
+
+ dm_build_1487 bool
+}
+
+const dm_build_1488 = 4096
+
+func Dm_build_1489(dm_build_1490 io.Reader, dm_build_1491 transform.Transformer, dm_build_1492 []byte, dm_build_1493 []byte) *Dm_build_1477 {
+ dm_build_1491.Reset()
+ return &Dm_build_1477{
+ dm_build_1478: dm_build_1490,
+ dm_build_1479: dm_build_1491,
+ dm_build_1481: dm_build_1492,
+ dm_build_1484: dm_build_1493,
+ }
+}
+
+func (dm_build_1495 *Dm_build_1477) Read(dm_build_1496 []byte) (int, error) {
+ dm_build_1497, dm_build_1498 := 0, error(nil)
+ for {
+
+ if dm_build_1495.dm_build_1482 != dm_build_1495.dm_build_1483 {
+ dm_build_1497 = copy(dm_build_1496, dm_build_1495.dm_build_1481[dm_build_1495.dm_build_1482:dm_build_1495.dm_build_1483])
+ dm_build_1495.dm_build_1482 += dm_build_1497
+ if dm_build_1495.dm_build_1482 == dm_build_1495.dm_build_1483 && dm_build_1495.dm_build_1487 {
+ return dm_build_1497, dm_build_1495.dm_build_1480
+ }
+ return dm_build_1497, nil
+ } else if dm_build_1495.dm_build_1487 {
+ return 0, dm_build_1495.dm_build_1480
+ }
+
+ if dm_build_1495.dm_build_1485 != dm_build_1495.dm_build_1486 || dm_build_1495.dm_build_1480 != nil {
+ dm_build_1495.dm_build_1482 = 0
+ dm_build_1495.dm_build_1483, dm_build_1497, dm_build_1498 = dm_build_1495.dm_build_1479.Transform(dm_build_1495.dm_build_1481, dm_build_1495.dm_build_1484[dm_build_1495.dm_build_1485:dm_build_1495.dm_build_1486], dm_build_1495.dm_build_1480 == io.EOF)
+ dm_build_1495.dm_build_1485 += dm_build_1497
+
+ switch {
+ case dm_build_1498 == nil:
+ if dm_build_1495.dm_build_1485 != dm_build_1495.dm_build_1486 {
+ dm_build_1495.dm_build_1480 = nil
+ }
+
+ dm_build_1495.dm_build_1487 = dm_build_1495.dm_build_1480 != nil
+ continue
+ case dm_build_1498 == transform.ErrShortDst && (dm_build_1495.dm_build_1483 != 0 || dm_build_1497 != 0):
+
+ continue
+ case dm_build_1498 == transform.ErrShortSrc && dm_build_1495.dm_build_1486-dm_build_1495.dm_build_1485 != len(dm_build_1495.dm_build_1484) && dm_build_1495.dm_build_1480 == nil:
+
+ default:
+ dm_build_1495.dm_build_1487 = true
+
+ if dm_build_1495.dm_build_1480 == nil || dm_build_1495.dm_build_1480 == io.EOF {
+ dm_build_1495.dm_build_1480 = dm_build_1498
+ }
+ continue
+ }
+ }
+
+ if dm_build_1495.dm_build_1485 != 0 {
+ dm_build_1495.dm_build_1485, dm_build_1495.dm_build_1486 = 0, copy(dm_build_1495.dm_build_1484, dm_build_1495.dm_build_1484[dm_build_1495.dm_build_1485:dm_build_1495.dm_build_1486])
+ }
+ dm_build_1497, dm_build_1495.dm_build_1480 = dm_build_1495.dm_build_1478.Read(dm_build_1495.dm_build_1484[dm_build_1495.dm_build_1486:])
+ dm_build_1495.dm_build_1486 += dm_build_1497
+ }
+}
diff --git a/dmr/f.go b/dmr/f.go
new file mode 100644
index 0000000..69912fa
--- /dev/null
+++ b/dmr/f.go
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "bytes"
+ "compress/zlib"
+ "github.com/golang/snappy"
+)
+
+func Compress(srcBuffer *Dm_build_0, offset int, length int, compressID int) ([]byte, error) {
+ if compressID == Dm_build_683 {
+ return snappy.Encode(nil, srcBuffer.Dm_build_290(offset, length)), nil
+ }
+ return GzlibCompress(srcBuffer, offset, length)
+}
+
+func UnCompress(srcBytes []byte, compressID int) ([]byte, error) {
+ if compressID == Dm_build_683 {
+ return snappy.Decode(nil, srcBytes)
+ }
+ return GzlibUncompress(srcBytes)
+}
+
+func GzlibCompress(srcBuffer *Dm_build_0, offset int, length int) ([]byte, error) {
+ var ret bytes.Buffer
+ var w = zlib.NewWriter(&ret)
+ w.Write(srcBuffer.Dm_build_290(offset, length))
+ w.Close()
+ return ret.Bytes(), nil
+}
+
+func GzlibUncompress(srcBytes []byte) ([]byte, error) {
+ var bytesBuf = new(bytes.Buffer)
+ r, err := zlib.NewReader(bytes.NewReader(srcBytes))
+ if err != nil {
+ return nil, err
+ }
+ defer r.Close()
+ _, err = bytesBuf.ReadFrom(r)
+ if err != nil {
+ return nil, err
+ }
+ return bytesBuf.Bytes(), nil
+}
diff --git a/dmr/g.go b/dmr/g.go
new file mode 100644
index 0000000..27d0dd4
--- /dev/null
+++ b/dmr/g.go
@@ -0,0 +1,2155 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "fmt"
+ "math"
+ "os"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+type ExecuteTypeEnum int
+
+const (
+ Execute ExecuteTypeEnum = iota
+ ExecuteQuery
+ ExecuteUpdate
+)
+
+var idGenerator int64 = 0
+
+func generateId() string {
+ return time.Now().String() + strconv.Itoa(int(atomic.AddInt64(&idGenerator, 1)))
+}
+
+func getInt64(counter *int64, reset bool) int64 {
+ if reset {
+ return atomic.SwapInt64(counter, 0)
+ }
+ return atomic.LoadInt64(counter)
+}
+
+type SqlStatValue struct {
+ id string
+
+ sql string
+
+ sqlHash int64
+
+ dataSource string
+
+ dataSourceId string
+
+ executeLastStartTime int64
+
+ executeBatchSizeTotal int64
+
+ executeBatchSizeMax int64
+
+ executeSuccessCount int64
+
+ executeSpanNanoTotal int64
+
+ executeSpanNanoMax int64
+
+ runningCount int64
+
+ concurrentMax int64
+
+ resultSetHoldTimeNano int64
+
+ executeAndResultSetHoldTime int64
+
+ executeNanoSpanMaxOccurTime int64
+
+ executeErrorCount int64
+
+ executeErrorLast error
+
+ executeErrorLastMessage string
+
+ executeErrorLastStackTrace string
+
+ executeErrorLastTime int64
+
+ updateCount int64
+
+ updateCountMax int64
+
+ fetchRowCount int64
+
+ fetchRowCountMax int64
+
+ inTransactionCount int64
+
+ lastSlowParameters string
+
+ clobOpenCount int64
+
+ blobOpenCount int64
+
+ readStringLength int64
+
+ readBytesLength int64
+
+ inputStreamOpenCount int64
+
+ readerOpenCount int64
+
+ histogram_0_1 int64
+
+ histogram_1_10 int64
+
+ histogram_10_100 int64
+
+ histogram_100_1000 int64
+
+ histogram_1000_10000 int64
+
+ histogram_10000_100000 int64
+
+ histogram_100000_1000000 int64
+
+ histogram_1000000_more int64
+
+ executeAndResultHoldTime_0_1 int64
+
+ executeAndResultHoldTime_1_10 int64
+
+ executeAndResultHoldTime_10_100 int64
+
+ executeAndResultHoldTime_100_1000 int64
+
+ executeAndResultHoldTime_1000_10000 int64
+
+ executeAndResultHoldTime_10000_100000 int64
+
+ executeAndResultHoldTime_100000_1000000 int64
+
+ executeAndResultHoldTime_1000000_more int64
+
+ fetchRowCount_0_1 int64
+
+ fetchRowCount_1_10 int64
+
+ fetchRowCount_10_100 int64
+
+ fetchRowCount_100_1000 int64
+
+ fetchRowCount_1000_10000 int64
+
+ fetchRowCount_10000_more int64
+
+ updateCount_0_1 int64
+
+ updateCount_1_10 int64
+
+ updateCount_10_100 int64
+
+ updateCount_100_1000 int64
+
+ updateCount_1000_10000 int64
+
+ updateCount_10000_more int64
+}
+
+func newSqlStatValue() *SqlStatValue {
+ ssv := new(SqlStatValue)
+ return ssv
+}
+
+func (ssv *SqlStatValue) getExecuteHistogram() []int64 {
+ return []int64{
+ ssv.histogram_0_1,
+ ssv.histogram_1_10,
+ ssv.histogram_10_100,
+ ssv.histogram_100_1000,
+ ssv.histogram_1000_10000,
+ ssv.histogram_10000_100000,
+ ssv.histogram_100000_1000000,
+ ssv.histogram_1000000_more,
+ }
+}
+
+func (ssv *SqlStatValue) getExecuteAndResultHoldHistogram() []int64 {
+ return []int64{ssv.executeAndResultHoldTime_0_1,
+ ssv.executeAndResultHoldTime_1_10,
+ ssv.executeAndResultHoldTime_10_100,
+ ssv.executeAndResultHoldTime_100_1000,
+ ssv.executeAndResultHoldTime_1000_10000,
+ ssv.executeAndResultHoldTime_10000_100000,
+ ssv.executeAndResultHoldTime_100000_1000000,
+ ssv.executeAndResultHoldTime_1000000_more,
+ }
+}
+
+func (ssv *SqlStatValue) getFetchRowHistogram() []int64 {
+ return []int64{ssv.fetchRowCount_0_1,
+ ssv.fetchRowCount_1_10,
+ ssv.fetchRowCount_10_100,
+ ssv.fetchRowCount_100_1000,
+ ssv.fetchRowCount_1000_10000,
+ ssv.fetchRowCount_10000_more,
+ }
+}
+
+func (ssv *SqlStatValue) getUpdateHistogram() []int64 {
+ return []int64{ssv.updateCount_0_1,
+ ssv.updateCount_1_10,
+ ssv.updateCount_10_100,
+ ssv.updateCount_100_1000,
+ ssv.updateCount_1000_10000,
+ ssv.updateCount_10000_more,
+ }
+}
+
+func (ssv *SqlStatValue) getExecuteCount() int64 {
+ return ssv.executeErrorCount + ssv.executeSuccessCount
+}
+
+func (ssv *SqlStatValue) getExecuteMillisMax() int64 {
+ return ssv.executeSpanNanoMax / (1000 * 1000)
+}
+
+func (ssv *SqlStatValue) getExecuteMillisTotal() int64 {
+ return ssv.executeSpanNanoTotal / (1000 * 1000)
+}
+
+func (ssv *SqlStatValue) getHistogramValues() []int64 {
+ return []int64{
+
+ ssv.histogram_0_1,
+ ssv.histogram_1_10,
+ ssv.histogram_10_100,
+ ssv.histogram_100_1000,
+ ssv.histogram_1000_10000,
+ ssv.histogram_10000_100000,
+ ssv.histogram_100000_1000000,
+ ssv.histogram_1000000_more,
+ }
+}
+
+func (ssv *SqlStatValue) getFetchRowCountHistogramValues() []int64 {
+ return []int64{
+
+ ssv.fetchRowCount_0_1,
+ ssv.fetchRowCount_1_10,
+ ssv.fetchRowCount_10_100,
+ ssv.fetchRowCount_100_1000,
+ ssv.fetchRowCount_1000_10000,
+ ssv.fetchRowCount_10000_more,
+ }
+}
+
+func (ssv *SqlStatValue) getUpdateCountHistogramValues() []int64 {
+ return []int64{
+
+ ssv.updateCount_0_1,
+ ssv.updateCount_1_10,
+ ssv.updateCount_10_100,
+ ssv.updateCount_100_1000,
+ ssv.updateCount_1000_10000,
+ ssv.updateCount_10000_more,
+ }
+}
+
+func (ssv *SqlStatValue) getExecuteAndResultHoldTimeHistogramValues() []int64 {
+ return []int64{
+
+ ssv.executeAndResultHoldTime_0_1,
+ ssv.executeAndResultHoldTime_1_10,
+ ssv.executeAndResultHoldTime_10_100,
+ ssv.executeAndResultHoldTime_100_1000,
+ ssv.executeAndResultHoldTime_1000_10000,
+ ssv.executeAndResultHoldTime_10000_100000,
+ ssv.executeAndResultHoldTime_100000_1000000,
+ ssv.executeAndResultHoldTime_1000000_more,
+ }
+}
+
+func (ssv *SqlStatValue) getResultSetHoldTimeMilis() int64 {
+ return ssv.resultSetHoldTimeNano / (1000 * 1000)
+}
+
+func (ssv *SqlStatValue) getExecuteAndResultSetHoldTimeMilis() int64 {
+ return ssv.executeAndResultSetHoldTime / (1000 * 1000)
+}
+
+func (ssv *SqlStatValue) getData() map[string]interface{} {
+ m := make(map[string]interface{})
+
+ m[idConstStr] = ssv.id
+ m[dataSourceConstStr] = ssv.dataSource
+ m["DataSourceId"] = ssv.dataSourceId
+ m[sqlConstStr] = ssv.sql
+ m[executeCountConstStr] = ssv.getExecuteCount()
+ m[errorCountConstStr] = ssv.executeErrorCount
+
+ m[totalTimeConstStr] = ssv.getExecuteMillisTotal()
+ m["LastTime"] = ssv.executeLastStartTime
+ m[maxTimespanConstStr] = ssv.getExecuteMillisMax()
+ m["LastError"] = ssv.executeErrorLast
+ m[effectedRowCountConstStr] = ssv.updateCount
+
+ m[fetchRowCountConstStr] = ssv.fetchRowCount
+ m["MaxTimespanOccurTime"] = ssv.executeNanoSpanMaxOccurTime
+ m["BatchSizeMax"] = ssv.executeBatchSizeMax
+ m["BatchSizeTotal"] = ssv.executeBatchSizeTotal
+ m[concurrentMaxConstStr] = ssv.concurrentMax
+
+ m[runningCountConstStr] = ssv.runningCount
+
+ if ssv.executeErrorLastMessage != "" {
+ m["LastErrorMessage"] = ssv.executeErrorLastMessage
+ m["LastErrorStackTrace"] = ssv.executeErrorLastStackTrace
+ m["LastErrorTime"] = ssv.executeErrorLastTime
+ } else {
+ m["LastErrorMessage"] = ""
+ m["LastErrorClass"] = ""
+ m["LastErrorStackTrace"] = ""
+ m["LastErrorTime"] = ""
+ }
+
+ m[urlConstStr] = ""
+ m[inTransactionCountConstStr] = ssv.inTransactionCount
+
+ m["Histogram"] = ssv.getHistogramValues()
+ m["LastSlowParameters"] = ssv.lastSlowParameters
+ m["ResultSetHoldTime"] = ssv.getResultSetHoldTimeMilis()
+ m["ExecuteAndResultSetHoldTime"] = ssv.getExecuteAndResultSetHoldTimeMilis()
+ m[fetchRowCountConstStr] = ssv.getFetchRowCountHistogramValues()
+
+ m[effectedRowCountHistogramConstStr] = ssv.getUpdateCountHistogramValues()
+ m[executeAndResultHoldTimeHistogramConstStr] = ssv.getExecuteAndResultHoldTimeHistogramValues()
+ m["EffectedRowCountMax"] = ssv.updateCountMax
+ m["FetchRowCountMax"] = ssv.fetchRowCountMax
+ m[clobOpenCountConstStr] = ssv.clobOpenCount
+
+ m[blobOpenCountConstStr] = ssv.blobOpenCount
+ m["ReadStringLength"] = ssv.readStringLength
+ m["ReadBytesLength"] = ssv.readBytesLength
+ m["InputStreamOpenCount"] = ssv.inputStreamOpenCount
+ m["ReaderOpenCount"] = ssv.readerOpenCount
+
+ m["HASH"] = ssv.sqlHash
+
+ m[executeHoldTimeHistogramConstStr] = ssv.getExecuteHistogram()
+
+ return m
+}
+
+type sqlStat struct {
+ Sql string
+
+ SqlHash int64
+
+ Id string
+
+ ExecuteLastStartTime int64
+
+ ExecuteBatchSizeTotal int64
+
+ ExecuteBatchSizeMax int64
+
+ ExecuteSuccessCount int64
+
+ ExecuteSpanNanoTotal int64
+
+ ExecuteSpanNanoMax int64
+
+ RunningCount int64
+
+ ConcurrentMax int64
+
+ ResultSetHoldTimeNano int64
+
+ ExecuteAndResultSetHoldTime int64
+
+ DataSource string
+
+ File string
+
+ ExecuteNanoSpanMaxOccurTime int64
+
+ ExecuteErrorCount int64
+
+ ExecuteErrorLast error
+
+ ExecuteErrorLastTime int64
+
+ UpdateCount int64
+
+ UpdateCountMax int64
+
+ FetchRowCount int64
+
+ FetchRowCountMax int64
+
+ InTransactionCount int64
+
+ LastSlowParameters string
+
+ Removed int64
+
+ ClobOpenCount int64
+
+ BlobOpenCount int64
+
+ ReadStringLength int64
+
+ ReadBytesLength int64
+
+ InputStreamOpenCount int64
+
+ ReaderOpenCount int64
+
+ Histogram_0_1 int64
+
+ Histogram_1_10 int64
+
+ Histogram_10_100 int64
+
+ Histogram_100_1000 int64
+
+ Histogram_1000_10000 int64
+
+ Histogram_10000_100000 int64
+
+ Histogram_100000_1000000 int64
+
+ Histogram_1000000_more int64
+
+ ExecuteAndResultHoldTime_0_1 int64
+
+ ExecuteAndResultHoldTime_1_10 int64
+
+ ExecuteAndResultHoldTime_10_100 int64
+
+ ExecuteAndResultHoldTime_100_1000 int64
+
+ ExecuteAndResultHoldTime_1000_10000 int64
+
+ ExecuteAndResultHoldTime_10000_100000 int64
+
+ ExecuteAndResultHoldTime_100000_1000000 int64
+
+ ExecuteAndResultHoldTime_1000000_more int64
+
+ FetchRowCount_0_1 int64
+
+ FetchRowCount_1_10 int64
+
+ FetchRowCount_10_100 int64
+
+ FetchRowCount_100_1000 int64
+
+ FetchRowCount_1000_10000 int64
+
+ FetchRowCount_10000_more int64
+
+ UpdateCount_0_1 int64
+
+ UpdateCount_1_10 int64
+
+ UpdateCount_10_100 int64
+
+ UpdateCount_100_1000 int64
+
+ UpdateCount_1000_10000 int64
+
+ UpdateCount_10000_more int64
+
+ DataSourceId string
+}
+
+func NewSqlStat(sql string) *sqlStat {
+ s := new(sqlStat)
+ s.Sql = sql
+ s.Id = "SQL" + generateId()
+ return s
+}
+
+func (s *sqlStat) reset() {
+ s.ExecuteLastStartTime = 0
+
+ s.ExecuteBatchSizeTotal = 0
+ s.ExecuteBatchSizeMax = 0
+
+ s.ExecuteSuccessCount = 0
+ s.ExecuteSpanNanoTotal = 0
+ s.ExecuteSpanNanoMax = 0
+ s.ExecuteNanoSpanMaxOccurTime = 0
+ s.ConcurrentMax = 0
+
+ s.ExecuteErrorCount = 0
+ s.ExecuteErrorLast = nil
+ s.ExecuteErrorLastTime = 0
+
+ s.UpdateCount = 0
+ s.UpdateCountMax = 0
+ s.FetchRowCount = 0
+ s.FetchRowCountMax = 0
+
+ s.Histogram_0_1 = 0
+ s.Histogram_1_10 = 0
+ s.Histogram_10_100 = 0
+ s.Histogram_100_1000 = 0
+ s.Histogram_1000_10000 = 0
+ s.Histogram_10000_100000 = 0
+ s.Histogram_100000_1000000 = 0
+ s.Histogram_1000000_more = 0
+
+ s.LastSlowParameters = ""
+ s.InTransactionCount = 0
+ s.ResultSetHoldTimeNano = 0
+ s.ExecuteAndResultSetHoldTime = 0
+
+ s.FetchRowCount_0_1 = 0
+ s.FetchRowCount_1_10 = 0
+ s.FetchRowCount_10_100 = 0
+ s.FetchRowCount_100_1000 = 0
+ s.FetchRowCount_1000_10000 = 0
+ s.FetchRowCount_10000_more = 0
+
+ s.UpdateCount_0_1 = 0
+ s.UpdateCount_1_10 = 0
+ s.UpdateCount_10_100 = 0
+ s.UpdateCount_100_1000 = 0
+ s.UpdateCount_1000_10000 = 0
+ s.UpdateCount_10000_more = 0
+
+ s.ExecuteAndResultHoldTime_0_1 = 0
+ s.ExecuteAndResultHoldTime_1_10 = 0
+ s.ExecuteAndResultHoldTime_10_100 = 0
+ s.ExecuteAndResultHoldTime_100_1000 = 0
+ s.ExecuteAndResultHoldTime_1000_10000 = 0
+ s.ExecuteAndResultHoldTime_10000_100000 = 0
+ s.ExecuteAndResultHoldTime_100000_1000000 = 0
+ s.ExecuteAndResultHoldTime_1000000_more = 0
+
+ s.BlobOpenCount = 0
+ s.ClobOpenCount = 0
+ s.ReadStringLength = 0
+ s.ReadBytesLength = 0
+ s.InputStreamOpenCount = 0
+ s.ReaderOpenCount = 0
+}
+
+func (s *sqlStat) getValueAndReset() *SqlStatValue {
+ return s.getValue(true)
+}
+
+func (s *sqlStat) getValue(reset bool) *SqlStatValue {
+ ssv := newSqlStatValue()
+ ssv.dataSource = s.DataSource
+ ssv.dataSourceId = s.DataSourceId
+ ssv.sql = s.Sql
+ ssv.sqlHash = s.SqlHash
+ ssv.id = s.Id
+ ssv.executeLastStartTime = s.ExecuteLastStartTime
+ if reset {
+ s.ExecuteLastStartTime = 0
+ }
+
+ ssv.executeBatchSizeTotal = getInt64(&s.ExecuteBatchSizeTotal, reset)
+ ssv.executeBatchSizeMax = getInt64(&s.ExecuteBatchSizeMax, reset)
+ ssv.executeSuccessCount = getInt64(&s.ExecuteSuccessCount, reset)
+ ssv.executeSpanNanoTotal = getInt64(&s.ExecuteSpanNanoTotal, reset)
+ ssv.executeSpanNanoMax = getInt64(&s.ExecuteSpanNanoMax, reset)
+ ssv.executeNanoSpanMaxOccurTime = s.ExecuteNanoSpanMaxOccurTime
+ if reset {
+ s.ExecuteNanoSpanMaxOccurTime = 0
+ }
+
+ ssv.runningCount = s.RunningCount
+ ssv.concurrentMax = getInt64(&s.ConcurrentMax, reset)
+ ssv.executeErrorCount = getInt64(&s.ExecuteErrorCount, reset)
+ ssv.executeErrorLast = s.ExecuteErrorLast
+ if reset {
+ s.ExecuteErrorLast = nil
+ }
+
+ ssv.executeErrorLastTime = s.ExecuteErrorLastTime
+ if reset {
+ ssv.executeErrorLastTime = 0
+ }
+
+ ssv.updateCount = getInt64(&s.UpdateCount, reset)
+ ssv.updateCountMax = getInt64(&s.UpdateCountMax, reset)
+ ssv.fetchRowCount = getInt64(&s.FetchRowCount, reset)
+ ssv.fetchRowCountMax = getInt64(&s.FetchRowCountMax, reset)
+ ssv.histogram_0_1 = getInt64(&s.Histogram_0_1, reset)
+ ssv.histogram_1_10 = getInt64(&s.Histogram_1_10, reset)
+ ssv.histogram_10_100 = getInt64(&s.Histogram_10_100, reset)
+ ssv.histogram_100_1000 = getInt64(&s.Histogram_100_1000, reset)
+ ssv.histogram_1000_10000 = getInt64(&s.Histogram_1000_10000, reset)
+ ssv.histogram_10000_100000 = getInt64(&s.Histogram_10000_100000, reset)
+ ssv.histogram_100000_1000000 = getInt64(&s.Histogram_100000_1000000, reset)
+ ssv.histogram_1000000_more = getInt64(&s.Histogram_1000000_more, reset)
+ ssv.lastSlowParameters = s.LastSlowParameters
+ if reset {
+ s.LastSlowParameters = ""
+ }
+
+ ssv.inTransactionCount = getInt64(&s.InTransactionCount, reset)
+ ssv.resultSetHoldTimeNano = getInt64(&s.ResultSetHoldTimeNano, reset)
+ ssv.executeAndResultSetHoldTime = getInt64(&s.ExecuteAndResultSetHoldTime, reset)
+ ssv.fetchRowCount_0_1 = getInt64(&s.FetchRowCount_0_1, reset)
+ ssv.fetchRowCount_1_10 = getInt64(&s.FetchRowCount_1_10, reset)
+ ssv.fetchRowCount_10_100 = getInt64(&s.FetchRowCount_10_100, reset)
+ ssv.fetchRowCount_100_1000 = getInt64(&s.FetchRowCount_100_1000, reset)
+ ssv.fetchRowCount_1000_10000 = getInt64(&s.FetchRowCount_1000_10000, reset)
+ ssv.fetchRowCount_10000_more = getInt64(&s.FetchRowCount_10000_more, reset)
+ ssv.updateCount_0_1 = getInt64(&s.UpdateCount_0_1, reset)
+ ssv.updateCount_1_10 = getInt64(&s.UpdateCount_1_10, reset)
+ ssv.updateCount_10_100 = getInt64(&s.UpdateCount_10_100, reset)
+ ssv.updateCount_100_1000 = getInt64(&s.UpdateCount_100_1000, reset)
+ ssv.updateCount_1000_10000 = getInt64(&s.UpdateCount_1000_10000, reset)
+ ssv.updateCount_10000_more = getInt64(&s.UpdateCount_10000_more, reset)
+ ssv.executeAndResultHoldTime_0_1 = getInt64(&s.ExecuteAndResultHoldTime_0_1, reset)
+ ssv.executeAndResultHoldTime_1_10 = getInt64(&s.ExecuteAndResultHoldTime_1_10, reset)
+ ssv.executeAndResultHoldTime_10_100 = getInt64(&s.ExecuteAndResultHoldTime_10_100, reset)
+ ssv.executeAndResultHoldTime_100_1000 = getInt64(&s.ExecuteAndResultHoldTime_100_1000, reset)
+ ssv.executeAndResultHoldTime_1000_10000 = getInt64(&s.ExecuteAndResultHoldTime_1000_10000, reset)
+ ssv.executeAndResultHoldTime_10000_100000 = getInt64(&s.ExecuteAndResultHoldTime_10000_100000, reset)
+ ssv.executeAndResultHoldTime_100000_1000000 = getInt64(&s.ExecuteAndResultHoldTime_100000_1000000, reset)
+ ssv.executeAndResultHoldTime_1000000_more = getInt64(&s.ExecuteAndResultHoldTime_1000000_more, reset)
+ ssv.blobOpenCount = getInt64(&s.BlobOpenCount, reset)
+ ssv.clobOpenCount = getInt64(&s.ClobOpenCount, reset)
+ ssv.readStringLength = getInt64(&s.ReadStringLength, reset)
+ ssv.readBytesLength = getInt64(&s.ReadBytesLength, reset)
+ ssv.inputStreamOpenCount = getInt64(&s.InputStreamOpenCount, reset)
+ ssv.readerOpenCount = getInt64(&s.ReaderOpenCount, reset)
+ return ssv
+}
+
+func (s *sqlStat) addUpdateCount(delta int64) {
+ if delta > 0 {
+ atomic.AddInt64(&s.UpdateCount, delta)
+ }
+
+ for {
+ max := atomic.LoadInt64(&s.UpdateCountMax)
+ if delta <= max {
+ break
+ }
+ if atomic.CompareAndSwapInt64(&s.UpdateCountMax, max, delta) {
+ break
+ }
+ }
+
+ if delta < 1 {
+ atomic.AddInt64(&s.UpdateCount_0_1, 1)
+ } else if delta < 10 {
+ atomic.AddInt64(&s.UpdateCount_1_10, 1)
+ } else if delta < 100 {
+ atomic.AddInt64(&s.UpdateCount_10_100, 1)
+ } else if delta < 1000 {
+ atomic.AddInt64(&s.UpdateCount_100_1000, 1)
+ } else if delta < 10000 {
+ atomic.AddInt64(&s.UpdateCount_1000_10000, 1)
+ } else {
+ atomic.AddInt64(&s.UpdateCount_10000_more, 1)
+ }
+}
+
+func (s *sqlStat) incrementClobOpenCount() {
+ atomic.AddInt64(&s.ClobOpenCount, 1)
+}
+
+func (s *sqlStat) incrementBlobOpenCount() {
+ atomic.AddInt64(&s.BlobOpenCount, 1)
+}
+
+func (s *sqlStat) addStringReadLength(length int64) {
+ atomic.AddInt64(&s.ReadStringLength, length)
+}
+
+func (s *sqlStat) addReadBytesLength(length int64) {
+ atomic.AddInt64(&s.ReadBytesLength, length)
+}
+
+func (s *sqlStat) addReaderOpenCount(count int64) {
+ atomic.AddInt64(&s.ReaderOpenCount, count)
+}
+
+func (s *sqlStat) addInputStreamOpenCount(count int64) {
+ atomic.AddInt64(&s.InputStreamOpenCount, count)
+}
+
+func (s *sqlStat) addFetchRowCount(delta int64) {
+ atomic.AddInt64(&s.FetchRowCount, delta)
+ for {
+ max := atomic.LoadInt64(&s.FetchRowCountMax)
+ if delta <= max {
+ break
+ }
+ if atomic.CompareAndSwapInt64(&s.FetchRowCountMax, max, delta) {
+ break
+ }
+ }
+
+ if delta < 1 {
+ atomic.AddInt64(&s.FetchRowCount_0_1, 1)
+ } else if delta < 10 {
+ atomic.AddInt64(&s.FetchRowCount_1_10, 1)
+ } else if delta < 100 {
+ atomic.AddInt64(&s.FetchRowCount_10_100, 1)
+ } else if delta < 1000 {
+ atomic.AddInt64(&s.FetchRowCount_100_1000, 1)
+ } else if delta < 10000 {
+ atomic.AddInt64(&s.FetchRowCount_1000_10000, 1)
+ } else {
+ atomic.AddInt64(&s.FetchRowCount_10000_more, 1)
+ }
+
+}
+
+func (s *sqlStat) addExecuteBatchCount(batchSize int64) {
+ atomic.AddInt64(&s.ExecuteBatchSizeTotal, batchSize)
+
+ for {
+ current := atomic.LoadInt64(&s.ExecuteBatchSizeMax)
+ if current < batchSize {
+ if atomic.CompareAndSwapInt64(&s.ExecuteBatchSizeMax, current, batchSize) {
+ break
+ } else {
+ continue
+ }
+ } else {
+ break
+ }
+ }
+}
+
+func (s *sqlStat) incrementExecuteSuccessCount() {
+ atomic.AddInt64(&s.ExecuteSuccessCount, 1)
+}
+
+func (s *sqlStat) incrementRunningCount() {
+ val := atomic.AddInt64(&s.RunningCount, 1)
+
+ for {
+ max := atomic.LoadInt64(&s.ConcurrentMax)
+ if val > max {
+ if atomic.CompareAndSwapInt64(&s.ConcurrentMax, max, val) {
+ break
+ } else {
+ continue
+ }
+ } else {
+ break
+ }
+ }
+}
+
+func (s *sqlStat) decrementRunningCount() {
+ atomic.AddInt64(&s.RunningCount, -1)
+}
+
+func (s *sqlStat) addExecuteTimeAndResultHoldTimeHistogramRecord(executeType ExecuteTypeEnum, firstResultSet bool, nanoSpan int64, parameters string) {
+ s.addExecuteTime(nanoSpan, parameters)
+
+ if ExecuteQuery != executeType && !firstResultSet {
+ s.executeAndResultHoldTimeHistogramRecord(nanoSpan)
+ }
+}
+
+func (s *sqlStat) executeAndResultHoldTimeHistogramRecord(nanoSpan int64) {
+ millis := nanoSpan / 1000 / 1000
+
+ if millis < 1 {
+ atomic.AddInt64(&s.ExecuteAndResultHoldTime_0_1, 1)
+ } else if millis < 10 {
+ atomic.AddInt64(&s.ExecuteAndResultHoldTime_1_10, 1)
+ } else if millis < 100 {
+ atomic.AddInt64(&s.ExecuteAndResultHoldTime_10_100, 1)
+ } else if millis < 1000 {
+ atomic.AddInt64(&s.ExecuteAndResultHoldTime_100_1000, 1)
+ } else if millis < 10000 {
+ atomic.AddInt64(&s.ExecuteAndResultHoldTime_1000_10000, 1)
+ } else if millis < 100000 {
+ atomic.AddInt64(&s.ExecuteAndResultHoldTime_10000_100000, 1)
+ } else if millis < 1000000 {
+ atomic.AddInt64(&s.ExecuteAndResultHoldTime_100000_1000000, 1)
+ } else {
+ atomic.AddInt64(&s.ExecuteAndResultHoldTime_1000000_more, 1)
+ }
+}
+
+func (s *sqlStat) histogramRecord(nanoSpan int64) {
+ millis := nanoSpan / 1000 / 1000
+
+ if millis < 1 {
+ atomic.AddInt64(&s.Histogram_0_1, 1)
+ } else if millis < 10 {
+ atomic.AddInt64(&s.Histogram_1_10, 1)
+ } else if millis < 100 {
+ atomic.AddInt64(&s.Histogram_10_100, 1)
+ } else if millis < 1000 {
+ atomic.AddInt64(&s.Histogram_100_1000, 1)
+ } else if millis < 10000 {
+ atomic.AddInt64(&s.Histogram_1000_10000, 1)
+ } else if millis < 100000 {
+ atomic.AddInt64(&s.Histogram_10000_100000, 1)
+ } else if millis < 1000000 {
+ atomic.AddInt64(&s.Histogram_100000_1000000, 1)
+ } else {
+ atomic.AddInt64(&s.Histogram_1000000_more, 1)
+ }
+}
+
+func (s *sqlStat) addExecuteTime(nanoSpan int64, parameters string) {
+ atomic.AddInt64(&s.ExecuteSpanNanoTotal, nanoSpan)
+
+ for {
+ current := atomic.LoadInt64(&s.ExecuteSpanNanoMax)
+ if current < nanoSpan {
+ if atomic.CompareAndSwapInt64(&s.ExecuteSpanNanoMax, current, nanoSpan) {
+
+ s.ExecuteNanoSpanMaxOccurTime = time.Now().UnixNano()
+ s.LastSlowParameters = parameters
+
+ break
+ } else {
+ continue
+ }
+ } else {
+ break
+ }
+ }
+
+ s.histogramRecord(nanoSpan)
+}
+
+func (s *sqlStat) getExecuteMillisTotal() int64 {
+ return s.ExecuteSpanNanoTotal / (1000 * 1000)
+}
+
+func (s *sqlStat) getExecuteMillisMax() int64 {
+ return s.ExecuteSpanNanoMax / (1000 * 1000)
+}
+
+func (s *sqlStat) incrementInTransactionCount() {
+ atomic.AddInt64(&s.InTransactionCount, 1)
+}
+
+func (s *sqlStat) getExecuteCount() int64 {
+ return s.ExecuteErrorCount + s.ExecuteSuccessCount
+}
+
+func (s *sqlStat) getData() map[string]interface{} {
+ return s.getValue(false).getData()
+}
+
+func (s *sqlStat) getHistogramValues() []int64 {
+ return []int64{
+
+ s.Histogram_0_1,
+ s.Histogram_1_10,
+ s.Histogram_10_100,
+ s.Histogram_100_1000,
+ s.Histogram_1000_10000,
+ s.Histogram_10000_100000,
+ s.Histogram_100000_1000000,
+ s.Histogram_1000000_more,
+ }
+}
+
+func (s *sqlStat) getHistogramSum() int64 {
+ values := s.getHistogramValues()
+ var sum int64 = 0
+ for i := 0; i < len(values); i++ {
+ sum += values[i]
+ }
+ return sum
+}
+
+func (s *sqlStat) error(err error) {
+ atomic.AddInt64(&s.ExecuteErrorCount, 1)
+ s.ExecuteErrorLastTime = time.Now().UnixNano()
+ s.ExecuteErrorLast = err
+}
+
+func (s *sqlStat) getResultSetHoldTimeMilis() int64 {
+ return s.ResultSetHoldTimeNano / (1000 * 1000)
+}
+
+func (s *sqlStat) getExecuteAndResultSetHoldTimeMilis() int64 {
+ return s.ExecuteAndResultSetHoldTime / (1000 * 1000)
+}
+
+func (s *sqlStat) getFetchRowCountHistogramValues() []int64 {
+ return []int64{
+
+ s.FetchRowCount_0_1,
+ s.FetchRowCount_1_10,
+ s.FetchRowCount_10_100,
+ s.FetchRowCount_100_1000,
+ s.FetchRowCount_1000_10000,
+ s.FetchRowCount_10000_more,
+ }
+}
+
+func (s *sqlStat) getUpdateCountHistogramValues() []int64 {
+ return []int64{
+
+ s.UpdateCount_0_1,
+ s.UpdateCount_1_10,
+ s.UpdateCount_10_100,
+ s.UpdateCount_100_1000,
+ s.UpdateCount_1000_10000,
+ s.UpdateCount_10000_more,
+ }
+}
+
+func (s *sqlStat) getExecuteAndResultHoldTimeHistogramValues() []int64 {
+ return []int64{
+
+ s.ExecuteAndResultHoldTime_0_1,
+ s.ExecuteAndResultHoldTime_1_10,
+ s.ExecuteAndResultHoldTime_10_100,
+ s.ExecuteAndResultHoldTime_100_1000,
+ s.ExecuteAndResultHoldTime_1000_10000,
+ s.ExecuteAndResultHoldTime_10000_100000,
+ s.ExecuteAndResultHoldTime_100000_1000000,
+ s.ExecuteAndResultHoldTime_1000000_more,
+ }
+}
+
+func (s *sqlStat) getExecuteAndResultHoldTimeHistogramSum() int64 {
+ values := s.getExecuteAndResultHoldTimeHistogramValues()
+ var sum int64 = 0
+ for i := 0; i < len(values); i++ {
+ sum += values[i]
+ }
+ return sum
+}
+
+func (s *sqlStat) addResultSetHoldTimeNano(nano int64) {
+ atomic.AddInt64(&s.ResultSetHoldTimeNano, nano)
+}
+
+func (s *sqlStat) addResultSetHoldTimeNano2(statementExecuteNano int64, resultHoldTimeNano int64) {
+ atomic.AddInt64(&s.ResultSetHoldTimeNano, resultHoldTimeNano)
+ atomic.AddInt64(&s.ExecuteAndResultSetHoldTime, statementExecuteNano+resultHoldTimeNano)
+ s.executeAndResultHoldTimeHistogramRecord((statementExecuteNano + resultHoldTimeNano) / 1000 / 1000)
+ atomic.AddInt64(&s.UpdateCount_0_1, 1)
+}
+
+type connectionStatValue struct {
+ id string
+
+ url string
+
+ connCount int64
+
+ activeConnCount int64
+
+ maxActiveConnCount int64
+
+ executeCount int64
+
+ errorCount int64
+
+ stmtCount int64
+
+ activeStmtCount int64
+
+ maxActiveStmtCount int64
+
+ commitCount int64
+
+ rollbackCount int64
+
+ clobOpenCount int64
+
+ blobOpenCount int64
+
+ properties string
+}
+
+func newConnectionStatValue() *connectionStatValue {
+ csv := new(connectionStatValue)
+ return csv
+}
+
+func (csv *connectionStatValue) getData() map[string]interface{} {
+ m := make(map[string]interface{})
+ m[idConstStr] = csv.id
+ m[urlConstStr] = csv.url
+ m[connCountConstStr] = csv.connCount
+ m[activeConnCountConstStr] = csv.activeConnCount
+ m[maxActiveConnCountConstStr] = csv.maxActiveConnCount
+
+ m[stmtCountConstStr] = csv.stmtCount
+ m[activeStmtCountConstStr] = csv.activeStmtCount
+ m[maxActiveStmtCountConstStr] = csv.maxActiveStmtCount
+
+ m[executeCountConstStr] = csv.executeCount
+ m[errorCountConstStr] = csv.errorCount
+ m[commitCountConstStr] = csv.commitCount
+ m[rollbackCountConstStr] = csv.rollbackCount
+
+ m[clobOpenCountConstStr] = csv.clobOpenCount
+ m[blobOpenCountConstStr] = csv.blobOpenCount
+
+ m[propertiesConstStr] = csv.properties
+ return m
+}
+
+type connectionStat struct {
+ id string
+
+ url string
+
+ connCount int64
+
+ activeConnCount int64
+
+ maxActiveConnCount int64
+
+ executeCount int64
+
+ errorCount int64
+
+ stmtCount int64
+
+ activeStmtCount int64
+
+ maxActiveStmtCount int64
+
+ commitCount int64
+
+ rollbackCount int64
+
+ clobOpenCount int64
+
+ blobOpenCount int64
+
+ sqlStatMap map[string]*sqlStat
+
+ maxSqlSize int
+
+ skipSqlCount int64
+
+ lock sync.RWMutex
+
+ properties string
+}
+
+func newConnectionStat(url string) *connectionStat {
+ cs := new(connectionStat)
+ cs.maxSqlSize = StatSqlMaxCount
+ cs.id = "DS" + generateId()
+ cs.url = url
+ cs.sqlStatMap = make(map[string]*sqlStat, 200)
+ return cs
+}
+
+func (cs *connectionStat) createSqlStat(sql string) *sqlStat {
+ cs.lock.Lock()
+ defer cs.lock.Unlock()
+ sqlStat, ok := cs.sqlStatMap[sql]
+ if !ok {
+ sqlStat := NewSqlStat(sql)
+ sqlStat.DataSource = cs.url
+ sqlStat.DataSourceId = cs.id
+ if cs.putSqlStat(sqlStat) {
+ return sqlStat
+ } else {
+ return nil
+ }
+ }
+
+ return sqlStat
+
+}
+
+func (cs *connectionStat) putSqlStat(sqlStat *sqlStat) bool {
+ if cs.maxSqlSize > 0 && len(cs.sqlStatMap) == cs.maxSqlSize {
+ if StatSqlRemoveMode == STAT_SQL_REMOVE_OLDEST {
+ removeSqlStat := cs.eliminateSqlStat()
+ if removeSqlStat.RunningCount > 0 || removeSqlStat.getExecuteCount() > 0 {
+ atomic.AddInt64(&cs.skipSqlCount, 1)
+ }
+ cs.sqlStatMap[sqlStat.Sql] = sqlStat
+ return true
+ } else {
+ if sqlStat.RunningCount > 0 || sqlStat.getExecuteCount() > 0 {
+ atomic.AddInt64(&cs.skipSqlCount, 1)
+ }
+ return false
+ }
+ } else {
+ cs.sqlStatMap[sqlStat.Sql] = sqlStat
+ return true
+ }
+}
+
+func (cs *connectionStat) eliminateSqlStat() *sqlStat {
+ if cs.maxSqlSize > 0 && len(cs.sqlStatMap) == cs.maxSqlSize {
+ if StatSqlRemoveMode == STAT_SQL_REMOVE_OLDEST {
+ for s, item := range cs.sqlStatMap {
+ if item != nil {
+ delete(cs.sqlStatMap, s)
+ return item
+ }
+ }
+ }
+ }
+ return nil
+}
+
+func (cs *connectionStat) getSqlStatMap() map[string]*sqlStat {
+ m := make(map[string]*sqlStat, len(cs.sqlStatMap))
+ cs.lock.Lock()
+ defer cs.lock.Unlock()
+ for s, item := range cs.sqlStatMap {
+ m[s] = item
+ }
+ return m
+}
+
+func (cs *connectionStat) getSqlStatMapAndReset() []*SqlStatValue {
+ stats := make([]*sqlStat, 0, len(cs.sqlStatMap))
+ cs.lock.Lock()
+ defer cs.lock.Unlock()
+
+ for s, stat := range cs.sqlStatMap {
+
+ if stat.getExecuteCount() == 0 && stat.RunningCount == 0 {
+ stat.Removed = 1
+ delete(cs.sqlStatMap, s)
+ } else {
+ stats = append(stats, stat)
+ }
+ }
+
+ values := make([]*SqlStatValue, 0, len(stats))
+ for _, stat := range stats {
+ value := stat.getValueAndReset()
+ if value.getExecuteCount() == 0 && value.runningCount == 0 {
+ continue
+ }
+ values = append(values, value)
+ }
+ return values
+}
+
+func (cs *connectionStat) incrementConn() {
+ atomic.AddInt64(&cs.connCount, 1)
+ atomic.AddInt64(&cs.activeConnCount, 1)
+ count := atomic.LoadInt64(&cs.activeConnCount)
+ if count > atomic.LoadInt64(&cs.maxActiveConnCount) {
+ atomic.StoreInt64(&cs.maxActiveConnCount, count)
+ }
+}
+
+func (cs *connectionStat) decrementConn() {
+ atomic.AddInt64(&cs.activeConnCount, -1)
+}
+
+func (cs *connectionStat) incrementStmt() {
+ atomic.AddInt64(&cs.stmtCount, 1)
+ atomic.AddInt64(&cs.activeStmtCount, 1)
+ count := atomic.LoadInt64(&cs.activeStmtCount)
+ if count > atomic.LoadInt64(&cs.maxActiveStmtCount) {
+ atomic.StoreInt64(&cs.maxActiveStmtCount, count)
+ }
+}
+
+func (cs *connectionStat) decrementStmt() {
+ atomic.AddInt64(&cs.activeStmtCount, -1)
+}
+
+func (cs *connectionStat) decrementStmtByActiveStmtCount(activeStmtCount int64) {
+ atomic.AddInt64(&cs.activeStmtCount, -activeStmtCount)
+}
+
+func (cs *connectionStat) incrementExecuteCount() {
+ atomic.AddInt64(&cs.executeCount, 1)
+}
+
+func (cs *connectionStat) incrementErrorCount() {
+ atomic.AddInt64(&cs.errorCount, 1)
+}
+
+func (cs *connectionStat) incrementCommitCount() {
+ atomic.AddInt64(&cs.commitCount, 1)
+}
+
+func (cs *connectionStat) incrementRollbackCount() {
+ atomic.AddInt64(&cs.rollbackCount, 1)
+}
+
+func (cs *connectionStat) getValue(reset bool) *connectionStatValue {
+ val := newConnectionStatValue()
+ val.id = cs.id
+ val.url = cs.url
+
+ val.connCount = getInt64(&cs.connCount, reset)
+ val.activeConnCount = getInt64(&cs.activeConnCount, false)
+ val.maxActiveConnCount = getInt64(&cs.maxActiveConnCount, false)
+
+ val.stmtCount = getInt64(&cs.stmtCount, reset)
+ val.activeStmtCount = getInt64(&cs.activeStmtCount, false)
+ val.maxActiveStmtCount = getInt64(&cs.maxActiveStmtCount, false)
+
+ val.commitCount = getInt64(&cs.commitCount, reset)
+ val.rollbackCount = getInt64(&cs.rollbackCount, reset)
+ val.executeCount = getInt64(&cs.executeCount, reset)
+ val.errorCount = getInt64(&cs.errorCount, reset)
+
+ val.blobOpenCount = getInt64(&cs.blobOpenCount, reset)
+ val.clobOpenCount = getInt64(&cs.clobOpenCount, reset)
+
+ val.properties = cs.properties
+ return val
+}
+
+func (cs *connectionStat) getData() map[string]interface{} {
+ return cs.getValue(false).getData()
+}
+
+func (cs *connectionStat) getValueAndReset() *connectionStatValue {
+ return cs.getValue(true)
+}
+
+type GoStat struct {
+ connStatMap map[string]*connectionStat
+
+ lock sync.RWMutex
+
+ maxConnSize int
+
+ skipConnCount int64
+}
+
+func newGoStat(maxConnSize int) *GoStat {
+ gs := new(GoStat)
+ if maxConnSize > 0 {
+ gs.maxConnSize = maxConnSize
+ } else {
+ gs.maxConnSize = 1000
+ }
+
+ gs.connStatMap = make(map[string]*connectionStat, 16)
+ return gs
+}
+
+func (gs *GoStat) createConnStat(conn *DmConnection) *connectionStat {
+ url := conn.dmConnector.host + ":" + strconv.Itoa(int(conn.dmConnector.port))
+ gs.lock.Lock()
+ defer gs.lock.Unlock()
+ connstat, ok := gs.connStatMap[url]
+ if !ok {
+ connstat = newConnectionStat(url)
+
+ remove := len(gs.connStatMap) > gs.maxConnSize
+ if remove && connstat.activeConnCount > 0 {
+ atomic.AddInt64(&gs.skipConnCount, 1)
+ }
+
+ gs.connStatMap[url] = connstat
+ }
+
+ return connstat
+}
+
+func (gs *GoStat) getConnStatMap() map[string]*connectionStat {
+ m := make(map[string]*connectionStat, len(gs.connStatMap))
+ gs.lock.Lock()
+ defer gs.lock.Unlock()
+
+ for s, stat := range gs.connStatMap {
+ m[s] = stat
+ }
+ return m
+}
+
+var sqlRowField = []string{rowNumConstStr, dataSourceConstStr, sqlConstStr, executeCountConstStr,
+ totalTimeConstStr, maxTimespanConstStr, inTransactionCountConstStr, errorCountConstStr, effectedRowCountConstStr,
+ fetchRowCountConstStr, runningCountConstStr, concurrentMaxConstStr, executeHoldTimeHistogramConstStr,
+ executeAndResultHoldTimeHistogramConstStr, fetchRowCountHistogramConstStr, effectedRowCountHistogramConstStr}
+
+var sqlColField = []string{"ID", "DataSource", "SQL", "ExecuteCount",
+ "ErrorCount", "TotalTime", "LastTime", "MaxTimespan", "LastError", "EffectedRowCount",
+ "FetchRowCount", "MaxTimespanOccurTime", "BatchSizeMax", "BatchSizeTotal", "ConcurrentMax",
+ "RunningCount", "Name", "File", "LastErrorMessage", "LastErrorClass", "LastErrorStackTrace",
+ "LastErrorTime", "DbType", "URL", "InTransactionCount", "Histogram", "LastSlowParameters",
+ "ResultSetHoldTime", "ExecuteAndResultSetHoldTime", "FetchRowCountHistogram",
+ "EffectedRowCountHistogram", "ExecuteAndResultHoldTimeHistogram", "EffectedRowCountMax",
+ "FetchRowCountMax", "ClobOpenCount"}
+
+const (
+ rowNumConstStr = "rowNum"
+ idConstStr = "ID"
+ urlConstStr = "Url"
+ connCountConstStr = "ConnCount"
+ activeConnCountConstStr = "ActiveConnCount"
+ maxActiveConnCountConstStr = "MaxActiveConnCount"
+ stmtCountConstStr = "StmtCount"
+ activeStmtCountConstStr = "ActiveStmtCount"
+ maxActiveStmtCountConstStr = "MaxActiveStmtCount"
+ executeCountConstStr = "ExecuteCount"
+ errorCountConstStr = "ErrorCount"
+ commitCountConstStr = "CommitCount"
+ rollbackCountConstStr = "RollbackCount"
+ clobOpenCountConstStr = "ClobOpenCount"
+ blobOpenCountConstStr = "BlobOpenCount"
+ propertiesConstStr = "Properties"
+ dataSourceConstStr = "DataSource"
+ sqlConstStr = "SQL"
+ totalTimeConstStr = "TotalTime"
+ maxTimespanConstStr = "MaxTimespan"
+ inTransactionCountConstStr = "InTransactionCount"
+ effectedRowCountConstStr = "EffectedRowCount"
+ fetchRowCountConstStr = "FetchRowCount"
+ runningCountConstStr = "RunningCount"
+ concurrentMaxConstStr = "ConcurrentMax"
+ executeHoldTimeHistogramConstStr = "ExecuteHoldTimeHistogram"
+ executeAndResultHoldTimeHistogramConstStr = "ExecuteAndResultHoldTimeHistogram"
+ fetchRowCountHistogramConstStr = "FetchRowCountHistogram"
+ effectedRowCountHistogramConstStr = "EffectedRowCountHistogram"
+)
+
+var dsRowField = []string{rowNumConstStr, urlConstStr, activeConnCountConstStr,
+ maxActiveConnCountConstStr, activeStmtCountConstStr, maxActiveStmtCountConstStr, executeCountConstStr, errorCountConstStr,
+ commitCountConstStr, rollbackCountConstStr}
+
+var dsColField = []string{"ID", "ConnCount", "ActiveConnCount",
+ "MaxActiveConnCount", "StmtCount", "ActiveStmtCount", "MaxActiveStmtCount", "ExecuteCount",
+ "ErrorCount", "CommitCount", "RollbackCount", "ClobOpenCount", "BlobOpenCount"}
+
+const (
+ PROP_NAME_SORT = "sort"
+ PROP_NAME_SORT_FIELD = "field"
+ PROP_NAME_SORT_TYPE = "direction"
+ PROP_NAME_SEARCH = "search"
+ PROP_NAME_PAGE_NUM = "pageNum"
+ PROP_NAME_PAGE_SIZE = "pageSize"
+ PROP_NAME_PAGE_COUNT = "pageCount"
+ PROP_NAME_TOTAL_ROW_COUNT = "totalRowCount"
+ PROP_NAME_FLUSH_FREQ = "flushFreq"
+ PROP_NAME_DATASOURCE_ID = "dataSourceId"
+ PROP_NAME_SQL_ID = "sqlId"
+
+ URL_SQL = "sql"
+ URL_SQL_DETAIL = "sqlDetail"
+ URL_DATASOURCE = "dataSource"
+ URL_DATASOURCE_DETAIL = "dataSourceDetail"
+
+ RESULT_CODE_SUCCESS = 1
+ RESULT_CODE_ERROR = -1
+ DEFAULT_PAGE_NUM = 1
+ DEFAULT_PAGE_SIZE = int(INT32_MAX)
+ DEFAULT_ORDER_TYPE = "asc"
+ DEFAULT_ORDERBY = "DataSourceId"
+)
+
+type StatReader struct {
+ connStat []map[string]interface{}
+
+ connStatColLens []int
+
+ highFreqSqlStat []map[string]interface{}
+
+ highFreqSqlStatColLens []int
+
+ slowSqlStat []map[string]interface{}
+
+ slowSqlStatColLens []int
+}
+
+func newStatReader() *StatReader {
+ sr := new(StatReader)
+ return sr
+}
+
+func (sr *StatReader) readConnStat(retList []string, maxCount int) (bool, []string) {
+ fields := dsRowField
+ isAppend := false
+ if sr.connStat == nil {
+ sr.connStat = sr.getConnStat("", fields)
+ sr.connStatColLens = calcColLens(sr.connStat, fields, COL_MAX_LEN)
+ isAppend = false
+ } else {
+ isAppend = true
+ }
+ var retContent []map[string]interface{}
+ if maxCount > 0 && len(sr.connStat) > maxCount {
+ retContent = sr.connStat[0:maxCount]
+ sr.connStat = sr.connStat[maxCount:len(sr.connStat)]
+ } else {
+ retContent = sr.connStat
+ sr.connStat = nil
+ }
+ retList = append(retList, sr.getFormattedOutput(retContent, fields, sr.connStatColLens, isAppend))
+ return sr.connStat != nil, retList
+}
+
+func (sr *StatReader) readHighFreqSqlStat(retList []string, maxCount int) (bool, []string) {
+ isAppend := false
+ if sr.highFreqSqlStat == nil {
+ sr.highFreqSqlStat = sr.getHighFreqSqlStat(StatHighFreqSqlCount, -1, sqlRowField)
+ sr.highFreqSqlStatColLens = calcColLens(sr.highFreqSqlStat, sqlRowField, COL_MAX_LEN)
+ isAppend = false
+ } else {
+ isAppend = true
+ }
+ var retContent []map[string]interface{}
+ if maxCount > 0 && len(sr.highFreqSqlStat) > maxCount {
+ retContent = sr.highFreqSqlStat[0:maxCount]
+ sr.highFreqSqlStat = sr.highFreqSqlStat[maxCount:len(sr.highFreqSqlStat)]
+ } else {
+ retContent = sr.highFreqSqlStat
+ sr.highFreqSqlStat = nil
+ }
+ retList = append(retList, sr.getFormattedOutput(retContent, sqlRowField, sr.highFreqSqlStatColLens, isAppend))
+ return sr.highFreqSqlStat != nil, retList
+}
+
+func (sr *StatReader) getHighFreqSqlStat(topCount int, sqlId int,
+ fields []string) []map[string]interface{} {
+ var content []map[string]interface{}
+
+ if topCount != 0 {
+ parameters := NewProperties()
+ parameters.Set(PROP_NAME_SORT_FIELD, "ExecuteCount")
+ parameters.Set(PROP_NAME_SORT_TYPE, "desc")
+ parameters.Set(PROP_NAME_PAGE_NUM, "1")
+ parameters.Set(PROP_NAME_PAGE_SIZE, strconv.Itoa(topCount))
+ content = sr.service(URL_SQL, parameters)
+ if sqlId != -1 {
+ matchedContent := make([]map[string]interface{}, 0)
+ for _, sqlStat := range content {
+ idStr := sqlStat["ID"]
+ if idStr == sqlId {
+ matchedContent = append(matchedContent, sqlStat)
+ break
+ }
+ }
+ content = matchedContent
+ }
+ }
+
+ if content == nil {
+ content = make([]map[string]interface{}, 0)
+ } else {
+ i := 1
+ for _, m := range content {
+ m[rowNumConstStr] = i
+ i++
+ }
+ }
+ content = addTitles(content, fields)
+ return content
+}
+
+func (sr *StatReader) readSlowSqlStat(retList []string, maxCount int) (bool, []string) {
+ isAppend := false
+ if sr.slowSqlStat == nil {
+ sr.slowSqlStat = sr.getSlowSqlStat(StatSlowSqlCount, -1, sqlRowField)
+ sr.slowSqlStatColLens = calcColLens(sr.slowSqlStat, sqlRowField,
+ COL_MAX_LEN)
+ isAppend = false
+ } else {
+ isAppend = true
+ }
+ var retContent []map[string]interface{}
+ if maxCount > 0 && len(sr.slowSqlStat) > maxCount {
+ retContent = sr.slowSqlStat[0:maxCount]
+ sr.slowSqlStat = sr.slowSqlStat[maxCount:len(sr.slowSqlStat)]
+ } else {
+ retContent = sr.slowSqlStat
+ sr.slowSqlStat = nil
+ }
+ retList = append(retList, sr.getFormattedOutput(retContent, sqlRowField, sr.slowSqlStatColLens, isAppend))
+ return sr.slowSqlStat != nil, retList
+}
+
+func (sr *StatReader) getSlowSqlStat(topCount int, sqlId int, fields []string) []map[string]interface{} {
+ var content []map[string]interface{}
+
+ if topCount != 0 {
+ parameters := NewProperties()
+ parameters.Set(PROP_NAME_SORT_FIELD, "MaxTimespan")
+ parameters.Set(PROP_NAME_SORT_TYPE, "desc")
+ parameters.Set(PROP_NAME_PAGE_NUM, "1")
+ parameters.Set(PROP_NAME_PAGE_SIZE, strconv.Itoa(topCount))
+
+ content = sr.service(URL_SQL, parameters)
+ if sqlId != -1 {
+ matchedContent := make([]map[string]interface{}, 0)
+ for _, sqlStat := range content {
+ idStr := sqlStat["ID"]
+ if idStr == sqlId {
+ matchedContent = append(matchedContent, sqlStat)
+ break
+ }
+ }
+ content = matchedContent
+ }
+ }
+
+ if content == nil {
+ content = make([]map[string]interface{}, 0)
+ } else {
+ i := 1
+ for _, m := range content {
+ m["rowNum"] = i
+ i++
+ }
+ }
+ content = addTitles(content, fields)
+ return content
+}
+
+func (sr *StatReader) getConnStat(connId string, fields []string) []map[string]interface{} {
+ content := sr.service(URL_DATASOURCE, nil)
+ if connId != "" {
+ matchedContent := make([]map[string]interface{}, 0)
+ for _, dsStat := range content {
+ idStr := dsStat["Identity"]
+ if connId == idStr {
+ matchedContent = append(matchedContent, dsStat)
+ break
+ }
+ }
+ content = matchedContent
+ }
+ if content == nil {
+ content = make([]map[string]interface{}, 0)
+ } else {
+ i := 1
+ for _, m := range content {
+ m["rowNum"] = i
+ i++
+ }
+ }
+ content = addTitles(content, fields)
+ return content
+}
+
+func (sr *StatReader) getFormattedOutput(content []map[string]interface{}, fields []string, colLens []int,
+ isAppend bool) string {
+ return toTable(content, fields, colLens, true, isAppend)
+}
+
+func (sr *StatReader) parseUrl(url string) *Properties {
+ parameters := NewProperties()
+
+ if url == "" || len(strings.TrimSpace(url)) == 0 {
+ return parameters
+ }
+
+ parametersStr := util.StringUtil.SubstringBetween(url, "?", "")
+ if parametersStr == "" || len(parametersStr) == 0 {
+ return parameters
+ }
+
+ parametersArray := strings.Split(parametersStr, "&")
+
+ for _, parameterStr := range parametersArray {
+ index := strings.Index(parametersStr, "=")
+ if index <= 0 {
+ continue
+ }
+
+ name := parameterStr[0:index]
+ value := parameterStr[index+1:]
+ parameters.Set(name, value)
+ }
+ return parameters
+}
+
+func (sr *StatReader) service(url string, params *Properties) []map[string]interface{} {
+ if params != nil {
+ params.SetProperties(sr.parseUrl(url))
+ } else {
+ params = sr.parseUrl(url)
+ }
+
+ if strings.Index(url, URL_SQL) == 0 {
+ array := sr.getSqlStatList(params)
+ array = sr.comparatorOrderBy(array, params)
+ params.Set(PROP_NAME_FLUSH_FREQ, strconv.Itoa(StatFlushFreq))
+ return array
+ } else if strings.Index(url, URL_SQL_DETAIL) == 0 {
+ array := sr.getSqlStatDetailList(params)
+ return array
+ } else if strings.Index(url, URL_DATASOURCE) == 0 {
+ array := sr.getConnStatList(params)
+ array = sr.comparatorOrderBy(array, params)
+ params.Set(PROP_NAME_FLUSH_FREQ, strconv.Itoa(StatFlushFreq))
+ return array
+ } else if strings.Index(url, URL_DATASOURCE_DETAIL) == 0 {
+ array := sr.getConnStatDetailList(params)
+ return array
+ } else {
+ return nil
+ }
+}
+
+func (sr *StatReader) getSqlStatList(params *Properties) []map[string]interface{} {
+ array := make([]map[string]interface{}, 0)
+ connStatMap := goStat.getConnStatMap()
+ var sqlStatMap map[string]*sqlStat
+ for _, connStat := range connStatMap {
+ sqlStatMap = connStat.getSqlStatMap()
+ for _, sqlStat := range sqlStatMap {
+ data := sqlStat.getData()
+ executeCount := data[executeCountConstStr]
+ runningCount := data[runningCountConstStr]
+ if executeCount == 0 && runningCount == 0 {
+ continue
+ }
+
+ array = append(array, data)
+ }
+ }
+
+ return array
+}
+
+func (sr *StatReader) getSqlStatDetailList(params *Properties) []map[string]interface{} {
+ array := make([]map[string]interface{}, 0)
+ connStatMap := goStat.getConnStatMap()
+ var data *sqlStat
+ sqlId := ""
+ dsId := ""
+ if v := params.GetString(PROP_NAME_SQL_ID, ""); v != "" {
+ sqlId = v
+ }
+ if v := params.GetString(PROP_NAME_DATASOURCE_ID, ""); v != "" {
+ dsId = v
+ }
+ if sqlId != "" && dsId != "" {
+ for _, connStat := range connStatMap {
+ if dsId != connStat.id {
+ continue
+ } else {
+ sqlStatMap := connStat.getSqlStatMap()
+ for _, sqlStat := range sqlStatMap {
+
+ if sqlId == sqlStat.Id {
+ data = sqlStat
+ break
+ }
+ }
+ }
+ break
+ }
+ }
+ if data != nil {
+
+ array = append(array, data.getData())
+
+ }
+ return array
+}
+
+func (sr *StatReader) getConnStatList(params *Properties) []map[string]interface{} {
+ array := make([]map[string]interface{}, 0)
+ connStatMap := goStat.getConnStatMap()
+ id := ""
+ if v := params.GetString(PROP_NAME_DATASOURCE_ID, ""); v != "" {
+ id = v
+ }
+ for _, connStat := range connStatMap {
+ data := connStat.getData()
+
+ connCount := data["ConnCount"]
+
+ if connCount == 0 {
+ continue
+ }
+
+ if id != "" {
+ if id == connStat.id {
+ array = append(array, data)
+ break
+ } else {
+ continue
+ }
+ } else {
+
+ array = append(array, data)
+ }
+
+ }
+ return array
+}
+
+func (sr *StatReader) getConnStatDetailList(params *Properties) []map[string]interface{} {
+ array := make([]map[string]interface{}, 0)
+ var data *connectionStat
+ connStatMap := goStat.getConnStatMap()
+ id := ""
+ if v := params.GetString(PROP_NAME_DATASOURCE_ID, ""); v != "" {
+ id = v
+ }
+ if id != "" {
+ for _, connStat := range connStatMap {
+ if id == connStat.id {
+ data = connStat
+ break
+ }
+ }
+ }
+ if data != nil {
+ dataValue := data.getValue(false)
+ m := make(map[string]interface{}, 2)
+ m["name"] = "数据源"
+ m["value"] = dataValue.url
+ array = append(array, m)
+
+ m = make(map[string]interface{}, 2)
+ m["name"] = "总会话数"
+ m["value"] = dataValue.connCount
+ array = append(array, m)
+
+ m = make(map[string]interface{}, 2)
+ m["name"] = "活动会话数"
+ m["value"] = dataValue.activeConnCount
+ array = append(array, m)
+
+ m = make(map[string]interface{}, 2)
+ m["name"] = "活动会话数峰值"
+ m["value"] = dataValue.maxActiveStmtCount
+ array = append(array, m)
+
+ m = make(map[string]interface{}, 2)
+ m["name"] = "总句柄数"
+ m["value"] = dataValue.stmtCount
+ array = append(array, m)
+
+ m = make(map[string]interface{}, 2)
+ m["name"] = "活动句柄数"
+ m["value"] = dataValue.activeStmtCount
+ array = append(array, m)
+
+ m = make(map[string]interface{}, 2)
+ m["name"] = "活动句柄数峰值"
+ m["value"] = dataValue.maxActiveStmtCount
+ array = append(array, m)
+
+ m = make(map[string]interface{}, 2)
+ m["name"] = "执行次数"
+ m["value"] = dataValue.executeCount
+ array = append(array, m)
+
+ m = make(map[string]interface{}, 2)
+ m["name"] = "执行出错次数"
+ m["value"] = dataValue.errorCount
+ array = append(array, m)
+
+ m = make(map[string]interface{}, 2)
+ m["name"] = "提交次数"
+ m["value"] = dataValue.commitCount
+ array = append(array, m)
+
+ m = make(map[string]interface{}, 2)
+ m["name"] = "回滚次数"
+ m["value"] = dataValue.rollbackCount
+ array = append(array, m)
+
+ }
+ return array
+}
+
+type mapSlice struct {
+ m []map[string]interface{}
+ isDesc bool
+ orderByKey string
+}
+
+func newMapSlice(m []map[string]interface{}, isDesc bool, orderByKey string) *mapSlice {
+ ms := new(mapSlice)
+ ms.m = m
+ ms.isDesc = isDesc
+ ms.orderByKey = orderByKey
+ return ms
+}
+
+func (ms mapSlice) Len() int { return len(ms.m) }
+
+func (ms mapSlice) Less(i, j int) bool {
+ m1 := ms.m[i]
+ m2 := ms.m[j]
+ v1 := m1[ms.orderByKey]
+ v2 := m2[ms.orderByKey]
+ if v1 == nil {
+ return true
+ } else if v2 == nil {
+ return false
+ }
+
+ switch v1.(type) {
+ case int64:
+ return v1.(int64) < v2.(int64)
+ case float64:
+ return v1.(float64) < v2.(float64)
+ default:
+ return true
+ }
+}
+
+func (ms mapSlice) Swap(i, j int) {
+ ms.m[i], ms.m[j] = ms.m[j], ms.m[i]
+}
+
+func (sr *StatReader) comparatorOrderBy(array []map[string]interface{}, params *Properties) []map[string]interface{} {
+ if array == nil {
+ array = make([]map[string]interface{}, 0)
+ }
+
+ orderBy := DEFAULT_ORDERBY
+ orderType := DEFAULT_ORDER_TYPE
+ pageNum := DEFAULT_PAGE_NUM
+ pageSize := DEFAULT_PAGE_SIZE
+ if params != nil {
+ if v := params.GetTrimString(PROP_NAME_SORT_FIELD, ""); v != "" {
+ orderBy = v
+ }
+
+ if v := params.GetTrimString(PROP_NAME_SORT_TYPE, ""); v != "" {
+ orderType = v
+ }
+
+ if v := params.GetTrimString(PROP_NAME_PAGE_NUM, ""); v != "" {
+ var err error
+ pageNum, err = strconv.Atoi(v)
+ if err != nil {
+ pageNum = DEFAULT_PAGE_NUM
+ }
+ }
+ if v := params.GetTrimString(PROP_NAME_PAGE_SIZE, ""); v != "" {
+ var err error
+ pageSize, err = strconv.Atoi(v)
+ if err != nil {
+ pageSize = DEFAULT_PAGE_SIZE
+ }
+ }
+ }
+
+ rowCount := len(array)
+ pageCount := int(math.Ceil(float64(rowCount * 1.0 / pageSize)))
+ if pageCount < 1 {
+ pageCount = 1
+ }
+
+ if pageNum > pageCount {
+ pageNum = pageCount
+ }
+
+ if len(array) > 0 {
+
+ if orderBy != "" {
+ sort.Sort(newMapSlice(array, !(DEFAULT_ORDER_TYPE == orderType), orderBy))
+ }
+
+ fromIndex := (pageNum - 1) * pageSize
+
+ toIndex := pageNum * pageSize
+ if toIndex > rowCount {
+ toIndex = rowCount
+ }
+ array = array[fromIndex:toIndex]
+ }
+ sr.resetPageInfo(params, rowCount, pageCount, pageNum)
+ return array
+}
+
+func (sr *StatReader) resetPageInfo(params *Properties, rowCount int, pageCount int, pageNum int) {
+
+ if params != nil {
+ v := params.GetString(PROP_NAME_PAGE_SIZE, "")
+ if v != "" {
+
+ params.Set(PROP_NAME_PAGE_COUNT, strconv.Itoa(pageCount))
+ params.Set(PROP_NAME_TOTAL_ROW_COUNT, strconv.Itoa(rowCount))
+ params.Set(PROP_NAME_PAGE_NUM, strconv.Itoa(pageNum))
+ }
+ }
+}
+
+const COL_MAX_LEN = 32
+
+func calcColLens(objList []map[string]interface{}, fields []string, maxColLen int) []int {
+
+ colLen := 0
+ colVal := ""
+ colLens := make([]int, len(fields))
+ for _, obj := range objList {
+ for i := 0; i < len(fields); i++ {
+ colVal = getColValue(obj[fields[i]])
+ colLen = len(colVal)
+ if colLen > colLens[i] {
+ colLens[i] = colLen
+ }
+ }
+ }
+ if maxColLen > 0 {
+ for i := 0; i < len(fields); i++ {
+ if colLens[i] > maxColLen {
+ colLens[i] = maxColLen
+ }
+ }
+ }
+ return colLens
+}
+
+func addTitles(objList []map[string]interface{}, fields []string) []map[string]interface{} {
+ titleMap := make(map[string]interface{}, len(fields))
+ for i := 0; i < len(fields); i++ {
+ titleMap[fields[i]] = fields[i]
+ }
+
+ dst := append(objList, titleMap)
+ copy(dst[1:], dst[:len(dst)-1])
+ dst[0] = titleMap
+ return dst
+}
+
+func toTable(objList []map[string]interface{}, fields []string, colLens []int,
+ showAll bool, append bool) string {
+ if fields == nil || objList == nil {
+ return ""
+ }
+
+ if colLens == nil {
+ colLens = calcColLens(objList, fields, COL_MAX_LEN)
+ }
+
+ output := &strings.Builder{}
+ if !append {
+ sepLine(output, colLens)
+ }
+
+ for _, obj := range objList {
+ objMore := obj
+ for objMore != nil {
+ objMore = formateLine(output, objMore, fields, colLens, showAll)
+ }
+ sepLine(output, colLens)
+ }
+
+ return output.String()
+}
+
+func formateLine(output *strings.Builder, obj map[string]interface{}, fields []string, colLens []int,
+ showAll bool) map[string]interface{} {
+ hasMore := false
+ objMore := make(map[string]interface{})
+ colLen := 0
+ colVal := ""
+ for i := 0; i < len(fields); i++ {
+ colVal = getColValue(obj[fields[i]])
+
+ colLen = len(colVal)
+ if colLen <= colLens[i] {
+ output.WriteString("|")
+ output.WriteString(colVal)
+ blanks(output, colLens[i]-colLen)
+ if showAll {
+ objMore[fields[i]] = ""
+ }
+ } else {
+ output.WriteString("|")
+ if showAll {
+ output.WriteString(colVal[0:colLens[i]])
+ objMore[fields[i]] = colVal[colLens[i]:]
+ hasMore = true
+ } else {
+ output.WriteString(colVal[0:colLens[i]-3] + "...")
+ }
+ }
+ }
+ output.WriteString("|")
+ output.WriteString(util.StringUtil.LineSeparator())
+
+ if hasMore {
+ return objMore
+ } else {
+ return nil
+ }
+}
+
+func sepLine(output *strings.Builder, colLens []int) {
+ output.WriteString("+")
+ for _, colLen := range colLens {
+ for i := 0; i < colLen; i++ {
+ output.WriteString("+")
+ }
+ output.WriteString("+")
+ }
+ output.WriteString(util.StringUtil.LineSeparator())
+}
+
+func blanks(output *strings.Builder, count int) {
+ for count > 0 {
+ output.WriteString(" ")
+ count--
+ }
+}
+
+func getColValue(colObj interface{}) string {
+ var colVal string
+ if colObj == nil {
+ colVal = ""
+ } else {
+ colVal = fmt.Sprint(colObj)
+ }
+
+ colVal = strings.Replace(colVal, "\t", "", -1)
+ colVal = strings.Replace(colVal, "\n", "", -1)
+ colVal = strings.Replace(colVal, "\r", "", -1)
+
+ return colVal
+}
+
+const (
+ READ_MAX_SIZE = 100
+)
+
+type statFlusher struct {
+ sr *StatReader
+ logList []string
+ date string
+ logFile *os.File
+ flushFreq int
+ filePath string
+ filePrefix string
+ buffer *Dm_build_1499
+}
+
+func newStatFlusher() *statFlusher {
+ sf := new(statFlusher)
+ sf.sr = newStatReader()
+ sf.logList = make([]string, 0, 32)
+ sf.date = time.Now().Format("2006-01-02")
+ sf.flushFreq = StatFlushFreq
+ sf.filePath = StatDir
+ sf.filePrefix = "dm_go_stat"
+ sf.buffer = Dm_build_1503()
+ return sf
+}
+
+func (sf *statFlusher) isConnStatEnabled() bool {
+ return StatEnable
+}
+
+func (sf *statFlusher) isSlowSqlStatEnabled() bool {
+ return StatEnable
+}
+
+func (sf *statFlusher) isHighFreqSqlStatEnabled() bool {
+ return StatEnable
+}
+
+func (sf *statFlusher) doRun() {
+
+ for {
+ if len(goStat.connStatMap) > 0 {
+ sf.logList = append(sf.logList, time.Now().String())
+ if sf.isConnStatEnabled() {
+ sf.logList = append(sf.logList, "#connection stat")
+ hasMore := true
+ for hasMore {
+ hasMore, sf.logList = sf.sr.readConnStat(sf.logList, READ_MAX_SIZE)
+ sf.writeAndFlush(sf.logList, 0, len(sf.logList))
+ sf.logList = sf.logList[0:0]
+ }
+ }
+ if sf.isHighFreqSqlStatEnabled() {
+ sf.logList = append(sf.logList, "#top "+strconv.Itoa(StatHighFreqSqlCount)+" high freq sql stat")
+ hasMore := true
+ for hasMore {
+ hasMore, sf.logList = sf.sr.readHighFreqSqlStat(sf.logList, READ_MAX_SIZE)
+ sf.writeAndFlush(sf.logList, 0, len(sf.logList))
+ sf.logList = sf.logList[0:0]
+ }
+ }
+ if sf.isSlowSqlStatEnabled() {
+ sf.logList = append(sf.logList, "#top "+strconv.Itoa(StatSlowSqlCount)+" slow sql stat")
+ hasMore := true
+ for hasMore {
+ hasMore, sf.logList = sf.sr.readSlowSqlStat(sf.logList, READ_MAX_SIZE)
+ sf.writeAndFlush(sf.logList, 0, len(sf.logList))
+ sf.logList = sf.logList[0:0]
+ }
+ }
+ sf.logList = append(sf.logList, util.StringUtil.LineSeparator())
+ sf.logList = append(sf.logList, util.StringUtil.LineSeparator())
+ sf.writeAndFlush(sf.logList, 0, len(sf.logList))
+ sf.logList = sf.logList[0:0]
+ time.Sleep(time.Duration(StatFlushFreq) * time.Second)
+ }
+ }
+}
+
+func (sf *statFlusher) writeAndFlush(logs []string, startOff int, l int) {
+ var bytes []byte
+ for i := startOff; i < startOff+l; i++ {
+ bytes = []byte(logs[i] + util.StringUtil.LineSeparator())
+
+ sf.buffer.Dm_build_1525(bytes, 0, len(bytes))
+
+ if sf.buffer.Dm_build_1504() >= FLUSH_SIZE {
+ sf.doFlush(sf.buffer)
+ }
+ }
+
+ if sf.buffer.Dm_build_1504() > 0 {
+ sf.doFlush(sf.buffer)
+ }
+}
+
+func (sf *statFlusher) doFlush(buffer *Dm_build_1499) {
+ if sf.needCreateNewFile() {
+ sf.closeCurrentFile()
+ sf.logFile = sf.createNewFile()
+ }
+ buffer.Dm_build_1519(sf.logFile, buffer.Dm_build_1504())
+}
+func (sf *statFlusher) closeCurrentFile() {
+ if sf.logFile != nil {
+ sf.logFile.Close()
+ sf.logFile = nil
+ }
+}
+func (sf *statFlusher) createNewFile() *os.File {
+ sf.date = time.Now().Format("2006-01-02")
+ fileName := sf.filePrefix + "_" + sf.date + "_" + strconv.Itoa(time.Now().Nanosecond()) + ".txt"
+ sf.filePath = StatDir
+ if len(sf.filePath) > 0 {
+ if _, err := os.Stat(sf.filePath); err != nil {
+ os.MkdirAll(sf.filePath, 0755)
+ }
+ if _, err := os.Stat(sf.filePath + fileName); err != nil {
+ logFile, err := os.Create(sf.filePath + fileName)
+ if err != nil {
+ panic(err)
+ }
+ return logFile
+ }
+ }
+ return nil
+}
+func (sf *statFlusher) needCreateNewFile() bool {
+ now := time.Now().Format("2006-01-02")
+ fileInfo, err := sf.logFile.Stat()
+ return now != sf.date || err != nil || sf.logFile == nil || fileInfo.Size() > int64(MAX_FILE_SIZE)
+}
diff --git a/dmr/h.go b/dmr/h.go
new file mode 100644
index 0000000..945441e
--- /dev/null
+++ b/dmr/h.go
@@ -0,0 +1,790 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "math"
+ "strconv"
+ "strings"
+ "time"
+ "unicode"
+)
+
+func encodeByString(x string, dtype int, scale int, ltz int, dtz int) ([]byte, error) {
+ dt := make([]int, DT_LEN)
+ if _, err := toDTFromString(x, dt); err != nil {
+ return nil, err
+ }
+ return encode(dt, dtype, scale, ltz)
+}
+
+func encodeByTime(x time.Time, dtype int, scale int, lTz int, dbTz int) ([]byte, error) {
+ dt := toDTFromTime(x)
+ return encode(dt, dtype, scale, lTz)
+}
+
+func encodeByDateNumber(x int64, destDType int, scale int, lTz int, dbTz int16) ([]byte, error) {
+ switch destDType {
+ case DATETIME:
+
+ if x > 2958463*24*60*60 {
+ return nil, ECGO_DATETIME_OVERFLOW.throw()
+ }
+
+ dt := toDTFromUnix(x-Seconds_1900_1970, 0)
+ return encode(dt, destDType, scale, lTz)
+
+ case TIME:
+ dt := toDTFromUnix(x, 0)
+ return encode(dt, destDType, scale, lTz)
+
+ case DATE:
+
+ if x > 2958463 {
+ return nil, ECGO_DATETIME_OVERFLOW.throw()
+ }
+
+ dt := toDTFromUnix(x*24*60*60-Seconds_1900_1970, 0)
+ if dt[OFFSET_YEAR] < -4712 || dt[OFFSET_YEAR] > 9999 {
+ return nil, ECGO_DATETIME_OVERFLOW.throw()
+ }
+ return encode(dt, destDType, scale, lTz)
+
+ default:
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+
+ }
+}
+
+func toTimeFromString(str string, ltz int) time.Time {
+ dt := make([]int, DT_LEN)
+ toDTFromString(str, dt)
+ return toTimeFromDT(dt, ltz)
+}
+
+func toTimeFromDT(dt []int, ltz int) time.Time {
+ var year, month, day, hour, minute, second, nsec, tz int
+
+ year = dt[OFFSET_YEAR]
+
+ if dt[OFFSET_MONTH] > 0 {
+ month = dt[OFFSET_MONTH]
+ } else {
+ month = 1
+ }
+
+ if dt[OFFSET_DAY] > 0 {
+ day = dt[OFFSET_DAY]
+ } else {
+ day = 1
+ }
+
+ hour = dt[OFFSET_HOUR]
+ minute = dt[OFFSET_MINUTE]
+ second = dt[OFFSET_SECOND]
+ nsec = dt[OFFSET_MILLISECOND] * 1000
+ if dt[OFFSET_TIMEZONE] == INVALID_VALUE {
+ tz = ltz * 60
+ } else {
+ tz = dt[OFFSET_TIMEZONE] * 60
+ }
+ return time.Date(year, time.Month(month), day, hour, minute, second, nsec, time.FixedZone("", tz))
+}
+
+func decode(value []byte, isBdta bool, colType int, scale int, ltz int, dbtz int) []int {
+ var dt []int
+ if isBdta {
+ dt = dmdtDecodeBdta(value)
+ } else {
+ dt = dmdtDecodeFast(value)
+ }
+
+ if isLocalTimeZone(colType, scale) {
+ transformTZ(dt, dbtz, ltz)
+ scale = getLocalTimeZoneScale(colType, scale)
+ }
+
+ if scale > 0 && scale < 6 {
+ tmp := math.Pow10(6 - scale)
+ dt[OFFSET_MILLISECOND] = int(float64(dt[OFFSET_MILLISECOND]) / tmp * tmp)
+ }
+ return dt
+}
+
+func dmdtDecodeFast(value []byte) []int {
+ dt := make([]int, DT_LEN)
+ dt[OFFSET_TIMEZONE] = INVALID_VALUE
+
+ if len(value) == 3 {
+
+ dt[OFFSET_YEAR] = int(Dm_build_1220.Dm_build_1317(value, 0)) & 0x7FFF
+ if dt[OFFSET_YEAR] > 9999 {
+ dt[OFFSET_YEAR] = int(int16(dt[OFFSET_YEAR] | 0x8000))
+ }
+
+ dt[OFFSET_MONTH] = ((int(value[1]) >> 7) & 0x1) + ((int(value[2]) & 0x07) << 1)
+
+ dt[OFFSET_DAY] = ((int(value[2]) & 0xF8) >> 3) & 0x1f
+ } else if len(value) < 8 {
+
+ dt[OFFSET_HOUR] = int(value[0]) & 0x1F
+ dt[OFFSET_MINUTE] = ((int(value[0]) >> 5) & 0x07) + ((int(value[1]) & 0x07) << 3)
+ dt[OFFSET_SECOND] = ((int(value[1]) >> 3) & 0x1f) + ((int(value[2]) & 0x01) << 5)
+ dt[OFFSET_MILLISECOND] = ((int(value[2]) >> 1) & 0x7f) + ((int(value[3]) & 0x00ff) << 7) + ((int(value[4]) & 0x1F) << 15)
+
+ if len(value) > 5 {
+ dt[OFFSET_TIMEZONE] = int(Dm_build_1220.Dm_build_1317(value, 5))
+ }
+ } else {
+
+ dt[OFFSET_YEAR] = int(Dm_build_1220.Dm_build_1317(value, 0)) & 0x7FFF
+ if dt[OFFSET_YEAR] > 9999 {
+ dt[OFFSET_YEAR] = int(int16(dt[OFFSET_YEAR] | 0x8000))
+ }
+
+ dt[OFFSET_MONTH] = ((int(value[1]) >> 7) & 0x1) + ((int(value[2]) & 0x07) << 1)
+
+ dt[OFFSET_DAY] = ((int(value[2]) & 0xF8) >> 3) & 0x1f
+
+ dt[OFFSET_HOUR] = (int(value[3]) & 0x1F)
+
+ dt[OFFSET_MINUTE] = ((int(value[3]) >> 5) & 0x07) + ((int(value[4]) & 0x07) << 3)
+
+ dt[OFFSET_SECOND] = ((int(value[4]) >> 3) & 0x1f) + ((int(value[5]) & 0x01) << 5)
+
+ dt[OFFSET_MILLISECOND] = ((int(value[5]) >> 1) & 0x7f) + ((int(value[6]) & 0x00ff) << 7) + ((int(value[7]) & 0x1F) << 15)
+
+ if len(value) > 8 {
+ dt[OFFSET_TIMEZONE] = int(Dm_build_1220.Dm_build_1317(value, 8))
+ }
+ }
+ return dt
+}
+
+func dmdtDecodeBdta(value []byte) []int {
+ dt := make([]int, DT_LEN)
+ dt[OFFSET_YEAR] = int(Dm_build_1220.Dm_build_1317(value, 0))
+ dt[OFFSET_MONTH] = int(value[2] & 0xFF)
+ dt[OFFSET_DAY] = int(value[3] & 0xFF)
+ dt[OFFSET_HOUR] = int(value[4] & 0xFF)
+ dt[OFFSET_MINUTE] = int(value[5] & 0xFF)
+ dt[OFFSET_SECOND] = int(value[6] & 0xFF)
+ dt[OFFSET_MILLISECOND] = int((value[7] & 0xFF) + (value[8] << 8) + (value[9] << 16))
+ dt[OFFSET_TIMEZONE] = int(Dm_build_1220.Dm_build_1317(value, 10))
+ return dt
+}
+
+func dtToStringByOracleFormat(dt []int, oracleFormatPattern string, language int) string {
+ return format(dt, oracleFormatPattern, language)
+}
+
+func dtToString(dt []int, dtype int, scale int) string {
+ switch dtype {
+ case DATE:
+ return formatYear(dt[OFFSET_YEAR]) + "-" + format2(dt[OFFSET_MONTH]) + "-" + format2(dt[OFFSET_DAY])
+
+ case TIME:
+ if scale > 0 {
+ return format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + "." + formatMilliSecond(dt[OFFSET_MILLISECOND], scale)
+ } else {
+ return format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND])
+ }
+
+ case TIME_TZ:
+ if scale > 0 {
+ return format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + "." + formatMilliSecond(dt[OFFSET_MILLISECOND], scale) + " " + formatTZ(dt[OFFSET_TIMEZONE])
+ } else {
+ return format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + " " + formatTZ(dt[OFFSET_TIMEZONE])
+ }
+
+ case DATETIME:
+ if scale > 0 {
+ return formatYear(dt[OFFSET_YEAR]) + "-" + format2(dt[OFFSET_MONTH]) + "-" + format2(dt[OFFSET_DAY]) + " " + format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + "." + formatMilliSecond(dt[OFFSET_MILLISECOND], scale)
+ } else {
+ return formatYear(dt[OFFSET_YEAR]) + "-" + format2(dt[OFFSET_MONTH]) + "-" + format2(dt[OFFSET_DAY]) + " " + format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND])
+ }
+
+ case DATETIME_TZ:
+ if scale > 0 {
+ return formatYear(dt[OFFSET_YEAR]) + "-" + format2(dt[OFFSET_MONTH]) + "-" + format2(dt[OFFSET_DAY]) + " " + format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + "." + formatMilliSecond(dt[OFFSET_MILLISECOND], scale) + " " + formatTZ(dt[OFFSET_TIMEZONE])
+ } else {
+ return formatYear(dt[OFFSET_YEAR]) + "-" + format2(dt[OFFSET_MONTH]) + "-" + format2(dt[OFFSET_DAY]) + " " + format2(dt[OFFSET_HOUR]) + ":" + format2(dt[OFFSET_MINUTE]) + ":" + format2(dt[OFFSET_SECOND]) + " " + formatTZ(dt[OFFSET_TIMEZONE])
+ }
+ }
+
+ return ""
+}
+
+func formatYear(value int) string {
+ if value >= 0 {
+ if value < 10 {
+ return "000" + strconv.FormatInt(int64(value), 10)
+ } else if value < 100 {
+ return "00" + strconv.FormatInt(int64(value), 10)
+ } else if value < 1000 {
+ return "0" + strconv.FormatInt(int64(value), 10)
+ } else {
+ return strconv.FormatInt(int64(value), 10)
+ }
+ } else {
+ if value > -10 {
+ return "-000" + strconv.FormatInt(int64(-value), 10)
+ } else if value > -100 {
+ return "-00" + strconv.FormatInt(int64(-value), 10)
+ } else if value > -1000 {
+ return "-0" + strconv.FormatInt(int64(-value), 10)
+ } else {
+ return strconv.FormatInt(int64(-value), 10)
+ }
+ }
+}
+
+func format2(value int) string {
+ if value < 10 {
+ return "0" + strconv.FormatInt(int64(value), 10)
+ } else {
+ return strconv.FormatInt(int64(value), 10)
+ }
+}
+
+func formatMilliSecond(ms int, prec int) string {
+ var ret string
+ if ms < 10 {
+ ret = "00000" + strconv.FormatInt(int64(ms), 10)
+ } else if ms < 100 {
+ ret = "0000" + strconv.FormatInt(int64(ms), 10)
+ } else if ms < 1000 {
+ ret = "000" + strconv.FormatInt(int64(ms), 10)
+ } else if ms < 10000 {
+ ret = "00" + strconv.FormatInt(int64(ms), 10)
+ } else if ms < 100000 {
+ ret = "0" + strconv.FormatInt(int64(ms), 10)
+ } else {
+ ret = strconv.FormatInt(int64(ms), 10)
+ }
+
+ if prec < 6 {
+ ret = ret[:prec]
+ }
+ return ret
+}
+
+func formatTZ(tz int) string {
+ tz_hour := int(math.Abs(float64(tz / 60)))
+ tz_min := int(math.Abs(float64(tz % 60)))
+
+ if tz >= 0 {
+ return "+" + format2(tz_hour) + ":" + format2(tz_min)
+ } else {
+ return "-" + format2(tz_hour) + ":" + format2(tz_min)
+ }
+}
+
+func toDTFromTime(x time.Time) []int {
+ hour, min, sec := x.Clock()
+ ts := make([]int, DT_LEN)
+ ts[OFFSET_YEAR] = x.Year()
+ ts[OFFSET_MONTH] = int(x.Month())
+ ts[OFFSET_DAY] = x.Day()
+ ts[OFFSET_HOUR] = hour
+ ts[OFFSET_MINUTE] = min
+ ts[OFFSET_SECOND] = sec
+ ts[OFFSET_MILLISECOND] = (int)(x.Nanosecond() / 1000)
+ _, tz := x.Zone()
+ ts[OFFSET_TIMEZONE] = tz / 60
+ return ts
+}
+
+func toDTFromUnix(sec int64, nsec int64) []int {
+ return toDTFromTime(time.Unix(sec, nsec))
+}
+
+func toDTFromString(s string, dt []int) (dtype int, err error) {
+ defer func() {
+ if p := recover(); p != nil {
+ err = ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ }()
+ date_s := ""
+ time_s := ""
+ nanos_s := ""
+ tz_s := ""
+ year := 0
+ month := 0
+ day := 0
+ hour := 0
+ minute := 0
+ second := 0
+ a_nanos := 0
+ firstDash := -1
+ secondDash := -1
+ firstColon := -1
+ secondColon := -1
+ period := -1
+ sign := 0
+ ownTz := INVALID_VALUE
+ dtype = -1
+
+ zeros := "000000000"
+
+ if s != "" && strings.TrimSpace(s) == "" {
+ return 0, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ s = strings.TrimSpace(s)
+
+ if strings.Index(s, "-") == 0 {
+ s = strings.TrimSpace(s[1:])
+ sign = 1
+ }
+
+ comps := strings.Split(s, " ")
+
+ switch len(comps) {
+ case 3:
+ date_s = comps[0]
+ time_s = comps[1]
+ tz_s = comps[2]
+ dtype = DATETIME_TZ
+
+ case 2:
+ if strings.Index(comps[0], ":") > 0 {
+ time_s = comps[0]
+ tz_s = comps[1]
+ dtype = TIME_TZ
+ } else {
+ date_s = comps[0]
+ time_s = comps[1]
+ dtype = DATETIME
+ }
+
+ case 1:
+ if strings.Index(comps[0], ":") > 0 {
+ time_s = comps[0]
+ dtype = TIME
+ } else {
+ date_s = comps[0]
+ dtype = DATE
+ }
+
+ default:
+ return 0, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+
+ if date_s != "" {
+
+ firstDash = strings.Index(date_s, "-")
+ secondDash = strings.Index(date_s[firstDash+1:], "-")
+
+ if firstDash < 0 || secondDash < 0 {
+ firstDash = strings.Index(s, ".")
+ secondDash = strings.Index(date_s[firstDash+1:], ".")
+ }
+
+ if firstDash < 0 || secondDash < 0 {
+ firstDash = strings.Index(s, "/")
+ secondDash = strings.Index(date_s[firstDash+1:], "/")
+ }
+ if secondDash > 0 {
+ secondDash += firstDash + 1
+ }
+
+ if (firstDash > 0) && (secondDash > 0) && (secondDash < len(date_s)-1) {
+
+ if sign == 1 {
+ i, err := strconv.ParseInt(date_s[:firstDash], 10, 32)
+ if err != nil {
+ return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
+ }
+ year = 0 - int(i) - 1900
+ } else {
+ i, err := strconv.ParseInt(date_s[:firstDash], 10, 32)
+ if err != nil {
+ return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
+ }
+ year = int(i) - 1900
+ }
+
+ i, err := strconv.ParseInt(date_s[firstDash+1:secondDash], 10, 32)
+ if err != nil {
+ return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
+ }
+ month = int(i) - 1
+
+ i, err = strconv.ParseInt(date_s[secondDash+1:], 10, 32)
+ if err != nil {
+ return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
+ }
+ day = int(i)
+
+ if !checkDate(year+1900, month+1, day) {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ } else {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ }
+
+ if time_s != "" {
+ firstColon = strings.Index(time_s, ":")
+ secondColon = strings.Index(time_s[firstColon+1:], ":")
+ if secondColon > 0 {
+ secondColon += firstColon + 1
+ }
+
+ period = strings.Index(time_s[secondColon+1:], ".")
+ if period > 0 {
+ period += secondColon + 1
+ }
+
+ if (firstColon > 0) && (secondColon > 0) && (secondColon < len(time_s)-1) {
+ i, err := strconv.ParseInt(time_s[:firstColon], 10, 32)
+ if err != nil {
+ return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
+ }
+ hour = int(i)
+
+ i, err = strconv.ParseInt(time_s[firstColon+1:secondColon], 10, 32)
+ if err != nil {
+ return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
+ }
+ minute = int(i)
+
+ if period > 0 && period < len(time_s)-1 {
+ i, err = strconv.ParseInt(time_s[secondColon+1:period], 10, 32)
+ if err != nil {
+ return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
+ }
+ second = int(i)
+
+ nanos_s = time_s[period+1:]
+ if len(nanos_s) > 9 {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ if !unicode.IsDigit(rune(nanos_s[0])) {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ nanos_s = nanos_s + zeros[0:9-len(nanos_s)]
+
+ i, err = strconv.ParseInt(nanos_s[:6], 10, 32)
+ if err != nil {
+ return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
+ }
+ a_nanos = int(i)
+ } else if period > 0 {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ } else {
+ i, err = strconv.ParseInt(time_s[secondColon+1:], 10, 32)
+ if err != nil {
+ return 0, ECGO_INVALID_DATETIME_FORMAT.addDetailln(err.Error()).throw()
+ }
+ second = int(i)
+ }
+
+ if hour >= 24 || hour < 0 || minute >= 60 || minute < 0 || second >= 60 || second < 0 {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ } else {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ }
+
+ if tz_s != "" {
+ neg := false
+ if strings.Index(tz_s, "-") == 0 {
+ neg = true
+ }
+
+ if strings.Index(tz_s, "-") == 0 || strings.Index(tz_s, "+") == 0 {
+ tz_s = strings.TrimSpace(tz_s[1:])
+ }
+
+ hm := strings.Split(tz_s, ":")
+ var tzh, tzm int16 = 0, 0
+ switch len(hm) {
+ case 2:
+ s, err := strconv.ParseInt(strings.TrimSpace(hm[0]), 10, 16)
+ if err != nil {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ tzh = int16(s)
+
+ s, err = strconv.ParseInt(strings.TrimSpace(hm[1]), 10, 16)
+ if err != nil {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ tzm = int16(s)
+ case 1:
+ s, err := strconv.ParseInt(strings.TrimSpace(hm[0]), 10, 16)
+ if err != nil {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ tzh = int16(s)
+ default:
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+
+ ownTz = int(tzh*60 + tzm)
+ if ownTz < 0 {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+
+ if neg {
+ ownTz *= -1
+ }
+
+ if ownTz <= -13*60 || ownTz > 14*60 {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ }
+
+ dt[OFFSET_YEAR] = year + 1900
+ dt[OFFSET_MONTH] = month + 1
+ if day == 0 {
+ dt[OFFSET_DAY] = 1
+ } else {
+ dt[OFFSET_DAY] = day
+ }
+ dt[OFFSET_HOUR] = hour
+ dt[OFFSET_MINUTE] = minute
+ dt[OFFSET_SECOND] = second
+ dt[OFFSET_MILLISECOND] = a_nanos
+ dt[OFFSET_TIMEZONE] = int(ownTz)
+ return dtype, nil
+}
+
+func transformTZ(dt []int, defaultSrcTz int, destTz int) {
+ srcTz := defaultSrcTz
+ if dt[OFFSET_TIMEZONE] != INVALID_VALUE {
+ srcTz = dt[OFFSET_TIMEZONE]
+ }
+
+ if destTz != srcTz {
+ dt = addMinute(dt, destTz-srcTz)
+ if dt[OFFSET_TIMEZONE] != INVALID_VALUE {
+ dt[OFFSET_TIMEZONE] = destTz
+ }
+ }
+}
+
+func encode(dt []int, dtype int, scale int, lTz int) ([]byte, error) {
+
+ if isLocalTimeZone(dtype, scale) && dt[OFFSET_TIMEZONE] != INVALID_VALUE && dt[OFFSET_TIMEZONE] != lTz {
+ transformTZ(dt, dt[OFFSET_TIMEZONE], lTz)
+ }
+
+ if dt[OFFSET_YEAR] < -4712 || dt[OFFSET_YEAR] > 9999 {
+ return nil, ECGO_DATETIME_OVERFLOW.throw()
+ }
+
+ year := dt[OFFSET_YEAR]
+
+ month := dt[OFFSET_MONTH]
+
+ day := dt[OFFSET_DAY]
+
+ hour := dt[OFFSET_HOUR]
+
+ min := dt[OFFSET_MINUTE]
+
+ sec := dt[OFFSET_SECOND]
+
+ msec := dt[OFFSET_MILLISECOND]
+
+ var tz int
+
+ if dt[OFFSET_TIMEZONE] == INVALID_VALUE {
+ tz = lTz
+ } else {
+ tz = dt[OFFSET_TIMEZONE]
+ }
+
+ var ret []byte
+
+ if dtype == DATE {
+ ret = make([]byte, 3)
+
+ ret[0] = (byte)(year & 0xFF)
+
+ if year >= 0 {
+ ret[1] = (byte)((year >> 8) | ((month & 0x01) << 7))
+ } else {
+ ret[1] = (byte)((year >> 8) & (((month & 0x01) << 7) | 0x7f))
+ }
+
+ ret[2] = (byte)(((month & 0x0E) >> 1) | (day << 3))
+ } else if dtype == DATETIME {
+ ret = make([]byte, 8)
+
+ ret[0] = (byte)(year & 0xFF)
+
+ if year >= 0 {
+ ret[1] = (byte)((year >> 8) | ((month & 0x01) << 7))
+ } else {
+ ret[1] = (byte)((year >> 8) & (((month & 0x01) << 7) | 0x7f))
+ }
+
+ ret[2] = (byte)(((month & 0x0E) >> 1) | (day << 3))
+
+ ret[3] = (byte)(hour | ((min & 0x07) << 5))
+
+ ret[4] = (byte)(((min & 0x38) >> 3) | ((sec & 0x1F) << 3))
+
+ ret[5] = (byte)(((sec & 0x20) >> 5) | ((msec & 0x7F) << 1))
+
+ ret[6] = (byte)((msec >> 7) & 0xFF)
+
+ ret[7] = (byte)((msec >> 15) & 0xFF)
+ } else if dtype == DATETIME_TZ {
+ ret = make([]byte, 10)
+
+ ret[0] = (byte)(year & 0xFF)
+
+ if year >= 0 {
+ ret[1] = (byte)((year >> 8) | ((month & 0x01) << 7))
+ } else {
+ ret[1] = (byte)((year >> 8) & (((month & 0x01) << 7) | 0x7f))
+ }
+
+ ret[2] = (byte)(((month & 0x0E) >> 1) | (day << 3))
+
+ ret[3] = (byte)(hour | ((min & 0x07) << 5))
+
+ ret[4] = (byte)(((min & 0x38) >> 3) | ((sec & 0x1F) << 3))
+
+ ret[5] = (byte)(((sec & 0x20) >> 5) | ((msec & 0x7F) << 1))
+
+ ret[6] = (byte)((msec >> 7) & 0xFF)
+
+ ret[7] = (byte)((msec >> 15) & 0xFF)
+
+ Dm_build_1220.Dm_build_1231(ret, 8, int16(tz))
+ } else if dtype == TIME {
+ ret = make([]byte, 5)
+
+ ret[0] = (byte)(hour | ((min & 0x07) << 5))
+
+ ret[1] = (byte)(((min & 0x38) >> 3) | ((sec & 0x1F) << 3))
+
+ ret[2] = (byte)(((sec & 0x20) >> 5) | ((msec & 0x7F) << 1))
+
+ ret[3] = (byte)((msec >> 7) & 0xFF)
+
+ ret[4] = (byte)((msec >> 15) & 0xFF)
+ } else if dtype == TIME_TZ {
+ ret = make([]byte, 7)
+
+ ret[0] = (byte)(hour | ((min & 0x07) << 5))
+
+ ret[1] = (byte)(((min & 0x38) >> 3) | ((sec & 0x1F) << 3))
+
+ ret[2] = (byte)(((sec & 0x20) >> 5) | ((msec & 0x7F) << 1))
+
+ ret[3] = (byte)((msec >> 7) & 0xFF)
+
+ ret[4] = (byte)((msec >> 15) & 0xFF)
+
+ Dm_build_1220.Dm_build_1231(ret, 5, int16(tz))
+ }
+
+ return ret, nil
+}
+
+func checkDate(year int, month int, day int) bool {
+ if year > 9999 || year < -4712 || month > 12 || month < 1 {
+ return false
+ }
+
+ monthDays := getDaysOfMonth(year, month)
+ if day > monthDays || day < 1 {
+ return false
+ }
+ return true
+}
+
+func getDaysOfMonth(year int, month int) int {
+ switch month {
+ case 1, 3, 5, 7, 8, 10, 12:
+ return 31
+ case 4, 6, 9, 11:
+ return 30
+ case 2:
+ if isLeapYear(year) {
+ return 29
+ }
+ return 28
+ default:
+ return 0
+ }
+}
+
+func isLeapYear(year int) bool {
+ return ((year%4 == 0 && year%100 != 0) || year%400 == 0)
+}
+
+func addYear(dt []int, n int) []int {
+ dt[OFFSET_YEAR] += n
+ return dt
+}
+
+func addMonth(dt []int, n int) []int {
+ month := dt[OFFSET_MONTH] + n
+ addYearValue := month / 12
+ if month %= 12; month < 1 {
+ month += 12
+ addYearValue--
+ }
+
+ daysOfMonth := getDaysOfMonth(dt[OFFSET_YEAR], month)
+ if dt[OFFSET_DAY] > daysOfMonth {
+ dt[OFFSET_DAY] = daysOfMonth
+ }
+
+ dt[OFFSET_MONTH] = month
+ addYear(dt, addYearValue)
+ return dt
+}
+
+func addDay(dt []int, n int) []int {
+ tmp := dt[OFFSET_DAY] + n
+ monthDays := 0
+ monthDays = getDaysOfMonth(dt[OFFSET_YEAR], dt[OFFSET_MONTH])
+ for tmp > monthDays || tmp <= 0 {
+ if tmp > monthDays {
+ addMonth(dt, 1)
+ tmp -= monthDays
+ } else {
+ addMonth(dt, -1)
+ tmp += monthDays
+ }
+ }
+ dt[OFFSET_DAY] = tmp
+ return dt
+}
+
+func addHour(dt []int, n int) []int {
+ hour := dt[OFFSET_HOUR] + n
+ addDayValue := hour / 24
+ if hour %= 24; hour < 0 {
+ hour += 24
+ addDayValue--
+ }
+
+ dt[OFFSET_HOUR] = hour
+ addDay(dt, addDayValue)
+ return dt
+}
+
+func addMinute(dt []int, n int) []int {
+ minute := dt[OFFSET_MINUTE] + n
+ addHourValue := minute / 60
+ if minute %= 60; minute < 0 {
+ minute += 60
+ addHourValue--
+ }
+
+ dt[OFFSET_MINUTE] = minute
+ addHour(dt, addHourValue)
+ return dt
+}
diff --git a/dmr/i.go b/dmr/i.go
new file mode 100644
index 0000000..30a28de
--- /dev/null
+++ b/dmr/i.go
@@ -0,0 +1,896 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "strconv"
+ "time"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+var DB2G db2g
+
+type db2g struct {
+}
+
+func (DB2G db2g) processVarchar2(bytes []byte, prec int) []byte {
+ rbytes := make([]byte, prec)
+ copy(rbytes[:len(bytes)], bytes[:])
+ for i := len(bytes); i < len(rbytes); i++ {
+ rbytes[i] = ' '
+ }
+ return rbytes
+}
+
+func (DB2G db2g) charToString(bytes []byte, column *column, conn *DmConnection) string {
+ if column.colType == VARCHAR2 {
+ bytes = DB2G.processVarchar2(bytes, int(column.prec))
+ } else if column.colType == CLOB {
+ clob := newClobFromDB(bytes, conn, column, true)
+ clobLen, _ := clob.GetLength()
+ clobStr, _ := clob.getSubString(1, int32(clobLen))
+ return clobStr
+ }
+ return Dm_build_1220.Dm_build_1470(bytes, conn.serverEncoding, conn)
+}
+
+func (DB2G db2g) charToFloat64(bytes []byte, column *column, conn *DmConnection) (float64, error) {
+ str := DB2G.charToString(bytes, column, conn)
+ val, err := strconv.ParseFloat(str, 64)
+ if err != nil {
+ return 0, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+
+ return val, nil
+}
+
+func (DB2G db2g) charToDeciaml(bytes []byte, column *column, conn *DmConnection) (*DmDecimal, error) {
+ str := DB2G.charToString(bytes, column, conn)
+ return NewDecimalFromString(str)
+}
+
+func (DB2G db2g) BinaryToInt64(bytes []byte, column *column, conn *DmConnection) (int64, error) {
+ if column.colType == BLOB {
+ blob := newBlobFromDB(bytes, conn, column, true)
+ blobLen, err := blob.GetLength()
+ if err != nil {
+ return 0, err
+ }
+ bytes, err = blob.getBytes(1, int32(blobLen))
+ if err != nil {
+ return 0, err
+ }
+ }
+ var n, b int64 = 0, 0
+
+ startIndex := 0
+ var length int
+ if len(bytes) > 8 {
+ length = 8
+ for j := 0; j < len(bytes)-8; j++ {
+ if bytes[j] != 0 {
+ return 0, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+
+ startIndex = len(bytes) - 8
+ length = 8
+ }
+ } else {
+ length = len(bytes)
+ }
+
+ for j := startIndex; j < startIndex+length; j++ {
+ b = int64(0xff & bytes[j])
+ n = b | (n << 8)
+ }
+
+ return n, nil
+}
+
+func (DB2G db2g) decToDecimal(bytes []byte, prec int, scale int, compatibleOracle bool) (*DmDecimal, error) {
+
+ if compatibleOracle {
+ prec = -1
+ scale = -1
+ }
+ return newDecimal(bytes, prec, scale)
+}
+
+func (DB2G db2g) toBytes(bytes []byte, column *column, conn *DmConnection) ([]byte, error) {
+ retBytes := Dm_build_1220.Dm_build_1371(bytes, 0, len(bytes))
+ switch column.colType {
+ case CLOB:
+ clob := newClobFromDB(retBytes, conn, column, true)
+ str, err := clob.getSubString(1, int32(clob.length))
+ if err != nil {
+ return nil, err
+ }
+
+ return Dm_build_1220.Dm_build_1433(str, conn.getServerEncoding(), conn), nil
+ case BLOB:
+ blob := newBlobFromDB(retBytes, conn, column, true)
+ bs, err := blob.getBytes(1, int32(blob.length))
+ if err != nil {
+ return nil, err
+ }
+
+ return bs, nil
+ }
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (DB2G db2g) toString(bytes []byte, column *column, conn *DmConnection) string {
+ switch column.colType {
+ case CHAR, VARCHAR, VARCHAR2:
+ return DB2G.charToString(bytes, column, conn)
+ case BIT, BOOLEAN, TINYINT:
+ return strconv.FormatInt(int64(bytes[0]), 10)
+ case SMALLINT:
+ return strconv.FormatInt(int64(Dm_build_1220.Dm_build_1441(bytes)), 10)
+ case INT:
+ return strconv.FormatInt(int64(Dm_build_1220.Dm_build_1444(bytes)), 10)
+ case BIGINT:
+ return strconv.FormatInt(int64(Dm_build_1220.Dm_build_1447(bytes)), 10)
+ case REAL:
+ return strconv.FormatFloat(float64(Dm_build_1220.Dm_build_1450(bytes)), 'f', -1, 32)
+ case DOUBLE:
+ return strconv.FormatFloat(float64(Dm_build_1220.Dm_build_1453(bytes)), 'f', -1, 64)
+ case DECIMAL:
+
+ case BINARY, VARBINARY:
+ util.StringUtil.BytesToHexString(bytes, false)
+ case BLOB:
+
+ case CLOB:
+
+ case DATE:
+ dt := decode(bytes, column.isBdta, int(column.colType), int(column.scale), int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
+ if conn.FormatDate != "" {
+ return dtToStringByOracleFormat(dt, conn.FormatDate, int(conn.OracleDateLanguage))
+ }
+ case TIME:
+ dt := decode(bytes, column.isBdta, int(column.colType), int(column.scale), int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
+ if conn.FormatTime != "" {
+ return dtToStringByOracleFormat(dt, conn.FormatTime, int(conn.OracleDateLanguage))
+ }
+ case DATETIME:
+ dt := decode(bytes, column.isBdta, int(column.colType), int(column.scale), int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
+ if conn.FormatTimestamp != "" {
+ return dtToStringByOracleFormat(dt, conn.FormatTimestamp, int(conn.OracleDateLanguage))
+ }
+ case TIME_TZ:
+ dt := decode(bytes, column.isBdta, int(column.colType), int(column.scale), int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
+ if conn.FormatTimeTZ != "" {
+ return dtToStringByOracleFormat(dt, conn.FormatTimeTZ, int(conn.OracleDateLanguage))
+ }
+ case DATETIME_TZ:
+ dt := decode(bytes, column.isBdta, int(column.colType), int(column.scale), int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
+ if conn.FormatTimestampTZ != "" {
+ return dtToStringByOracleFormat(dt, conn.FormatTimestampTZ, int(conn.OracleDateLanguage))
+ }
+ case INTERVAL_DT:
+ return newDmIntervalDTByBytes(bytes).String()
+ case INTERVAL_YM:
+ return newDmIntervalYMByBytes(bytes).String()
+ case ARRAY:
+
+ case SARRAY:
+
+ case CLASS:
+
+ case PLTYPE_RECORD:
+
+ }
+ return ""
+}
+
+func (DB2G db2g) toBool(bytes []byte, column *column, conn *DmConnection) (bool, error) {
+ switch column.colType {
+ case BIT, BOOLEAN, TINYINT:
+ return bytes[0] != 0, nil
+ case SMALLINT:
+ return Dm_build_1220.Dm_build_1317(bytes, 0) != 0, nil
+ case INT:
+ return Dm_build_1220.Dm_build_1322(bytes, 0) != 0, nil
+ case BIGINT:
+ return Dm_build_1220.Dm_build_1327(bytes, 0) != 0, nil
+ case REAL:
+ return Dm_build_1220.Dm_build_1332(bytes, 0) != 0, nil
+ case DOUBLE:
+ return Dm_build_1220.Dm_build_1336(bytes, 0) != 0, nil
+ case DECIMAL:
+
+ case CHAR, VARCHAR, VARCHAR2, CLOB:
+ return G2DB.toBool(DB2G.charToString(bytes, column, conn))
+ }
+
+ return false, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (DB2G db2g) toByte(bytes []byte, column *column, conn *DmConnection) (byte, error) {
+ switch column.colType {
+ case BIT, BOOLEAN, TINYINT:
+
+ if bytes == nil || len(bytes) == 0 {
+ return 0, nil
+ } else {
+ return bytes[0], nil
+ }
+ case SMALLINT:
+ tval := Dm_build_1220.Dm_build_1317(bytes, 0)
+ if tval < int16(BYTE_MIN) || tval > int16(BYTE_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return byte(tval), nil
+ case INT:
+ tval := Dm_build_1220.Dm_build_1322(bytes, 0)
+ if tval < int32(BYTE_MIN) || tval > int32(BYTE_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return byte(tval), nil
+ case BIGINT:
+ tval := Dm_build_1220.Dm_build_1327(bytes, 0)
+ if tval < int64(BYTE_MIN) || tval > int64(BYTE_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return byte(tval), nil
+ case REAL:
+ tval := Dm_build_1220.Dm_build_1332(bytes, 0)
+ if tval < float32(BYTE_MIN) || tval > float32(BYTE_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return byte(tval), nil
+ case DOUBLE:
+ tval := Dm_build_1220.Dm_build_1336(bytes, 0)
+ if tval < float64(BYTE_MIN) || tval > float64(BYTE_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return byte(tval), nil
+ case DECIMAL:
+
+ case CHAR, VARCHAR, VARCHAR2, CLOB:
+ tval, err := DB2G.charToFloat64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ if tval < float64(BYTE_MIN) || tval > float64(BYTE_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return byte(tval), nil
+ case BINARY, VARBINARY, BLOB:
+ {
+ tval, err := DB2G.BinaryToInt64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ if tval < int64(BYTE_MIN) || tval > int64(BYTE_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return byte(tval), nil
+ }
+ }
+
+ return 0, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (DB2G db2g) toInt8(bytes []byte, column *column, conn *DmConnection) (int8, error) {
+ switch column.colType {
+ case BIT, BOOLEAN, TINYINT:
+ if bytes == nil || len(bytes) == 0 {
+ return 0, nil
+ }
+
+ return int8(bytes[0]), nil
+ case SMALLINT:
+ tval := Dm_build_1220.Dm_build_1317(bytes, 0)
+ if tval < int16(INT8_MIN) || tval < int16(INT8_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int8(tval), nil
+ case INT:
+
+ tval := Dm_build_1220.Dm_build_1322(bytes, 0)
+ if tval < int32(INT8_MIN) || tval > int32(INT8_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int8(tval), nil
+ case BIGINT:
+ tval := Dm_build_1220.Dm_build_1327(bytes, 0)
+ if tval < int64(INT8_MIN) || tval > int64(INT8_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int8(tval), nil
+ case REAL:
+ tval := Dm_build_1220.Dm_build_1332(bytes, 0)
+ if tval < float32(INT8_MIN) || tval > float32(INT8_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int8(tval), nil
+ case DOUBLE:
+ tval := Dm_build_1220.Dm_build_1336(bytes, 0)
+ if tval < float64(INT8_MIN) || tval > float64(INT8_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int8(tval), nil
+ case DECIMAL:
+
+ case CHAR, VARCHAR, VARCHAR2, CLOB:
+ tval, err := DB2G.charToFloat64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ if tval < float64(INT8_MIN) || tval > float64(INT8_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int8(tval), nil
+ case BINARY, VARBINARY, BLOB:
+ {
+ tval, err := DB2G.BinaryToInt64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ if tval < int64(INT8_MIN) || tval > int64(INT8_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int8(tval), nil
+ }
+ }
+
+ return 0, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (DB2G db2g) toInt16(bytes []byte, column *column, conn *DmConnection) (int16, error) {
+ switch column.colType {
+ case BIT, BOOLEAN, TINYINT:
+ if bytes == nil || len(bytes) == 0 {
+ return 0, nil
+ }
+
+ return int16(bytes[0]), nil
+ case SMALLINT:
+ return Dm_build_1220.Dm_build_1317(bytes, 0), nil
+ case INT:
+
+ tval := Dm_build_1220.Dm_build_1322(bytes, 0)
+ if tval < int32(INT16_MIN) || tval > int32(INT16_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int16(tval), nil
+ case BIGINT:
+ tval := Dm_build_1220.Dm_build_1327(bytes, 0)
+ if tval < int64(INT16_MIN) || tval > int64(INT16_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int16(tval), nil
+ case REAL:
+ tval := Dm_build_1220.Dm_build_1332(bytes, 0)
+ if tval < float32(INT16_MIN) || tval > float32(INT16_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int16(tval), nil
+ case DOUBLE:
+ tval := Dm_build_1220.Dm_build_1336(bytes, 0)
+ if tval < float64(INT16_MIN) || tval > float64(INT16_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int16(tval), nil
+ case DECIMAL:
+
+ case CHAR, VARCHAR, VARCHAR2, CLOB:
+ tval, err := DB2G.charToFloat64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ if tval < float64(INT16_MIN) || tval > float64(INT16_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int16(tval), nil
+ case BINARY, VARBINARY, BLOB:
+ {
+ tval, err := DB2G.BinaryToInt64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ if tval < int64(INT16_MIN) || tval > int64(INT16_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int16(tval), nil
+ }
+ }
+
+ return 0, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (DB2G db2g) toUInt16(bytes []byte, column *column, conn *DmConnection) (uint16, error) {
+ switch column.colType {
+ case BIT, BOOLEAN, TINYINT:
+ if bytes == nil || len(bytes) == 0 {
+ return 0, nil
+ }
+
+ return uint16(bytes[0]), nil
+ case SMALLINT:
+ return uint16(Dm_build_1220.Dm_build_1317(bytes, 0)), nil
+ case INT:
+ tval := Dm_build_1220.Dm_build_1322(bytes, 0)
+ if tval < int32(UINT16_MIN) || tval > int32(UINT16_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return uint16(tval), nil
+ case BIGINT:
+ tval := Dm_build_1220.Dm_build_1327(bytes, 0)
+ if tval < int64(UINT16_MIN) || tval > int64(UINT16_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return uint16(tval), nil
+ case REAL:
+ tval := Dm_build_1220.Dm_build_1332(bytes, 0)
+ if tval < float32(UINT16_MIN) || tval > float32(UINT16_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return uint16(tval), nil
+ case DOUBLE:
+ tval := Dm_build_1220.Dm_build_1336(bytes, 0)
+ if tval < float64(UINT16_MIN) || tval > float64(UINT16_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return uint16(tval), nil
+ case DECIMAL:
+
+ case CHAR, VARCHAR, VARCHAR2, CLOB:
+ tval, err := DB2G.charToFloat64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ if tval < float64(UINT16_MIN) || tval > float64(UINT16_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return uint16(tval), nil
+ case BINARY, VARBINARY, BLOB:
+ {
+ tval, err := DB2G.BinaryToInt64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ if tval < int64(UINT16_MIN) || tval > int64(UINT16_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return uint16(tval), nil
+ }
+ }
+
+ return 0, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (DB2G db2g) toInt32(bytes []byte, column *column, conn *DmConnection) (int32, error) {
+ switch column.colType {
+ case BIT, BOOLEAN, TINYINT:
+ if bytes == nil || len(bytes) == 0 {
+ return 0, nil
+ }
+
+ return int32(bytes[0]), nil
+ case SMALLINT:
+ return int32(Dm_build_1220.Dm_build_1317(bytes, 0)), nil
+ case INT:
+ return Dm_build_1220.Dm_build_1322(bytes, 0), nil
+ case BIGINT:
+ tval := Dm_build_1220.Dm_build_1327(bytes, 0)
+ if tval < int64(INT32_MIN) || tval > int64(INT32_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int32(tval), nil
+ case REAL:
+ tval := Dm_build_1220.Dm_build_1332(bytes, 0)
+ if tval < float32(INT32_MIN) || tval > float32(INT32_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int32(tval), nil
+ case DOUBLE:
+ tval := Dm_build_1220.Dm_build_1336(bytes, 0)
+ if tval < float64(INT32_MIN) || tval > float64(INT32_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int32(tval), nil
+ case DECIMAL:
+
+ case CHAR, VARCHAR, VARCHAR2, CLOB:
+ tval, err := DB2G.charToFloat64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ if tval < float64(INT32_MIN) || tval > float64(INT32_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int32(tval), nil
+ case BINARY, VARBINARY, BLOB:
+ {
+ tval, err := DB2G.BinaryToInt64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ if tval < int64(INT32_MIN) || tval > int64(INT32_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int32(tval), nil
+ }
+ }
+
+ return 0, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (DB2G db2g) toUInt32(bytes []byte, column *column, conn *DmConnection) (uint32, error) {
+ switch column.colType {
+ case BIT, BOOLEAN, TINYINT:
+ if bytes == nil || len(bytes) == 0 {
+ return 0, nil
+ }
+
+ return uint32(bytes[0]), nil
+ case SMALLINT:
+ return uint32(Dm_build_1220.Dm_build_1317(bytes, 0)), nil
+ case INT:
+ return uint32(Dm_build_1220.Dm_build_1322(bytes, 0)), nil
+ case BIGINT:
+ tval := Dm_build_1220.Dm_build_1327(bytes, 0)
+ if tval < int64(UINT32_MIN) || tval > int64(UINT32_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return uint32(tval), nil
+ case REAL:
+ tval := Dm_build_1220.Dm_build_1332(bytes, 0)
+ if tval < float32(UINT32_MIN) || tval > float32(UINT32_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return uint32(tval), nil
+ case DOUBLE:
+ tval := Dm_build_1220.Dm_build_1336(bytes, 0)
+ if tval < float64(UINT32_MIN) || tval > float64(UINT32_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return uint32(tval), nil
+ case DECIMAL:
+
+ case CHAR, VARCHAR, VARCHAR2, CLOB:
+ tval, err := DB2G.charToFloat64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ if tval < float64(UINT32_MIN) || tval > float64(UINT32_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return uint32(tval), nil
+ case BINARY, VARBINARY, BLOB:
+ {
+ tval, err := DB2G.BinaryToInt64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ if tval < int64(UINT32_MIN) || tval > int64(UINT32_MAX) {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return uint32(tval), nil
+ }
+ }
+
+ return 0, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (DB2G db2g) toInt64(bytes []byte, column *column, conn *DmConnection) (int64, error) {
+ switch column.colType {
+ case BOOLEAN, BIT, TINYINT:
+ if bytes == nil || len(bytes) == 0 {
+ return int64(0), nil
+ } else {
+ return int64(bytes[0]), nil
+ }
+ case SMALLINT:
+ return int64(Dm_build_1220.Dm_build_1441(bytes)), nil
+ case INT:
+ return int64(Dm_build_1220.Dm_build_1444(bytes)), nil
+ case BIGINT:
+ return int64(Dm_build_1220.Dm_build_1447(bytes)), nil
+ case REAL:
+ return int64(Dm_build_1220.Dm_build_1450(bytes)), nil
+ case DOUBLE:
+ return int64(Dm_build_1220.Dm_build_1453(bytes)), nil
+
+ case CHAR, VARCHAR2, VARCHAR, CLOB:
+ tval, err := DB2G.charToFloat64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ if int64(tval) < INT64_MIN || int64(tval) > INT64_MAX {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return int64(tval), nil
+ case BINARY, VARBINARY, BLOB:
+ tval, err := DB2G.BinaryToInt64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ return tval, nil
+ }
+ return 0, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (DB2G db2g) toUInt64(bytes []byte, column *column, conn *DmConnection) (uint64, error) {
+ switch column.colType {
+ case BOOLEAN, BIT, TINYINT:
+ if bytes == nil || len(bytes) == 0 {
+ return uint64(0), nil
+ } else {
+ return uint64(bytes[0]), nil
+ }
+ case SMALLINT:
+ return uint64(Dm_build_1220.Dm_build_1441(bytes)), nil
+ case INT:
+ return uint64(Dm_build_1220.Dm_build_1444(bytes)), nil
+ case BIGINT:
+ return uint64(Dm_build_1220.Dm_build_1447(bytes)), nil
+ case REAL:
+ return uint64(Dm_build_1220.Dm_build_1450(bytes)), nil
+ case DOUBLE:
+ return uint64(Dm_build_1220.Dm_build_1453(bytes)), nil
+
+ case CHAR, VARCHAR2, VARCHAR, CLOB:
+ tval, err := DB2G.charToFloat64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ if uint64(tval) < UINT64_MIN || uint64(tval) > UINT64_MAX {
+ return 0, ECGO_DATA_OVERFLOW.throw()
+ }
+ return uint64(tval), nil
+ case BINARY, VARBINARY, BLOB:
+ tval, err := DB2G.BinaryToInt64(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+
+ return uint64(tval), nil
+ }
+ return 0, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (DB2G db2g) toInt(bytes []byte, column *column, conn *DmConnection) (int, error) {
+ if strconv.IntSize == 32 {
+ tmp, err := DB2G.toInt32(bytes, column, conn)
+ return int(tmp), err
+ } else {
+ tmp, err := DB2G.toInt64(bytes, column, conn)
+ return int(tmp), err
+ }
+}
+
+func (DB2G db2g) toUInt(bytes []byte, column *column, conn *DmConnection) (uint, error) {
+ if strconv.IntSize == 32 {
+ tmp, err := DB2G.toUInt32(bytes, column, conn)
+ return uint(tmp), err
+ } else {
+ tmp, err := DB2G.toUInt64(bytes, column, conn)
+ return uint(tmp), err
+ }
+}
+
+func (DB2G db2g) toFloat32(bytes []byte, column *column, conn *DmConnection) (float32, error) {
+ switch column.colType {
+ case BIT, BOOLEAN, TINYINT:
+ if bytes == nil || len(bytes) == 0 {
+ return 0, nil
+ }
+ return float32(bytes[0]), nil
+ case SMALLINT:
+ return float32(Dm_build_1220.Dm_build_1317(bytes, 0)), nil
+ case INT:
+ return float32(Dm_build_1220.Dm_build_1322(bytes, 0)), nil
+ case BIGINT:
+ return float32(Dm_build_1220.Dm_build_1327(bytes, 0)), nil
+ case REAL:
+ return Dm_build_1220.Dm_build_1332(bytes, 0), nil
+ case DOUBLE:
+ dval := Dm_build_1220.Dm_build_1336(bytes, 0)
+ return float32(dval), nil
+ case DECIMAL:
+ dval, err := DB2G.decToDecimal(bytes, int(column.prec), int(column.scale), conn.CompatibleOracle())
+ if err != nil {
+ return 0, err
+ }
+ return float32(dval.ToFloat64()), nil
+ case CHAR, VARCHAR2, VARCHAR, CLOB:
+ dval, err := DB2G.charToDeciaml(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+ return float32(dval.ToFloat64()), nil
+ }
+ return 0, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (DB2G db2g) toFloat64(bytes []byte, column *column, conn *DmConnection) (float64, error) {
+ switch column.colType {
+ case BIT, BOOLEAN, TINYINT:
+ if bytes == nil || len(bytes) == 0 {
+ return 0, nil
+ }
+ return float64(bytes[0]), nil
+ case SMALLINT:
+ return float64(Dm_build_1220.Dm_build_1317(bytes, 0)), nil
+ case INT:
+ return float64(Dm_build_1220.Dm_build_1322(bytes, 0)), nil
+ case BIGINT:
+ return float64(Dm_build_1220.Dm_build_1327(bytes, 0)), nil
+ case REAL:
+ return float64(Dm_build_1220.Dm_build_1332(bytes, 0)), nil
+ case DOUBLE:
+ return Dm_build_1220.Dm_build_1336(bytes, 0), nil
+ case DECIMAL:
+ dval, err := DB2G.decToDecimal(bytes, int(column.prec), int(column.scale), conn.CompatibleOracle())
+ if err != nil {
+ return 0, err
+ }
+ return dval.ToFloat64(), nil
+ case CHAR, VARCHAR2, VARCHAR, CLOB:
+ dval, err := DB2G.charToDeciaml(bytes, column, conn)
+ if err != nil {
+ return 0, err
+ }
+ return dval.ToFloat64(), nil
+ }
+
+ return 0, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (DB2G db2g) toDmBlob(value []byte, column *column, conn *DmConnection) *DmBlob {
+
+ switch column.colType {
+ case BLOB:
+ return newBlobFromDB(value, conn, column, conn.lobFetchAll())
+ }
+
+ return nil
+}
+
+func (DB2G db2g) toDmClob(value []byte, conn *DmConnection, column *column) *DmClob {
+
+ switch column.colType {
+ case CLOB:
+ return newClobFromDB(value, conn, column, conn.lobFetchAll())
+ }
+
+ return nil
+}
+
+func (DB2G db2g) toDmDecimal(value []byte, column *column, conn *DmConnection) (*DmDecimal, error) {
+
+ switch column.colType {
+ case BIT, BOOLEAN, TINYINT:
+ if value == nil || len(value) == 0 {
+ return NewDecimalFromInt64(0)
+ } else {
+ return NewDecimalFromInt64(int64(value[0]))
+ }
+ case SMALLINT:
+ return NewDecimalFromInt64(int64(Dm_build_1220.Dm_build_1317(value, 0)))
+ case INT:
+ return NewDecimalFromInt64(int64(Dm_build_1220.Dm_build_1322(value, 0)))
+ case BIGINT:
+ return NewDecimalFromInt64(Dm_build_1220.Dm_build_1327(value, 0))
+ case REAL:
+ return NewDecimalFromFloat64(float64(Dm_build_1220.Dm_build_1332(value, 0)))
+ case DOUBLE:
+ return NewDecimalFromFloat64(Dm_build_1220.Dm_build_1336(value, 0))
+ case DECIMAL:
+ return decodeDecimal(value, int(column.prec), int(column.scale))
+ case CHAR, VARCHAR, VARCHAR2, CLOB:
+ return DB2G.charToDeciaml(value, column, conn)
+ }
+
+ return nil, ECGO_DATA_CONVERTION_ERROR
+}
+
+func (DB2G db2g) toTime(bytes []byte, column *column, conn *DmConnection) (time.Time, error) {
+ switch column.colType {
+ case DATE, TIME, TIME_TZ, DATETIME_TZ, DATETIME:
+ dt := decode(bytes, column.isBdta, int(column.colType), int(column.scale), int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
+ return toTimeFromDT(dt, int(conn.dmConnector.localTimezone)), nil
+ case CHAR, VARCHAR2, VARCHAR, CLOB:
+ return toTimeFromString(DB2G.charToString(bytes, column, conn), int(conn.dmConnector.localTimezone)), nil
+ }
+ return time.Now(), ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (DB2G db2g) toObject(bytes []byte, column *column, conn *DmConnection) (interface{}, error) {
+
+ switch column.colType {
+ case BIT, BOOLEAN:
+ return bytes[0] != 0, nil
+
+ case TINYINT:
+
+ return Dm_build_1220.Dm_build_1313(bytes, 0), nil
+ case SMALLINT:
+ return Dm_build_1220.Dm_build_1317(bytes, 0), nil
+ case INT:
+ return Dm_build_1220.Dm_build_1322(bytes, 0), nil
+ case BIGINT:
+ return Dm_build_1220.Dm_build_1327(bytes, 0), nil
+ case DECIMAL:
+
+ case REAL:
+ return Dm_build_1220.Dm_build_1332(bytes, 0), nil
+ case DOUBLE:
+ return Dm_build_1220.Dm_build_1336(bytes, 0), nil
+ case DATE, TIME, DATETIME, TIME_TZ, DATETIME_TZ:
+ dt := decode(bytes, column.isBdta, int(column.colType), int(column.scale), int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
+ return toTimeFromDT(dt, int(conn.dmConnector.localTimezone)), nil
+ case BINARY, VARBINARY:
+ return bytes, nil
+ case BLOB:
+ blob := newBlobFromDB(bytes, conn, column, conn.lobFetchAll())
+
+ if util.StringUtil.EqualsIgnoreCase(column.typeName, "LONGVARBINARY") {
+
+ l, err := blob.GetLength()
+ if err != nil {
+ return nil, err
+ }
+ return blob.getBytes(1, int32(l))
+ } else {
+ return blob, nil
+ }
+ case CHAR, VARCHAR, VARCHAR2:
+ val := DB2G.charToString(bytes, column, conn)
+ if isBFile(int(column.colType), int(column.prec), int(column.scale)) {
+
+ }
+
+ return val, nil
+ case CLOB:
+ clob := newClobFromDB(bytes, conn, column, conn.lobFetchAll())
+ if util.StringUtil.EqualsIgnoreCase(column.typeName, "LONGVARCHAR") {
+
+ l, err := clob.GetLength()
+ if err != nil {
+ return nil, err
+ }
+ return clob.getSubString(1, int32(l))
+ } else {
+ return clob, nil
+ }
+ case INTERVAL_YM:
+ return newDmIntervalYMByBytes(bytes), nil
+ case INTERVAL_DT:
+ return newDmIntervalDTByBytes(bytes), nil
+ case ARRAY:
+ return TypeDataSV.bytesToArray(bytes, nil, column.typeDescriptor)
+ case SARRAY:
+ return TypeDataSV.bytesToSArray(bytes, nil, column.typeDescriptor)
+ case CLASS:
+
+ case PLTYPE_RECORD:
+
+ default:
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+}
diff --git a/dmr/i18n/zj.go b/dmr/i18n/zj.go
new file mode 100644
index 0000000..62b5bfd
--- /dev/null
+++ b/dmr/i18n/zj.go
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package i18n
+
+import (
+ "encoding/json"
+ "golang.org/x/text/language"
+ "golang.org/x/text/message"
+)
+
+type msg struct {
+ Id string `json:"id"`
+ Translation string `json:"translation,omitempty"`
+}
+
+type i18n struct {
+ Language string `json:"language"`
+ Messages []msg `json:"messages"`
+}
+
+func InitConfig(jsonStr string) {
+
+ var i18n i18n
+ json.Unmarshal([]byte(jsonStr), &i18n)
+ msaArry := i18n.Messages
+ tag := language.MustParse(i18n.Language)
+ for _, e := range msaArry {
+ message.SetString(tag, e.Id, e.Translation)
+ }
+}
+
+func Get(key string, locale int) string {
+ var p *message.Printer
+
+ switch locale {
+ case 0:
+ p = message.NewPrinter(language.SimplifiedChinese)
+ case 1:
+ p = message.NewPrinter(language.AmericanEnglish)
+ case 2:
+ p = message.NewPrinter(language.TraditionalChinese)
+ }
+
+ return p.Sprintf(key)
+}
diff --git a/dmr/i18n/zk.go b/dmr/i18n/zk.go
new file mode 100644
index 0000000..f69a9b8
--- /dev/null
+++ b/dmr/i18n/zk.go
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package i18n
+
+const Messages_en_US = `{
+ "language": "en-US",
+ "messages": [
+ {
+ "id": "error.dsn.invalidSchema",
+ "translation": "DSN must start with dm://"
+ },
+ {
+ "id": "error.unsupported.scan",
+ "translation": "Unsupported scan type"
+ },
+ {
+ "id": "error.invalidParameterNumber",
+ "translation": "Invalid parameter number"
+ },
+ {
+ "id": "error.initThirdPartCipherFailed",
+ "translation": "Init third part cipher failed"
+ },
+ {
+ "id": "error.connectionSwitchFailed",
+ "translation": "Connection switch failed"
+ },
+ {
+ "id": "error.connectionSwitched",
+ "translation": "Connection has been switched"
+ },
+ {
+ "id": "error.invalidServerMode",
+ "translation": "Invalid server mode"
+ },
+ {
+ "id": "error.osauthError",
+ "translation": "At the same time using the specifed user login and OS authentication login, please determine a way."
+ },
+ {
+ "id": "error.notQuerySQL",
+ "translation": "The SQL is not a query SQL"
+ },
+ {
+ "id": "error.notExecSQL",
+ "translation": "The SQL is not a execute SQL"
+ },
+ {
+ "id": "error.invalidTranIsolation",
+ "translation": "invalid Transaltion Isolation"
+ },
+ {
+ "id": "errorCommitInAutoCommitMode",
+ "translation": "Can't commit in Auto commit status"
+ },
+ {
+ "id": "errorCommitInAutoCommitMode",
+ "translation": "Can't rollback in Auto commit status"
+ },
+ {
+ "id": "errorStatementHandleClosed",
+ "translation": "Statement handle is closed"
+ },
+ {
+ "id": "errorResultSetColsed",
+ "translation": "Resultset is closed"
+ },
+ {
+ "id": "error.communicationError",
+ "translation": "Communication error"
+ },
+ {
+ "id": "error.msgCheckError",
+ "translation": "Message check error"
+ },
+ {
+ "id": "error.unkownNetWork",
+ "translation": "Unkown net work"
+ },
+ {
+ "id": "error.serverVersion",
+ "translation": "Server version is too low"
+ },
+ {
+ "id": "error.usernameTooLong",
+ "translation": "Username is too long."
+ },
+ {
+ "id": "error.passwordTooLong",
+ "translation": "Password to login is too long."
+ },
+ {
+ "id": "error.dataTooLong",
+ "translation": "The data is too large to support."
+ },
+ {
+ "id": "error.invalidColumnType",
+ "translation": "Invalid column type"
+ },
+ {
+ "id": "error.dataConvertionError",
+ "translation": "Data convertion error"
+ },
+ {
+ "id": "error.invalidConn",
+ "translation": "Invalid connection"
+ },
+ {
+ "id": "error.invalidHex",
+ "translation": "Invalid Hex Number."
+ },
+ {
+ "id": "error.invalidBFile",
+ "translation": "Invalid BFile format string."
+ },
+ {
+ "id": "error.dataOverflow",
+ "translation": "Digital overflow"
+ },
+ {
+ "id": "error.invalidDateTimeFormat",
+ "translation": "Invalid datetime type format"
+ },
+ {
+ "id": "error.datetimeOverflow",
+ "translation": "Digital overflow"
+ },
+ {
+ "id": "error.invalidTimeInterval",
+ "translation": "Invalid time interval type value"
+ },
+ {
+ "id": "error.unsupportedInparamType",
+ "translation": "Unsupported input parameter type"
+ },
+ {
+ "id": "error.unsupportedOutparamType",
+ "translation": "Unsupported output parameter type"
+ },
+ {
+ "id": "error.unsupportedType",
+ "translation": "Not support this type"
+ },
+ {
+ "id": "error.invalidObjBlob",
+ "translation": "invalid Object Blob Data."
+ },
+ {
+ "id": "error.structMemNotMatch",
+ "translation": "Members are not matched in Record or Class"
+ },
+ {
+ "id": "error.invalidComplexTypeName",
+ "translation": "Invalid descriptor name."
+ },
+ {
+ "id": "error.invalidParamterValue",
+ "translation": "Invalid parameter value"
+ },
+ {
+ "id": "error.invalidArrayLen",
+ "translation": "the length of static array is bigger than the one when defined."
+ },
+ {
+ "id": "error.invalidSequenceNumber",
+ "translation": "Invalid sequence no"
+ },
+ {
+ "id": "error.resultsetInReadOnlyStatus",
+ "translation": "Resultset in readonly status"
+ },
+ {
+ "id": "error.SSLInitFailed",
+ "translation": "Failed to initialize SSL"
+ },
+ {
+ "id": "error.LobDataHasFreed",
+ "translation": "Lob Data has been freed"
+ },
+ {
+ "id": "error.fatalError",
+ "translation": "Fatal error"
+ },
+ {
+ "id": "error.invalidLenOrOffset",
+ "translation": "Invalid length or offset"
+ },
+ {
+ "id": "error.intervalValueOverflow",
+ "translation": "interval type value overflow"
+ },
+ {
+ "id": "error.invalidCipher",
+ "translation": "Invalid cipher type"
+ },
+ {
+ "id": "error.storeInNilPointer",
+ "translation": "Can't store value into a nil pointer"
+ },
+ {
+ "id": "error.batchError",
+ "translation": "Error in executing with batch"
+ },
+ {
+ "id": "warning.bpWithErr",
+ "translation": "Warning:Partial failure on execute with batch"
+ },
+ {
+ "id": "error.invalidSqlType",
+ "translation": "Invalid sql type"
+ },
+ {
+ "id": "error.invalidDateTimeValue",
+ "translation": "Invalid datetime value"
+ },
+ {
+ "id": "error.msgTooLong",
+ "translation": "Message too long, limit 512M"
+ },
+ {
+ "id": "error.isNull",
+ "translation": "Data is NULL"
+ }
+ ]
+}`
\ No newline at end of file
diff --git a/dmr/i18n/zl.go b/dmr/i18n/zl.go
new file mode 100644
index 0000000..868b292
--- /dev/null
+++ b/dmr/i18n/zl.go
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package i18n
+
+const Messages_zh_CN = `{
+ "language": "zh-Hans",
+ "messages": [
+ {
+ "id": "error.dsn.invalidSchema",
+ "translation": "DSN串必须以dm://开头"
+ },
+ {
+ "id": "error.unsupported.scan",
+ "translation": "Scan类型转换出错"
+ },
+ {
+ "id": "error.invalidParameterNumber",
+ "translation": "参数个数不匹配"
+ },
+ {
+ "id": "error.initThirdPartCipherFailed",
+ "translation": "第三方加密初始化失败"
+ },
+ {
+ "id": "error.connectionSwitchFailed",
+ "translation": "连接重置失败"
+ },
+ {
+ "id": "error.connectionSwitched",
+ "translation": "连接已重置"
+ },
+ {
+ "id": "error.invalidServerMode",
+ "translation": "服务器模式不匹配"
+ },
+ {
+ "id": "error.osauthError",
+ "translation": "同时使用了指定用户登录和OS认证登录, 请确定一种方式."
+ },
+ {
+ "id": "error.notQuerySQL",
+ "translation": "非查询SQL语句"
+ },
+ {
+ "id": "error.notExecSQL",
+ "translation": "非执行SQL语句"
+ },
+ {
+ "id": "error.invalidTranIsolation",
+ "translation": "非法的事务隔离级"
+ },
+ {
+ "id": "errorCommitInAutoCommitMode",
+ "translation": "自动提交模式下不能手动提交"
+ },
+ {
+ "id": "errorRollbackInAutoCommitMode",
+ "translation": "自动提交模式下不能手动回滚"
+ },
+ {
+ "id": "errorStatementHandleClosed",
+ "translation": "语句已经关闭"
+ },
+ {
+ "id": "errorResultSetColsed",
+ "translation": "结果集已经关闭"
+ },
+ {
+ "id": "error.communicationError",
+ "translation": "网络通信异常"
+ },
+ {
+ "id": "error.msgCheckError",
+ "translation": "消息校验异常"
+ },
+ {
+ "id": "error.unkownNetWork",
+ "translation": "未知的网络"
+ },
+ {
+ "id": "error.serverVersion",
+ "translation": "服务器版本太低"
+ },
+ {
+ "id": "error.usernameTooLong",
+ "translation": "用户名超长"
+ },
+ {
+ "id": "error.passwordTooLong",
+ "translation": "密码超长"
+ },
+ {
+ "id": "error.dataTooLong",
+ "translation": "数据大小已超过可支持范围"
+ },
+ {
+ "id": "error.invalidColumnType",
+ "translation": "无效的列类型"
+ },
+ {
+ "id": "error.dataConvertionError",
+ "translation": "类型转换异常"
+ },
+ {
+ "id": "error.invalidConn",
+ "translation": "连接失效"
+ },
+ {
+ "id": "error.invalidHex",
+ "translation": "无效的十六进制数字"
+ },
+ {
+ "id": "error.invalidBFile",
+ "translation": "无效的BFile格式串"
+ },
+ {
+ "id": "error.dataOverflow",
+ "translation": "数字溢出"
+ },
+ {
+ "id": "error.invalidDateTimeFormat",
+ "translation": "错误的日期时间类型格式"
+ },
+ {
+ "id": "error.datetimeOverflow",
+ "translation": "数字溢出"
+ },
+ {
+ "id": "error.invalidTimeInterval",
+ "translation": "错误的时间间隔类型数据"
+ },
+ {
+ "id": "error.unsupportedInparamType",
+ "translation": "输入参数类型不支持"
+ },
+ {
+ "id": "error.unsupportedOutparamType",
+ "translation": "输出参数类型不支持"
+ },
+ {
+ "id": "error.unsupportedType",
+ "translation": "不支持该数据类型"
+ },
+ {
+ "id": "error.invalidObjBlob",
+ "translation": "无效的对象BLOB数据"
+ },
+ {
+ "id": "error.structMemNotMatch",
+ "translation": "记录或类数据成员不匹配"
+ },
+ {
+ "id": "error.invalidComplexTypeName",
+ "translation": "无效的类型描述名称"
+ },
+ {
+ "id": "error.invalidParamterValue",
+ "translation": "无效的参数值"
+ },
+ {
+ "id": "error.invalidArrayLen",
+ "translation": "静态数组长度大于定义时长度"
+ },
+ {
+ "id": "error.invalidSequenceNumber",
+ "translation": "无效的列序号"
+ },
+ {
+ "id": "error.resultsetInReadOnlyStatus",
+ "translation": "结果集处于只读状态"
+ },
+ {
+ "id": "error.SSLInitFailed",
+ "translation": "初始化SSL环境失败"
+ },
+ {
+ "id": "error.LobDataHasFreed",
+ "translation": "LOB数据已经被释放"
+ },
+ {
+ "id": "error.fatalError",
+ "translation": "致命错误"
+ },
+ {
+ "id": "error.invalidLenOrOffset",
+ "translation": "长度或偏移错误"
+ },
+ {
+ "id": "error.intervalValueOverflow",
+ "translation": "时间间隔类型数据溢出"
+ },
+ {
+ "id": "error.invalidCipher",
+ "translation": "不支持的加密类型"
+ },
+ {
+ "id": "error.storeInNilPointer",
+ "translation": "无法将数据存入空指针"
+ },
+ {
+ "id": "error.batchError",
+ "translation": "批量执行出错"
+ },
+ {
+ "id": "warning.bpWithErr",
+ "translation": "警告:批量执行部分行产生错误"
+ },
+ {
+ "id": "error.invalidSqlType",
+ "translation": "非法的SQL语句类型"
+ },
+ {
+ "id": "error.invalidDateTimeValue",
+ "translation": "无效的日期时间类型值"
+ },
+ {
+ "id": "error.msgTooLong",
+ "translation": "消息长度超出限制512M"
+ },
+ {
+ "id": "error.isNull",
+ "translation": "数据为NULL"
+ }
+ ]
+}`
\ No newline at end of file
diff --git a/dmr/i18n/zm.go b/dmr/i18n/zm.go
new file mode 100644
index 0000000..ebc8a5d
--- /dev/null
+++ b/dmr/i18n/zm.go
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package i18n
+
+const Messages_zh_TW = `{
+ "language": "zh-Hant",
+ "messages": [
+ {
+ "id": "error.dsn.invalidSchema",
+ "translation": "DSN串必須以dm://開頭"
+ },
+ {
+ "id": "error.communicationError",
+ "translation": "網絡通信異常"
+ },
+ {
+ "id": "error.msgCheckError",
+ "translation": "消息校驗異常"
+ },
+ {
+ "id": "error.unkownNetWork",
+ "translation": "未知的網絡"
+ }
+ ]
+}`
\ No newline at end of file
diff --git a/dmr/j.go b/dmr/j.go
new file mode 100644
index 0000000..f70a685
--- /dev/null
+++ b/dmr/j.go
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import "database/sql/driver"
+
+type DmArray struct {
+ TypeData
+ m_arrDesc *ArrayDescriptor // 数组的描述信息
+
+ m_arrData []TypeData // 数组中各行数据值
+
+ m_objArray interface{} // 从服务端获取的
+
+ m_itemCount int // 本次获取的行数
+
+ m_itemSize int // 数组中一个数组项的大小,单位bytes
+
+ m_objCount int // 一个数组项中存在对象类型的个数(class、动态数组)
+
+ m_strCount int // 一个数组项中存在字符串类型的个数
+
+ m_objStrOffs []int // 对象在前,字符串在后
+
+ typeName string
+
+ elements []interface{}
+
+ // Valid为false代表DmArray数据在数据库中为NULL
+ Valid bool
+}
+
+func (da *DmArray) init() *DmArray {
+ da.initTypeData()
+ da.m_itemCount = 0
+ da.m_itemSize = 0
+ da.m_objCount = 0
+ da.m_strCount = 0
+ da.m_objStrOffs = nil
+ da.m_dumyData = nil
+ da.m_offset = 0
+
+ da.m_objArray = nil
+ da.Valid = true
+ return da
+}
+
+func NewDmArray(typeName string, elements []interface{}) *DmArray {
+ da := new(DmArray)
+ da.typeName = typeName
+ da.elements = elements
+ da.Valid = true
+ return da
+}
+
+func (da *DmArray) create(dc *DmConnection) (*DmArray, error) {
+ desc, err := newArrayDescriptor(da.typeName, dc)
+ if err != nil {
+ return nil, err
+ }
+ return da.createByArrayDescriptor(desc, dc)
+}
+
+func (da *DmArray) createByArrayDescriptor(arrDesc *ArrayDescriptor, conn *DmConnection) (*DmArray, error) {
+
+ if nil == arrDesc {
+ return nil, ECGO_INVALID_PARAMETER_VALUE.throw()
+ }
+
+ da.init()
+
+ da.m_arrDesc = arrDesc
+ if nil == da.elements {
+ da.m_arrData = make([]TypeData, 0)
+ } else {
+ // 若为静态数组,判断给定数组长度是否超过静态数组的上限
+ if arrDesc.getMDesc() == nil || (arrDesc.getMDesc().getDType() == SARRAY && len(da.elements) > arrDesc.getMDesc().getStaticArrayLength()) {
+ return nil, ECGO_INVALID_ARRAY_LEN.throw()
+ }
+
+ var err error
+ da.m_arrData, err = TypeDataSV.toArray(da.elements, da.m_arrDesc.getMDesc())
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ da.m_itemCount = len(da.m_arrData)
+ return da, nil
+}
+
+func newDmArrayByTypeData(atData []TypeData, desc *TypeDescriptor) *DmArray {
+ da := new(DmArray)
+ da.init()
+ da.m_arrDesc = newArrayDescriptorByTypeDescriptor(desc)
+ da.m_arrData = atData
+ return da
+}
+
+func (da *DmArray) checkIndex(index int64) error {
+ if index < 0 || index > int64(len(da.m_arrData)-1) {
+ return ECGO_INVALID_LENGTH_OR_OFFSET.throw()
+ }
+ return nil
+}
+
+func (da *DmArray) checkIndexAndCount(index int64, count int) error {
+ err := da.checkIndex(index)
+ if err != nil {
+ return err
+ }
+
+ if count <= 0 || index+int64(count) > int64(len(da.m_arrData)) {
+ return ECGO_INVALID_LENGTH_OR_OFFSET.throw()
+ }
+ return nil
+}
+
+func (da *DmArray) GetBaseTypeName() (string, error) {
+ if err := da.checkValid(); err != nil {
+ return "", err
+ }
+ return da.m_arrDesc.m_typeDesc.getFulName()
+}
+
+func (da *DmArray) GetObjArray(index int64, count int) (interface{}, error) {
+ var err error
+ if err = da.checkValid(); err != nil {
+ return nil, err
+ }
+ if err = da.checkIndexAndCount(index, count); err != nil {
+ return nil, err
+ }
+
+ return TypeDataSV.toJavaArray(da, index, count, da.m_arrDesc.getItemDesc().getDType())
+}
+
+func (da *DmArray) GetIntArray(index int64, count int) ([]int, error) {
+ var err error
+ if err = da.checkValid(); err != nil {
+ return nil, err
+ }
+ if err = da.checkIndexAndCount(index, count); err != nil {
+ return nil, err
+ }
+
+ tmp, err := TypeDataSV.toNumericArray(da, index, count, ARRAY_TYPE_INTEGER)
+ if err != nil {
+ return nil, err
+ }
+ return tmp.([]int), nil
+}
+
+func (da *DmArray) GetInt16Array(index int64, count int) ([]int16, error) {
+ var err error
+ if err = da.checkValid(); err != nil {
+ return nil, err
+ }
+ if err = da.checkIndexAndCount(index, count); err != nil {
+ return nil, err
+ }
+
+ tmp, err := TypeDataSV.toNumericArray(da, index, count, ARRAY_TYPE_SHORT)
+ if err != nil {
+ return nil, err
+ }
+ return tmp.([]int16), nil
+}
+
+func (da *DmArray) GetInt64Array(index int64, count int) ([]int64, error) {
+ var err error
+ if err = da.checkValid(); err != nil {
+ return nil, err
+ }
+ if err = da.checkIndexAndCount(index, count); err != nil {
+ return nil, err
+ }
+
+ tmp, err := TypeDataSV.toNumericArray(da, index, count, ARRAY_TYPE_LONG)
+ if err != nil {
+ return nil, err
+ }
+
+ return tmp.([]int64), nil
+}
+
+func (da *DmArray) GetFloatArray(index int64, count int) ([]float32, error) {
+ var err error
+ if err = da.checkValid(); err != nil {
+ return nil, err
+ }
+ if err = da.checkIndexAndCount(index, count); err != nil {
+ return nil, err
+ }
+
+ tmp, err := TypeDataSV.toNumericArray(da, index, count, ARRAY_TYPE_FLOAT)
+ if err != nil {
+ return nil, err
+ }
+
+ return tmp.([]float32), nil
+}
+
+func (da *DmArray) GetDoubleArray(index int64, count int) ([]float64, error) {
+ var err error
+ if err = da.checkValid(); err != nil {
+ return nil, err
+ }
+ if err = da.checkIndexAndCount(index, count); err != nil {
+ return nil, err
+ }
+
+ tmp, err := TypeDataSV.toNumericArray(da, index, count, ARRAY_TYPE_DOUBLE)
+ if err != nil {
+ return nil, err
+ }
+
+ return tmp.([]float64), nil
+}
+
+func (dest *DmArray) Scan(src interface{}) error {
+ if dest == nil {
+ return ECGO_STORE_IN_NIL_POINTER.throw()
+ }
+ switch src := src.(type) {
+ case nil:
+ *dest = *new(DmArray)
+ // 将Valid标志置false表示数据库中该列为NULL
+ (*dest).Valid = false
+ return nil
+ case *DmArray:
+ *dest = *src
+ return nil
+ default:
+ return UNSUPPORTED_SCAN.throw()
+ }
+}
+
+func (array DmArray) Value() (driver.Value, error) {
+ if !array.Valid {
+ return nil, nil
+ }
+ return array, nil
+}
+
+func (array *DmArray) checkValid() error {
+ if !array.Valid {
+ return ECGO_IS_NULL.throw()
+ }
+ return nil
+}
diff --git a/dmr/k.go b/dmr/k.go
new file mode 100644
index 0000000..9468aa9
--- /dev/null
+++ b/dmr/k.go
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "database/sql/driver"
+ "io"
+)
+
+type DmBlob struct {
+ lob
+ data []byte
+ offset int64
+}
+
+func newDmBlob() *DmBlob {
+ return &DmBlob{
+ lob: lob{
+ inRow: true,
+ groupId: -1,
+ fileId: -1,
+ pageNo: -1,
+ readOver: false,
+ local: true,
+ updateable: true,
+ length: -1,
+ compatibleOracle: false,
+ fetchAll: false,
+ freed: false,
+ modify: false,
+ Valid: true,
+ },
+ offset: 1,
+ }
+}
+
+func newBlobFromDB(value []byte, conn *DmConnection, column *column, fetchAll bool) *DmBlob {
+ var blob = newDmBlob()
+ blob.connection = conn
+ blob.lobFlag = LOB_FLAG_BYTE
+ blob.compatibleOracle = conn.CompatibleOracle()
+ blob.local = false
+ blob.updateable = !column.readonly
+ blob.tabId = column.lobTabId
+ blob.colId = column.lobColId
+
+ blob.inRow = Dm_build_1220.Dm_build_1313(value, NBLOB_HEAD_IN_ROW_FLAG) == LOB_IN_ROW
+ blob.blobId = Dm_build_1220.Dm_build_1327(value, NBLOB_HEAD_BLOBID)
+ if !blob.inRow {
+ blob.groupId = Dm_build_1220.Dm_build_1317(value, NBLOB_HEAD_OUTROW_GROUPID)
+ blob.fileId = Dm_build_1220.Dm_build_1317(value, NBLOB_HEAD_OUTROW_FILEID)
+ blob.pageNo = Dm_build_1220.Dm_build_1322(value, NBLOB_HEAD_OUTROW_PAGENO)
+ }
+ if conn.NewLobFlag {
+ blob.tabId = Dm_build_1220.Dm_build_1322(value, NBLOB_EX_HEAD_TABLE_ID)
+ blob.colId = Dm_build_1220.Dm_build_1317(value, NBLOB_EX_HEAD_COL_ID)
+ blob.rowId = Dm_build_1220.Dm_build_1327(value, NBLOB_EX_HEAD_ROW_ID)
+ blob.exGroupId = Dm_build_1220.Dm_build_1317(value, NBLOB_EX_HEAD_FPA_GRPID)
+ blob.exFileId = Dm_build_1220.Dm_build_1317(value, NBLOB_EX_HEAD_FPA_FILEID)
+ blob.exPageNo = Dm_build_1220.Dm_build_1322(value, NBLOB_EX_HEAD_FPA_PAGENO)
+ }
+ blob.resetCurrentInfo()
+
+ blob.length = blob.getLengthFromHead(value)
+ if blob.inRow {
+ blob.data = make([]byte, blob.length)
+ if conn.NewLobFlag {
+ Dm_build_1220.Dm_build_1276(blob.data, 0, value, NBLOB_EX_HEAD_SIZE, len(blob.data))
+ } else {
+ Dm_build_1220.Dm_build_1276(blob.data, 0, value, NBLOB_INROW_HEAD_SIZE, len(blob.data))
+ }
+ } else if fetchAll {
+ blob.loadAllData()
+ }
+ return blob
+}
+
+func newBlobOfLocal(value []byte, conn *DmConnection) *DmBlob {
+ var blob = newDmBlob()
+ blob.connection = conn
+ blob.lobFlag = LOB_FLAG_BYTE
+ blob.data = value
+ blob.length = int64(len(blob.data))
+ return blob
+}
+
+func NewBlob(value []byte) *DmBlob {
+ var blob = newDmBlob()
+
+ blob.lobFlag = LOB_FLAG_BYTE
+ blob.data = value
+ blob.length = int64(len(blob.data))
+ return blob
+}
+
+func (blob *DmBlob) Read(dest []byte) (n int, err error) {
+ if err = blob.checkValid(); err != nil {
+ return
+ }
+ result, err := blob.getBytes(blob.offset, int32(len(dest)))
+ if err != nil {
+ return 0, err
+ }
+ blob.offset += int64(len(result))
+ copy(dest, result)
+ if len(result) == 0 {
+ return 0, io.EOF
+ }
+ return len(result), nil
+}
+
+func (blob *DmBlob) ReadAt(pos int, dest []byte) (n int, err error) {
+ if err = blob.checkValid(); err != nil {
+ return
+ }
+ result, err := blob.getBytes(int64(pos), int32(len(dest)))
+ if err != nil {
+ return 0, err
+ }
+ if len(result) == 0 {
+ return 0, io.EOF
+ }
+ copy(dest[0:len(result)], result)
+ return len(result), nil
+}
+
+func (blob *DmBlob) Write(pos int, src []byte) (n int, err error) {
+ if err = blob.checkValid(); err != nil {
+ return
+ }
+ if err = blob.checkFreed(); err != nil {
+ return
+ }
+ if pos < 1 {
+ err = ECGO_INVALID_LENGTH_OR_OFFSET.throw()
+ return
+ }
+ if !blob.updateable {
+ err = ECGO_RESULTSET_IS_READ_ONLY.throw()
+ return
+ }
+ pos -= 1
+ if blob.local || blob.fetchAll {
+ if int64(pos) > blob.length {
+ err = ECGO_INVALID_LENGTH_OR_OFFSET.throw()
+ return
+ }
+ blob.setLocalData(pos, src)
+ n = len(src)
+ } else {
+ if err = blob.connection.checkClosed(); err != nil {
+ return -1, err
+ }
+ var writeLen, err = blob.connection.Access.dm_build_542(blob, pos, src)
+ if err != nil {
+ return -1, err
+ }
+
+ if blob.groupId == -1 {
+ blob.setLocalData(pos, src)
+ } else {
+ blob.inRow = false
+ blob.length = -1
+ }
+ n = writeLen
+
+ }
+ blob.modify = true
+ return
+}
+
+func (blob *DmBlob) Truncate(length int64) error {
+ var err error
+ if err = blob.checkValid(); err != nil {
+ return err
+ }
+ if err = blob.checkFreed(); err != nil {
+ return err
+ }
+ if length < 0 {
+ return ECGO_INVALID_LENGTH_OR_OFFSET.throw()
+ }
+ if !blob.updateable {
+ return ECGO_RESULTSET_IS_READ_ONLY.throw()
+ }
+ if blob.local || blob.fetchAll {
+ if length >= int64(len(blob.data)) {
+ return nil
+ }
+ tmp := make([]byte, length)
+ Dm_build_1220.Dm_build_1276(tmp, 0, blob.data, 0, len(tmp))
+ blob.data = tmp
+ blob.length = int64(len(tmp))
+ } else {
+ if err = blob.connection.checkClosed(); err != nil {
+ return err
+ }
+ blob.length, err = blob.connection.Access.dm_build_556(&blob.lob, int(length))
+ if err != nil {
+ return err
+ }
+ if blob.groupId == -1 {
+ tmp := make([]byte, blob.length)
+ Dm_build_1220.Dm_build_1276(tmp, 0, blob.data, 0, int(blob.length))
+ blob.data = tmp
+ }
+ }
+ blob.modify = true
+ return nil
+}
+
+func (dest *DmBlob) Scan(src interface{}) error {
+ if dest == nil {
+ return ECGO_STORE_IN_NIL_POINTER.throw()
+ }
+ switch src := src.(type) {
+ case nil:
+ *dest = *new(DmBlob)
+
+ (*dest).Valid = false
+ return nil
+ case []byte:
+ *dest = *NewBlob(src)
+ return nil
+ case *DmBlob:
+ *dest = *src
+ return nil
+ default:
+ return UNSUPPORTED_SCAN.throw()
+ }
+}
+
+func (blob DmBlob) Value() (driver.Value, error) {
+ if !blob.Valid {
+ return nil, nil
+ }
+ return blob, nil
+}
+
+func (blob *DmBlob) getBytes(pos int64, length int32) ([]byte, error) {
+ var err error
+ var leaveLength int64
+ if err = blob.checkFreed(); err != nil {
+ return nil, err
+ }
+ if pos < 1 || length < 0 {
+ return nil, ECGO_INVALID_LENGTH_OR_OFFSET.throw()
+ }
+ pos = pos - 1
+ if leaveLength, err = blob.GetLength(); err != nil {
+ return nil, err
+ }
+ leaveLength -= pos
+ if leaveLength < 0 {
+ return nil, ECGO_INVALID_LENGTH_OR_OFFSET.throw()
+ }
+ if int64(length) > leaveLength {
+ length = int32(leaveLength)
+ }
+ if blob.local || blob.inRow || blob.fetchAll {
+ return blob.data[pos : pos+int64(length)], nil
+ } else {
+
+ return blob.connection.Access.dm_build_505(blob, int32(pos), length)
+ }
+}
+
+func (blob *DmBlob) loadAllData() {
+ blob.checkFreed()
+ if blob.local || blob.inRow || blob.fetchAll {
+ return
+ }
+ len, _ := blob.GetLength()
+ blob.data, _ = blob.getBytes(1, int32(len))
+ blob.fetchAll = true
+}
+
+func (blob *DmBlob) setLocalData(pos int, p []byte) {
+ if pos+len(p) >= int(blob.length) {
+ var tmp = make([]byte, pos+len(p))
+ Dm_build_1220.Dm_build_1276(tmp, 0, blob.data, 0, pos)
+ Dm_build_1220.Dm_build_1276(tmp, pos, p, 0, len(p))
+ blob.data = tmp
+ } else {
+ Dm_build_1220.Dm_build_1276(blob.data, pos, p, 0, len(p))
+ }
+ blob.length = int64(len(blob.data))
+}
diff --git a/dmr/l.go b/dmr/l.go
new file mode 100644
index 0000000..b682ae2
--- /dev/null
+++ b/dmr/l.go
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "database/sql/driver"
+ "io"
+)
+
+type DmClob struct {
+ lob
+ data []rune
+ serverEncoding string
+}
+
+func newDmClob() *DmClob {
+ return &DmClob{
+ lob: lob{
+ inRow: true,
+ groupId: -1,
+ fileId: -1,
+ pageNo: -1,
+ readOver: false,
+ local: true,
+ updateable: true,
+ length: -1,
+ compatibleOracle: false,
+ fetchAll: false,
+ freed: false,
+ modify: false,
+ Valid: true,
+ },
+ }
+}
+
+func newClobFromDB(value []byte, conn *DmConnection, column *column, fetchAll bool) *DmClob {
+ var clob = newDmClob()
+ clob.connection = conn
+ clob.lobFlag = LOB_FLAG_CHAR
+ clob.compatibleOracle = conn.CompatibleOracle()
+ clob.local = false
+ clob.updateable = !column.readonly
+ clob.tabId = column.lobTabId
+ clob.colId = column.lobColId
+
+ clob.inRow = Dm_build_1220.Dm_build_1313(value, NBLOB_HEAD_IN_ROW_FLAG) == LOB_IN_ROW
+ clob.blobId = Dm_build_1220.Dm_build_1327(value, NBLOB_HEAD_BLOBID)
+ if !clob.inRow {
+ clob.groupId = Dm_build_1220.Dm_build_1317(value, NBLOB_HEAD_OUTROW_GROUPID)
+ clob.fileId = Dm_build_1220.Dm_build_1317(value, NBLOB_HEAD_OUTROW_FILEID)
+ clob.pageNo = Dm_build_1220.Dm_build_1322(value, NBLOB_HEAD_OUTROW_PAGENO)
+ }
+ if conn.NewLobFlag {
+ clob.tabId = Dm_build_1220.Dm_build_1322(value, NBLOB_EX_HEAD_TABLE_ID)
+ clob.colId = Dm_build_1220.Dm_build_1317(value, NBLOB_EX_HEAD_COL_ID)
+ clob.rowId = Dm_build_1220.Dm_build_1327(value, NBLOB_EX_HEAD_ROW_ID)
+ clob.exGroupId = Dm_build_1220.Dm_build_1317(value, NBLOB_EX_HEAD_FPA_GRPID)
+ clob.exFileId = Dm_build_1220.Dm_build_1317(value, NBLOB_EX_HEAD_FPA_FILEID)
+ clob.exPageNo = Dm_build_1220.Dm_build_1322(value, NBLOB_EX_HEAD_FPA_PAGENO)
+ }
+ clob.resetCurrentInfo()
+
+ clob.serverEncoding = conn.getServerEncoding()
+ if clob.inRow {
+ if conn.NewLobFlag {
+ clob.data = []rune(Dm_build_1220.Dm_build_1377(value, NBLOB_EX_HEAD_SIZE, int(clob.getLengthFromHead(value)), clob.serverEncoding, conn))
+ } else {
+ clob.data = []rune(Dm_build_1220.Dm_build_1377(value, NBLOB_INROW_HEAD_SIZE, int(clob.getLengthFromHead(value)), clob.serverEncoding, conn))
+ }
+ clob.length = int64(len(clob.data))
+ } else if fetchAll {
+ clob.loadAllData()
+ }
+ return clob
+}
+
+func newClobOfLocal(value string, conn *DmConnection) *DmClob {
+ var clob = newDmClob()
+ clob.connection = conn
+ clob.lobFlag = LOB_FLAG_CHAR
+ clob.data = []rune(value)
+ clob.length = int64(len(clob.data))
+ return clob
+}
+
+func NewClob(value string) *DmClob {
+ var clob = newDmClob()
+
+ clob.lobFlag = LOB_FLAG_CHAR
+ clob.data = []rune(value)
+ clob.length = int64(len(clob.data))
+ return clob
+}
+
+func (clob *DmClob) ReadString(pos int, length int) (result string, err error) {
+ if err = clob.checkValid(); err != nil {
+ return
+ }
+ result, err = clob.getSubString(int64(pos), int32(length))
+ if err != nil {
+ return
+ }
+ if len(result) == 0 {
+ err = io.EOF
+ return
+ }
+ return
+}
+
+func (clob *DmClob) WriteString(pos int, s string) (n int, err error) {
+ if err = clob.checkValid(); err != nil {
+ return
+ }
+ if err = clob.checkFreed(); err != nil {
+ return
+ }
+ if pos < 1 {
+ err = ECGO_INVALID_LENGTH_OR_OFFSET.throw()
+ return
+ }
+ if !clob.updateable {
+ err = ECGO_RESULTSET_IS_READ_ONLY.throw()
+ return
+ }
+ pos -= 1
+ if clob.local || clob.fetchAll {
+ if int64(pos) > clob.length {
+ err = ECGO_INVALID_LENGTH_OR_OFFSET.throw()
+ return
+ }
+ clob.setLocalData(pos, s)
+ n = len(s)
+ } else {
+ if err = clob.connection.checkClosed(); err != nil {
+ return -1, err
+ }
+ var writeLen, err = clob.connection.Access.dm_build_526(clob, pos, s, clob.serverEncoding)
+ if err != nil {
+ return -1, err
+ }
+
+ if clob.groupId == -1 {
+ clob.setLocalData(pos, s)
+ } else {
+ clob.inRow = false
+ clob.length = -1
+ }
+ n = writeLen
+ }
+ clob.modify = true
+ return
+}
+
+func (clob *DmClob) Truncate(length int64) error {
+ var err error
+ if err = clob.checkValid(); err != nil {
+ return err
+ }
+ if err = clob.checkFreed(); err != nil {
+ return err
+ }
+ if length < 0 {
+ return ECGO_INVALID_LENGTH_OR_OFFSET.throw()
+ }
+ if !clob.updateable {
+ return ECGO_RESULTSET_IS_READ_ONLY.throw()
+ }
+ if clob.local || clob.fetchAll {
+ if length >= int64(len(clob.data)) {
+ return nil
+ }
+ clob.data = clob.data[0:length]
+ clob.length = int64(len(clob.data))
+ } else {
+ if err = clob.connection.checkClosed(); err != nil {
+ return err
+ }
+ clob.length, err = clob.connection.Access.dm_build_556(&clob.lob, int(length))
+ if err != nil {
+ return err
+ }
+ if clob.groupId == -1 {
+ clob.data = clob.data[0:clob.length]
+ }
+ }
+ clob.modify = true
+ return nil
+}
+
+func (dest *DmClob) Scan(src interface{}) error {
+ if dest == nil {
+ return ECGO_STORE_IN_NIL_POINTER.throw()
+ }
+ switch src := src.(type) {
+ case nil:
+ *dest = *new(DmClob)
+
+ (*dest).Valid = false
+ return nil
+ case string:
+ *dest = *NewClob(src)
+ return nil
+ case *DmClob:
+ *dest = *src
+ return nil
+ default:
+ return UNSUPPORTED_SCAN.throw()
+ }
+}
+
+func (clob DmClob) Value() (driver.Value, error) {
+ if !clob.Valid {
+ return nil, nil
+ }
+ return clob, nil
+}
+
+func (clob *DmClob) getSubString(pos int64, len int32) (string, error) {
+ var err error
+ var leaveLength int64
+ if err = clob.checkFreed(); err != nil {
+ return "", err
+ }
+ if pos < 1 || len < 0 {
+ return "", ECGO_INVALID_LENGTH_OR_OFFSET.throw()
+ }
+ pos = pos - 1
+ if leaveLength, err = clob.GetLength(); err != nil {
+ return "", err
+ }
+ if pos > leaveLength {
+ pos = leaveLength
+ }
+ leaveLength -= pos
+ if leaveLength < 0 {
+ return "", ECGO_INVALID_LENGTH_OR_OFFSET.throw()
+ }
+ if int64(len) > leaveLength {
+ len = int32(leaveLength)
+ }
+ if clob.local || clob.inRow || clob.fetchAll {
+ if pos > clob.length {
+ return "", ECGO_INVALID_LENGTH_OR_OFFSET.throw()
+ }
+ return string(clob.data[pos : pos+int64(len)]), nil
+ } else {
+
+ return clob.connection.Access.dm_build_515(clob, int32(pos), len)
+ }
+}
+
+func (clob *DmClob) loadAllData() {
+ clob.checkFreed()
+ if clob.local || clob.inRow || clob.fetchAll {
+ return
+ }
+ len, _ := clob.GetLength()
+ s, _ := clob.getSubString(1, int32(len))
+ clob.data = []rune(s)
+ clob.fetchAll = true
+}
+
+func (clob *DmClob) setLocalData(pos int, str string) {
+ if pos+len(str) >= int(clob.length) {
+ clob.data = []rune(string(clob.data[0:pos]) + str)
+ } else {
+ clob.data = []rune(string(clob.data[0:pos]) + str + string(clob.data[pos+len(str):len(clob.data)]))
+ }
+ clob.length = int64(len(clob.data))
+}
diff --git a/dmr/m.go b/dmr/m.go
new file mode 100644
index 0000000..ea3d782
--- /dev/null
+++ b/dmr/m.go
@@ -0,0 +1,867 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "bytes"
+ "context"
+ "database/sql"
+ "database/sql/driver"
+ "fmt"
+ "sync/atomic"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/parser"
+ "golang.org/x/text/encoding"
+)
+
+type DmConnection struct {
+ filterable
+
+ dmConnector *DmConnector
+ Access *dm_build_332
+ stmtMap map[int32]*DmStatement
+ stmtPool []stmtPoolInfo
+ lastExecInfo *execRetInfo
+ lexer *parser.Lexer
+ encode encoding.Encoding
+ encodeBuffer *bytes.Buffer
+ transformReaderDst []byte
+ transformReaderSrc []byte
+
+ serverEncoding string
+ GlobalServerSeries int
+ ServerVersion string
+ Malini2 bool
+ Execute2 bool
+ LobEmptyCompOrcl bool
+ IsoLevel int32
+ ReadOnly bool
+ NewLobFlag bool
+ sslEncrypt int
+ MaxRowSize int32
+ DDLAutoCommit bool
+ BackslashEscape bool
+ SvrStat int32
+ SvrMode int32
+ ConstParaOpt bool
+ DbTimezone int16
+ LifeTimeRemainder int16
+ InstanceName string
+ Schema string
+ LastLoginIP string
+ LastLoginTime string
+ FailedAttempts int32
+ LoginWarningID int32
+ GraceTimeRemainder int32
+ Guid string
+ DbName string
+ StandbyHost string
+ StandbyPort int32
+ StandbyCount int32
+ SessionID int64
+ OracleDateLanguage byte
+ FormatDate string
+ FormatTimestamp string
+ FormatTimestampTZ string
+ FormatTime string
+ FormatTimeTZ string
+ Local bool
+ MsgVersion int32
+ TrxStatus int32
+ dscControl bool
+ trxFinish bool
+ sessionID int64
+ autoCommit bool
+ isBatch bool
+
+ watching bool
+ watcher chan<- context.Context
+ closech chan struct{}
+ finished chan<- struct{}
+ canceled atomicError
+ closed atomicBool
+}
+
+func (conn *DmConnection) setTrxFinish(status int32) {
+ switch status & Dm_build_722 {
+ case Dm_build_719, Dm_build_720, Dm_build_721:
+ conn.trxFinish = true
+ default:
+ conn.trxFinish = false
+ }
+}
+
+func (dmConn *DmConnection) init() {
+ if dmConn.dmConnector.stmtPoolMaxSize > 0 {
+ dmConn.stmtPool = make([]stmtPoolInfo, 0, dmConn.dmConnector.stmtPoolMaxSize)
+ }
+
+ dmConn.stmtMap = make(map[int32]*DmStatement)
+ dmConn.DbTimezone = 0
+ dmConn.GlobalServerSeries = 0
+ dmConn.MaxRowSize = 0
+ dmConn.LobEmptyCompOrcl = false
+ dmConn.ReadOnly = false
+ dmConn.DDLAutoCommit = false
+ dmConn.ConstParaOpt = false
+ dmConn.IsoLevel = -1
+ dmConn.sessionID = -1
+ dmConn.Malini2 = true
+ dmConn.NewLobFlag = true
+ dmConn.Execute2 = true
+ dmConn.serverEncoding = ENCODING_GB18030
+ dmConn.TrxStatus = Dm_build_670
+ dmConn.OracleDateLanguage = byte(Locale)
+ dmConn.lastExecInfo = NewExceInfo()
+ dmConn.MsgVersion = Dm_build_603
+
+ dmConn.idGenerator = dmConnIDGenerator
+}
+
+func (dmConn *DmConnection) reset() {
+ dmConn.DbTimezone = 0
+ dmConn.GlobalServerSeries = 0
+ dmConn.MaxRowSize = 0
+ dmConn.LobEmptyCompOrcl = false
+ dmConn.ReadOnly = false
+ dmConn.DDLAutoCommit = false
+ dmConn.ConstParaOpt = false
+ dmConn.IsoLevel = -1
+ dmConn.sessionID = -1
+ dmConn.Malini2 = true
+ dmConn.NewLobFlag = true
+ dmConn.Execute2 = true
+ dmConn.serverEncoding = ENCODING_GB18030
+ dmConn.TrxStatus = Dm_build_670
+}
+
+func (dc *DmConnection) checkClosed() error {
+ if dc.closed.IsSet() {
+ return driver.ErrBadConn
+ }
+
+ return nil
+}
+
+func (dc *DmConnection) executeInner(query string, execType int16) (interface{}, error) {
+
+ stmt, err := NewDmStmt(dc, query)
+
+ if err != nil {
+ return nil, err
+ }
+
+ if execType == Dm_build_687 {
+ defer stmt.close()
+ }
+
+ stmt.innerUsed = true
+ if stmt.dmConn.dmConnector.escapeProcess {
+ stmt.nativeSql, err = stmt.dmConn.escape(stmt.nativeSql, stmt.dmConn.dmConnector.keyWords)
+ if err != nil {
+ stmt.close()
+ return nil, err
+ }
+ }
+
+ var optParamList []OptParameter
+
+ if stmt.dmConn.ConstParaOpt {
+ optParamList = make([]OptParameter, 0)
+ stmt.nativeSql, optParamList, err = stmt.dmConn.execOpt(stmt.nativeSql, optParamList, stmt.dmConn.getServerEncoding())
+ if err != nil {
+ stmt.close()
+ optParamList = nil
+ }
+ }
+
+ if execType == Dm_build_686 && dc.dmConnector.enRsCache {
+ rpv, err := rp.get(stmt, query)
+ if err != nil {
+ return nil, err
+ }
+
+ if rpv != nil {
+ stmt.execInfo = rpv.execInfo
+ dc.lastExecInfo = rpv.execInfo
+ return newDmRows(rpv.getResultSet(stmt)), nil
+ }
+ }
+
+ var info *execRetInfo
+
+ if optParamList != nil && len(optParamList) > 0 {
+ info, err = dc.Access.Dm_build_411(stmt, optParamList)
+ if err != nil {
+ stmt.nativeSql = query
+ info, err = dc.Access.Dm_build_417(stmt, execType)
+ }
+ } else {
+ info, err = dc.Access.Dm_build_417(stmt, execType)
+ }
+
+ if err != nil {
+ stmt.close()
+ return nil, err
+ }
+ dc.lastExecInfo = info
+
+ if info.hasResultSet {
+ return newDmRows(newInnerRows(0, stmt, info)), nil
+ } else {
+ return newDmResult(stmt, info), nil
+ }
+}
+
+func g2dbIsoLevel(isoLevel int32) int32 {
+ switch isoLevel {
+ case 1:
+ return Dm_build_674
+ case 2:
+ return Dm_build_675
+ case 4:
+ return Dm_build_676
+ case 6:
+ return Dm_build_677
+ default:
+ return -1
+ }
+}
+
+func (dc *DmConnection) Begin() (driver.Tx, error) {
+ if len(dc.filterChain.filters) == 0 {
+ return dc.begin()
+ } else {
+ return dc.filterChain.reset().DmConnectionBegin(dc)
+ }
+}
+
+func (dc *DmConnection) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
+ if len(dc.filterChain.filters) == 0 {
+ return dc.beginTx(ctx, opts)
+ }
+ return dc.filterChain.reset().DmConnectionBeginTx(dc, ctx, opts)
+}
+
+func (dc *DmConnection) Commit() error {
+ if len(dc.filterChain.filters) == 0 {
+ return dc.commit()
+ } else {
+ return dc.filterChain.reset().DmConnectionCommit(dc)
+ }
+}
+
+func (dc *DmConnection) Rollback() error {
+ if len(dc.filterChain.filters) == 0 {
+ return dc.rollback()
+ } else {
+ return dc.filterChain.reset().DmConnectionRollback(dc)
+ }
+}
+
+func (dc *DmConnection) Close() error {
+ if len(dc.filterChain.filters) == 0 {
+ return dc.close()
+ } else {
+ return dc.filterChain.reset().DmConnectionClose(dc)
+ }
+}
+
+func (dc *DmConnection) Ping(ctx context.Context) error {
+ if len(dc.filterChain.filters) == 0 {
+ return dc.ping(ctx)
+ } else {
+ return dc.filterChain.reset().DmConnectionPing(dc, ctx)
+ }
+}
+
+func (dc *DmConnection) Exec(query string, args []driver.Value) (driver.Result, error) {
+ if len(dc.filterChain.filters) == 0 {
+ return dc.exec(query, args)
+ }
+ return dc.filterChain.reset().DmConnectionExec(dc, query, args)
+}
+
+func (dc *DmConnection) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
+ if len(dc.filterChain.filters) == 0 {
+ return dc.execContext(ctx, query, args)
+ }
+ return dc.filterChain.reset().DmConnectionExecContext(dc, ctx, query, args)
+}
+
+func (dc *DmConnection) Query(query string, args []driver.Value) (driver.Rows, error) {
+ if len(dc.filterChain.filters) == 0 {
+ return dc.query(query, args)
+ }
+ return dc.filterChain.reset().DmConnectionQuery(dc, query, args)
+}
+
+func (dc *DmConnection) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
+ if len(dc.filterChain.filters) == 0 {
+ return dc.queryContext(ctx, query, args)
+ }
+ return dc.filterChain.reset().DmConnectionQueryContext(dc, ctx, query, args)
+}
+
+func (dc *DmConnection) Prepare(query string) (driver.Stmt, error) {
+ if len(dc.filterChain.filters) == 0 {
+ return dc.prepare(query)
+ }
+ return dc.filterChain.reset().DmConnectionPrepare(dc, query)
+}
+
+func (dc *DmConnection) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
+ if len(dc.filterChain.filters) == 0 {
+ return dc.prepareContext(ctx, query)
+ }
+ return dc.filterChain.reset().DmConnectionPrepareContext(dc, ctx, query)
+}
+
+func (dc *DmConnection) ResetSession(ctx context.Context) error {
+ if len(dc.filterChain.filters) == 0 {
+ return dc.resetSession(ctx)
+ }
+ return dc.filterChain.reset().DmConnectionResetSession(dc, ctx)
+}
+
+func (dc *DmConnection) CheckNamedValue(nv *driver.NamedValue) error {
+ if len(dc.filterChain.filters) == 0 {
+ return dc.checkNamedValue(nv)
+ }
+ return dc.filterChain.reset().DmConnectionCheckNamedValue(dc, nv)
+}
+
+func (dc *DmConnection) begin() (*DmConnection, error) {
+ return dc.beginTx(context.Background(), driver.TxOptions{driver.IsolationLevel(sql.LevelDefault), false})
+}
+
+func (dc *DmConnection) beginTx(ctx context.Context, opts driver.TxOptions) (*DmConnection, error) {
+ if err := dc.watchCancel(ctx); err != nil {
+ return nil, err
+ }
+ defer dc.finish()
+
+ err := dc.checkClosed()
+ if err != nil {
+ return nil, err
+ }
+
+ dc.autoCommit = false
+
+ if sql.IsolationLevel(opts.Isolation) == sql.LevelDefault {
+ opts.Isolation = driver.IsolationLevel(sql.LevelReadCommitted)
+ }
+
+ dc.ReadOnly = opts.ReadOnly
+
+ if dc.IsoLevel == int32(opts.Isolation) {
+ return dc, nil
+ }
+
+ switch sql.IsolationLevel(opts.Isolation) {
+ case sql.LevelDefault, sql.LevelReadUncommitted:
+ return dc, nil
+ case sql.LevelReadCommitted, sql.LevelSerializable:
+ dc.IsoLevel = int32(opts.Isolation)
+ case sql.LevelRepeatableRead:
+ if dc.CompatibleMysql() {
+ dc.IsoLevel = int32(sql.LevelReadCommitted)
+ } else {
+ return nil, ECGO_INVALID_TRAN_ISOLATION.throw()
+ }
+ default:
+ return nil, ECGO_INVALID_TRAN_ISOLATION.throw()
+ }
+
+ err = dc.Access.Dm_build_471(dc)
+ if err != nil {
+ return nil, err
+ }
+ return dc, nil
+}
+
+func (dc *DmConnection) commit() error {
+ err := dc.checkClosed()
+ if err != nil {
+ return err
+ }
+
+ defer func() {
+ dc.autoCommit = dc.dmConnector.autoCommit
+ }()
+
+ if !dc.autoCommit {
+ err = dc.Access.Commit()
+ if err != nil {
+ return err
+ }
+ dc.trxFinish = true
+ return nil
+ } else if !dc.dmConnector.alwayseAllowCommit {
+ return ECGO_COMMIT_IN_AUTOCOMMIT_MODE.throw()
+ }
+
+ return nil
+}
+
+func (dc *DmConnection) rollback() error {
+ err := dc.checkClosed()
+ if err != nil {
+ return err
+ }
+
+ defer func() {
+ dc.autoCommit = dc.dmConnector.autoCommit
+ }()
+
+ if !dc.autoCommit {
+ err = dc.Access.Rollback()
+ if err != nil {
+ return err
+ }
+ dc.trxFinish = true
+ return nil
+ } else if !dc.dmConnector.alwayseAllowCommit {
+ return ECGO_ROLLBACK_IN_AUTOCOMMIT_MODE.throw()
+ }
+
+ return nil
+}
+
+func (dc *DmConnection) reconnect() error {
+ err := dc.Access.Close()
+ if err != nil {
+ return err
+ }
+
+ for _, stmt := range dc.stmtMap {
+ stmt.closed = true
+ for id, _ := range stmt.rsMap {
+ delete(stmt.rsMap, id)
+ }
+ }
+
+ if dc.stmtPool != nil {
+ dc.stmtPool = dc.stmtPool[:0]
+ }
+
+ dc.dmConnector.reConnection = dc
+
+ if dc.dmConnector.group != nil {
+ _, err = dc.dmConnector.group.connect(dc.dmConnector)
+ if err != nil {
+ return err
+ }
+ } else {
+ _, err = dc.dmConnector.connect(context.Background())
+ }
+
+ for _, stmt := range dc.stmtMap {
+ err = dc.Access.Dm_build_389(stmt)
+ if err != nil {
+ return err
+ }
+
+ if stmt.paramCount > 0 {
+ err = stmt.prepare()
+ if err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
+func (dc *DmConnection) cleanup() {
+ dc.close()
+}
+
+func (dc *DmConnection) close() error {
+ if !dc.closed.TrySet(true) {
+ return nil
+ }
+
+ close(dc.closech)
+ if dc.Access == nil {
+ return nil
+ }
+
+ dc.rollback()
+
+ for _, stmt := range dc.stmtMap {
+ stmt.free()
+ }
+
+ if dc.stmtPool != nil {
+ for _, spi := range dc.stmtPool {
+ dc.Access.Dm_build_394(spi.id)
+ }
+ dc.stmtPool = nil
+ }
+
+ dc.Access.Close()
+
+ return nil
+}
+
+func (dc *DmConnection) ping(ctx context.Context) error {
+ if err := dc.watchCancel(ctx); err != nil {
+ return err
+ }
+ defer dc.finish()
+
+ rows, err := dc.query("select 1", nil)
+ if err != nil {
+ return err
+ }
+ return rows.close()
+}
+
+func (dc *DmConnection) exec(query string, args []driver.Value) (*DmResult, error) {
+ err := dc.checkClosed()
+ if err != nil {
+ return nil, err
+ }
+
+ if args != nil && len(args) > 0 {
+ stmt, err := dc.prepare(query)
+ defer stmt.close()
+ if err != nil {
+ return nil, err
+ }
+ dc.lastExecInfo = stmt.execInfo
+
+ return stmt.exec(args)
+ } else {
+ r1, err := dc.executeInner(query, Dm_build_687)
+ if err != nil {
+ return nil, err
+ }
+
+ if r2, ok := r1.(*DmResult); ok {
+ return r2, nil
+ } else {
+ return nil, ECGO_NOT_EXEC_SQL.throw()
+ }
+ }
+}
+
+func (dc *DmConnection) execContext(ctx context.Context, query string, args []driver.NamedValue) (*DmResult, error) {
+
+ if err := dc.watchCancel(ctx); err != nil {
+ return nil, err
+ }
+ defer dc.finish()
+
+ err := dc.checkClosed()
+ if err != nil {
+ return nil, err
+ }
+
+ if args != nil && len(args) > 0 {
+ stmt, err := dc.prepare(query)
+ defer stmt.close()
+ if err != nil {
+ return nil, err
+ }
+ dc.lastExecInfo = stmt.execInfo
+
+ return stmt.execContext(ctx, args)
+ } else {
+ r1, err := dc.executeInner(query, Dm_build_687)
+ if err != nil {
+ return nil, err
+ }
+
+ if r2, ok := r1.(*DmResult); ok {
+ return r2, nil
+ } else {
+ return nil, ECGO_NOT_EXEC_SQL.throw()
+ }
+ }
+}
+
+func (dc *DmConnection) query(query string, args []driver.Value) (*DmRows, error) {
+
+ err := dc.checkClosed()
+ if err != nil {
+ return nil, err
+ }
+
+ if args != nil && len(args) > 0 {
+ stmt, err := dc.prepare(query)
+ if err != nil {
+ stmt.close()
+ return nil, err
+ }
+ dc.lastExecInfo = stmt.execInfo
+
+ stmt.innerUsed = true
+ return stmt.query(args)
+
+ } else {
+ r1, err := dc.executeInner(query, Dm_build_686)
+ if err != nil {
+ return nil, err
+ }
+
+ if r2, ok := r1.(*DmRows); ok {
+ return r2, nil
+ } else {
+ return nil, ECGO_NOT_QUERY_SQL.throw()
+ }
+ }
+}
+
+func (dc *DmConnection) queryContext(ctx context.Context, query string, args []driver.NamedValue) (*DmRows, error) {
+ if err := dc.watchCancel(ctx); err != nil {
+ return nil, err
+ }
+ defer dc.finish()
+
+ err := dc.checkClosed()
+ if err != nil {
+ return nil, err
+ }
+
+ if args != nil && len(args) > 0 {
+ stmt, err := dc.prepare(query)
+ if err != nil {
+ stmt.close()
+ return nil, err
+ }
+ dc.lastExecInfo = stmt.execInfo
+
+ stmt.innerUsed = true
+ return stmt.queryContext(ctx, args)
+
+ } else {
+ r1, err := dc.executeInner(query, Dm_build_686)
+ if err != nil {
+ return nil, err
+ }
+
+ if r2, ok := r1.(*DmRows); ok {
+ return r2, nil
+ } else {
+ return nil, ECGO_NOT_QUERY_SQL.throw()
+ }
+ }
+
+}
+
+func (dc *DmConnection) prepare(query string) (*DmStatement, error) {
+ err := dc.checkClosed()
+ if err != nil {
+ return nil, err
+ }
+
+ stmt, err := NewDmStmt(dc, query)
+ if err != nil {
+ return nil, err
+ }
+
+ err = stmt.prepare()
+ return stmt, err
+}
+
+func (dc *DmConnection) prepareContext(ctx context.Context, query string) (*DmStatement, error) {
+ if err := dc.watchCancel(ctx); err != nil {
+ return nil, err
+ }
+ defer dc.finish()
+
+ err := dc.checkClosed()
+ if err != nil {
+ return nil, err
+ }
+
+ stmt, err := dc.prepare(query)
+ if err != nil {
+ return nil, err
+ }
+
+ return stmt, nil
+}
+
+func (dc *DmConnection) resetSession(ctx context.Context) error {
+ err := dc.checkClosed()
+ if err != nil {
+ return err
+ }
+
+ for _, stmt := range dc.stmtMap {
+ stmt.inUse = false
+ }
+
+ return nil
+}
+
+func (dc *DmConnection) checkNamedValue(nv *driver.NamedValue) error {
+ var err error
+ var cvt = converter{dc, false}
+ nv.Value, err = cvt.ConvertValue(nv.Value)
+ dc.isBatch = cvt.isBatch
+ return err
+}
+
+func (dc *DmConnection) driverQuery(query string) (*DmStatement, *DmRows, error) {
+ stmt, err := NewDmStmt(dc, query)
+ if err != nil {
+ return nil, nil, err
+ }
+ stmt.innerUsed = true
+ stmt.innerExec = true
+ info, err := dc.Access.Dm_build_417(stmt, Dm_build_686)
+ if err != nil {
+ return nil, nil, err
+ }
+ dc.lastExecInfo = info
+ stmt.innerExec = false
+ return stmt, newDmRows(newInnerRows(0, stmt, info)), nil
+}
+
+func (dc *DmConnection) getIndexOnEPGroup() int32 {
+ if dc.dmConnector.group == nil || dc.dmConnector.group.epList == nil {
+ return -1
+ }
+ for i := 0; i < len(dc.dmConnector.group.epList); i++ {
+ ep := dc.dmConnector.group.epList[i]
+ if dc.dmConnector.host == ep.host && dc.dmConnector.port == ep.port {
+ return int32(i)
+ }
+ }
+ return -1
+}
+
+func (dc *DmConnection) getServerEncoding() string {
+ if dc.dmConnector.charCode != "" {
+ return dc.dmConnector.charCode
+ }
+ return dc.serverEncoding
+}
+
+func (dc *DmConnection) lobFetchAll() bool {
+ return dc.dmConnector.lobMode == 2
+}
+
+func (conn *DmConnection) CompatibleOracle() bool {
+ return conn.dmConnector.compatibleMode == COMPATIBLE_MODE_ORACLE
+}
+
+func (conn *DmConnection) CompatibleMysql() bool {
+ return conn.dmConnector.compatibleMode == COMPATIBLE_MODE_MYSQL
+}
+
+func (conn *DmConnection) cancel(err error) {
+ conn.canceled.Set(err)
+ fmt.Println(conn.close())
+}
+
+func (conn *DmConnection) finish() {
+ if !conn.watching || conn.finished == nil {
+ return
+ }
+ select {
+ case conn.finished <- struct{}{}:
+ conn.watching = false
+ case <-conn.closech:
+ }
+}
+
+func (conn *DmConnection) startWatcher() {
+ watcher := make(chan context.Context, 1)
+ conn.watcher = watcher
+ finished := make(chan struct{})
+ conn.finished = finished
+ go func() {
+ for {
+ var ctx context.Context
+ select {
+ case ctx = <-watcher:
+ case <-conn.closech:
+ return
+ }
+
+ select {
+ case <-ctx.Done():
+ conn.cancel(ctx.Err())
+ case <-finished:
+ case <-conn.closech:
+ return
+ }
+ }
+ }()
+}
+
+func (conn *DmConnection) watchCancel(ctx context.Context) error {
+ if conn.watching {
+
+ conn.cleanup()
+ return nil
+ }
+
+ if err := ctx.Err(); err != nil {
+ return err
+ }
+
+ if ctx.Done() == nil {
+ return nil
+ }
+
+ if conn.watcher == nil {
+ return nil
+ }
+
+ conn.watching = true
+ conn.watcher <- ctx
+ return nil
+}
+
+type noCopy struct{}
+
+func (*noCopy) Lock() {}
+
+type atomicBool struct {
+ _noCopy noCopy
+ value uint32
+}
+
+func (ab *atomicBool) IsSet() bool {
+ return atomic.LoadUint32(&ab.value) > 0
+}
+
+func (ab *atomicBool) Set(value bool) {
+ if value {
+ atomic.StoreUint32(&ab.value, 1)
+ } else {
+ atomic.StoreUint32(&ab.value, 0)
+ }
+}
+
+func (ab *atomicBool) TrySet(value bool) bool {
+ if value {
+ return atomic.SwapUint32(&ab.value, 1) == 0
+ }
+ return atomic.SwapUint32(&ab.value, 0) > 0
+}
+
+type atomicError struct {
+ _noCopy noCopy
+ value atomic.Value
+}
+
+func (ae *atomicError) Set(value error) {
+ ae.value.Store(value)
+}
+
+func (ae *atomicError) Value() error {
+ if v := ae.value.Load(); v != nil {
+
+ return v.(error)
+ }
+ return nil
+}
diff --git a/dmr/n.go b/dmr/n.go
new file mode 100644
index 0000000..8c329b7
--- /dev/null
+++ b/dmr/n.go
@@ -0,0 +1,897 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "bytes"
+ "context"
+ "database/sql/driver"
+ "net"
+ "net/url"
+ "os"
+ "path/filepath"
+ "regexp"
+ "runtime"
+ "strconv"
+ "strings"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+const (
+ TimeZoneKey = "timeZone"
+ EnRsCacheKey = "enRsCache"
+ RsCacheSizeKey = "rsCacheSize"
+ RsRefreshFreqKey = "rsRefreshFreq"
+ LoginPrimary = "loginPrimary"
+ LoginModeKey = "loginMode"
+ LoginStatusKey = "loginStatus"
+ LoginDscCtrlKey = "loginDscCtrl"
+ SwitchTimesKey = "switchTimes"
+ SwitchIntervalKey = "switchInterval"
+ EpSelectorKey = "epSelector"
+ PrimaryKey = "primaryKey"
+ KeywordsKey = "keywords"
+ CompressKey = "compress"
+ CompressIdKey = "compressId"
+ LoginEncryptKey = "loginEncrypt"
+ CommunicationEncryptKey = "communicationEncrypt"
+ DirectKey = "direct"
+ Dec2DoubleKey = "dec2double"
+ RwSeparateKey = "rwSeparate"
+ RwPercentKey = "rwPercent"
+ RwAutoDistributeKey = "rwAutoDistribute"
+ CompatibleModeKey = "compatibleMode"
+ CompatibleOraKey = "comOra"
+ CipherPathKey = "cipherPath"
+ DoSwitchKey = "doSwitch"
+ ClusterKey = "cluster"
+ LanguageKey = "language"
+ DbAliveCheckFreqKey = "dbAliveCheckFreq"
+ RwStandbyRecoverTimeKey = "rwStandbyRecoverTime"
+ LogLevelKey = "logLevel"
+ LogDirKey = "logDir"
+ LogBufferPoolSizeKey = "logBufferPoolSize"
+ LogBufferSizeKey = "logBufferSize"
+ LogFlusherQueueSizeKey = "logFlusherQueueSize"
+ LogFlushFreqKey = "logFlushFreq"
+ StatEnableKey = "statEnable"
+ StatDirKey = "statDir"
+ StatFlushFreqKey = "statFlushFreq"
+ StatHighFreqSqlCountKey = "statHighFreqSqlCount"
+ StatSlowSqlCountKey = "statSlowSqlCount"
+ StatSqlMaxCountKey = "statSqlMaxCount"
+ StatSqlRemoveModeKey = "statSqlRemoveMode"
+ AddressRemapKey = "addressRemap"
+ UserRemapKey = "userRemap"
+ ConnectTimeoutKey = "connectTimeout"
+ LoginCertificateKey = "loginCertificate"
+ UrlKey = "url"
+ HostKey = "host"
+ PortKey = "port"
+ UserKey = "user"
+ PasswordKey = "password"
+ RwStandbyKey = "rwStandby"
+ IsCompressKey = "isCompress"
+ RwHAKey = "rwHA"
+ RwIgnoreSqlKey = "rwIgnoreSql"
+ AppNameKey = "appName"
+ OsNameKey = "osName"
+ MppLocalKey = "mppLocal"
+ SocketTimeoutKey = "socketTimeout"
+ SessionTimeoutKey = "sessionTimeout"
+ ContinueBatchOnErrorKey = "continueBatchOnError"
+ BatchAllowMaxErrorsKey = "batchAllowMaxErrors"
+ EscapeProcessKey = "escapeProcess"
+ AutoCommitKey = "autoCommit"
+ MaxRowsKey = "maxRows"
+ RowPrefetchKey = "rowPrefetch"
+ BufPrefetchKey = "bufPrefetch"
+ LobModeKey = "LobMode"
+ StmtPoolSizeKey = "StmtPoolSize"
+ IgnoreCaseKey = "ignoreCase"
+ AlwayseAllowCommitKey = "AlwayseAllowCommit"
+ BatchTypeKey = "batchType"
+ BatchNotOnCallKey = "batchNotOnCall"
+ IsBdtaRSKey = "isBdtaRS"
+ ClobAsStringKey = "clobAsString"
+ SslCertPathKey = "sslCertPath"
+ SslKeyPathKey = "sslKeyPath"
+ SslFilesPathKey = "sslFilesPath"
+ KerberosLoginConfPathKey = "kerberosLoginConfPath"
+ UKeyNameKey = "uKeyName"
+ UKeyPinKey = "uKeyPin"
+ ColumnNameUpperCaseKey = "columnNameUpperCase"
+ ColumnNameCaseKey = "columnNameCase"
+ DatabaseProductNameKey = "databaseProductName"
+ OsAuthTypeKey = "osAuthType"
+ SchemaKey = "schema"
+
+ TIME_ZONE_DEFAULT int16 = 480
+
+ DO_SWITCH_OFF int32 = 0
+ DO_SWITCH_WHEN_CONN_ERROR int32 = 1
+ DO_SWITCH_WHEN_EP_RECOVER int32 = 2
+
+ CLUSTER_TYPE_NORMAL int32 = 0
+ CLUSTER_TYPE_RW int32 = 1
+ CLUSTER_TYPE_DW int32 = 2
+ CLUSTER_TYPE_DSC int32 = 3
+ CLUSTER_TYPE_MPP int32 = 4
+
+ EP_STATUS_OK int32 = 1
+ EP_STATUS_ERROR int32 = 2
+
+ LOGIN_MODE_PRIMARY_FIRST int32 = 0
+
+ LOGIN_MODE_PRIMARY_ONLY int32 = 1
+
+ LOGIN_MODE_STANDBY_ONLY int32 = 2
+
+ LOGIN_MODE_STANDBY_FIRST int32 = 3
+
+ LOGIN_MODE_NORMAL_FIRST int32 = 4
+
+ SERVER_MODE_NORMAL int32 = 0
+
+ SERVER_MODE_PRIMARY int32 = 1
+
+ SERVER_MODE_STANDBY int32 = 2
+
+ SERVER_STATUS_MOUNT int32 = 3
+
+ SERVER_STATUS_OPEN int32 = 4
+
+ SERVER_STATUS_SUSPEND int32 = 5
+
+ COMPATIBLE_MODE_ORACLE int = 1
+
+ COMPATIBLE_MODE_MYSQL int = 2
+
+ LANGUAGE_CN int = 0
+
+ LANGUAGE_EN int = 1
+
+ COLUMN_NAME_NATURAL_CASE = 0
+
+ COLUMN_NAME_UPPER_CASE = 1
+
+ COLUMN_NAME_LOWER_CASE = 2
+
+ compressDef = Dm_build_681
+ compressIDDef = Dm_build_682
+
+ charCodeDef = ""
+
+ enRsCacheDef = false
+
+ rsCacheSizeDef = 20
+
+ rsRefreshFreqDef = 10
+
+ loginModeDef = LOGIN_MODE_NORMAL_FIRST
+
+ loginStatusDef = 0
+
+ loginEncryptDef = true
+
+ loginCertificateDef = ""
+
+ dec2DoubleDef = false
+
+ rwHADef = false
+
+ rwStandbyDef = false
+
+ rwSeparateDef = false
+
+ rwPercentDef = 25
+
+ rwAutoDistributeDef = true
+
+ rwStandbyRecoverTimeDef = 1000
+
+ cipherPathDef = ""
+
+ urlDef = ""
+
+ userDef = "SYSDBA"
+
+ passwordDef = "SYSDBA"
+
+ hostDef = "localhost"
+
+ portDef = DEFAULT_PORT
+
+ appNameDef = ""
+
+ mppLocalDef = false
+
+ socketTimeoutDef = 0
+
+ connectTimeoutDef = 5000
+
+ sessionTimeoutDef = 0
+
+ osAuthTypeDef = Dm_build_664
+
+ continueBatchOnErrorDef = false
+
+ escapeProcessDef = false
+
+ autoCommitDef = true
+
+ maxRowsDef = 0
+
+ rowPrefetchDef = Dm_build_665
+
+ bufPrefetchDef = 0
+
+ lobModeDef = 1
+
+ stmtPoolMaxSizeDef = 15
+
+ ignoreCaseDef = true
+
+ alwayseAllowCommitDef = true
+
+ isBdtaRSDef = false
+
+ kerberosLoginConfPathDef = ""
+
+ uKeyNameDef = ""
+
+ uKeyPinDef = ""
+
+ databaseProductNameDef = ""
+
+ caseSensitiveDef = true
+
+ compatibleModeDef = 0
+
+ localTimezoneDef = TIME_ZONE_DEFAULT
+)
+
+type DmConnector struct {
+ filterable
+
+ dmDriver *DmDriver
+
+ compress int
+
+ compressID int8
+
+ newClientType bool
+
+ charCode string
+
+ enRsCache bool
+
+ rsCacheSize int
+
+ rsRefreshFreq int
+
+ loginMode int32
+
+ loginStatus int
+
+ loginDscCtrl bool
+
+ switchTimes int32
+
+ switchInterval int
+
+ epSelector int32
+
+ keyWords []string
+
+ loginEncrypt bool
+
+ loginCertificate string
+
+ dec2Double bool
+
+ rwHA bool
+
+ rwStandby bool
+
+ rwSeparate bool
+
+ rwPercent int32
+
+ rwAutoDistribute bool
+
+ rwStandbyRecoverTime int
+
+ rwIgnoreSql bool
+
+ doSwitch int32
+
+ cluster int32
+
+ cipherPath string
+
+ url string
+
+ user string
+
+ password string
+
+ host string
+
+ group *epGroup
+
+ port int32
+
+ appName string
+
+ osName string
+
+ mppLocal bool
+
+ socketTimeout int
+
+ connectTimeout int
+
+ sessionTimeout int
+
+ osAuthType byte
+
+ continueBatchOnError bool
+
+ batchAllowMaxErrors int32
+
+ escapeProcess bool
+
+ autoCommit bool
+
+ maxRows int
+
+ rowPrefetch int
+
+ bufPrefetch int
+
+ lobMode int
+
+ stmtPoolMaxSize int
+
+ ignoreCase bool
+
+ alwayseAllowCommit bool
+
+ batchType int
+
+ batchNotOnCall bool
+
+ isBdtaRS bool
+
+ sslCertPath string
+
+ sslKeyPath string
+
+ sslFilesPath string
+
+ kerberosLoginConfPath string
+
+ uKeyName string
+
+ uKeyPin string
+
+ svcConfPath string
+
+ columnNameCase int
+
+ caseSensitive bool
+
+ compatibleMode int
+
+ localTimezone int16
+
+ schema string
+
+ reConnection *DmConnection
+
+ logLevel int
+
+ logDir string
+
+ logFlushFreq int
+
+ logFlushQueueSize int
+
+ logBufferSize int
+
+ statEnable bool
+
+ statDir string
+
+ statFlushFreq int
+
+ statSlowSqlCount int
+
+ statHighFreqSqlCount int
+
+ statSqlMaxCount int
+
+ statSqlRemoveMode int
+}
+
+func (c *DmConnector) init() *DmConnector {
+ c.compress = compressDef
+ c.compressID = compressIDDef
+ c.charCode = charCodeDef
+ c.enRsCache = enRsCacheDef
+ c.rsCacheSize = rsCacheSizeDef
+ c.rsRefreshFreq = rsRefreshFreqDef
+ c.loginMode = loginModeDef
+ c.loginStatus = loginStatusDef
+ c.loginDscCtrl = false
+ c.switchTimes = 1
+ c.switchInterval = 1000
+ c.epSelector = 0
+ c.keyWords = nil
+ c.loginEncrypt = loginEncryptDef
+ c.loginCertificate = loginCertificateDef
+ c.dec2Double = dec2DoubleDef
+ c.rwHA = rwHADef
+ c.rwStandby = rwStandbyDef
+ c.rwSeparate = rwSeparateDef
+ c.rwPercent = rwPercentDef
+ c.rwAutoDistribute = rwAutoDistributeDef
+ c.rwStandbyRecoverTime = rwStandbyRecoverTimeDef
+ c.rwIgnoreSql = false
+ c.doSwitch = DO_SWITCH_OFF
+ c.cluster = CLUSTER_TYPE_NORMAL
+ c.cipherPath = cipherPathDef
+ c.url = urlDef
+ c.user = userDef
+ c.password = passwordDef
+ c.host = hostDef
+ c.port = portDef
+ c.appName = appNameDef
+ c.osName = runtime.GOOS
+ c.mppLocal = mppLocalDef
+ c.socketTimeout = socketTimeoutDef
+ c.connectTimeout = connectTimeoutDef
+ c.sessionTimeout = sessionTimeoutDef
+ c.osAuthType = osAuthTypeDef
+ c.continueBatchOnError = continueBatchOnErrorDef
+ c.batchAllowMaxErrors = 0
+ c.escapeProcess = escapeProcessDef
+ c.autoCommit = autoCommitDef
+ c.maxRows = maxRowsDef
+ c.rowPrefetch = rowPrefetchDef
+ c.bufPrefetch = bufPrefetchDef
+ c.lobMode = lobModeDef
+ c.stmtPoolMaxSize = stmtPoolMaxSizeDef
+ c.ignoreCase = ignoreCaseDef
+ c.alwayseAllowCommit = alwayseAllowCommitDef
+ c.batchType = 1
+ c.batchNotOnCall = false
+ c.isBdtaRS = isBdtaRSDef
+ c.kerberosLoginConfPath = kerberosLoginConfPathDef
+ c.uKeyName = uKeyNameDef
+ c.uKeyPin = uKeyPinDef
+ c.columnNameCase = COLUMN_NAME_NATURAL_CASE
+ c.caseSensitive = caseSensitiveDef
+ c.compatibleMode = compatibleModeDef
+ c.localTimezone = localTimezoneDef
+ c.idGenerator = dmConntorIDGenerator
+
+ c.logDir = LogDirDef
+ c.logFlushFreq = LogFlushFreqDef
+ c.logFlushQueueSize = LogFlushQueueSizeDef
+ c.logBufferSize = LogBufferSizeDef
+ c.statEnable = StatEnableDef
+ c.statDir = StatDirDef
+ c.statFlushFreq = StatFlushFreqDef
+ c.statSlowSqlCount = StatSlowSqlCountDef
+ c.statHighFreqSqlCount = StatHighFreqSqlCountDef
+ c.statSqlMaxCount = StatSqlMaxCountDef
+ c.statSqlRemoveMode = StatSqlRemoveModeDef
+ return c
+}
+
+func (c *DmConnector) setAttributes(props *Properties) error {
+ if props == nil || props.Len() == 0 {
+ return nil
+ }
+
+ c.url = props.GetTrimString(UrlKey, c.url)
+ c.host = props.GetTrimString(HostKey, c.host)
+ c.port = int32(props.GetInt(PortKey, int(c.port), 0, 65535))
+ c.user = props.GetString(UserKey, c.user)
+ c.password = props.GetString(PasswordKey, c.password)
+ c.rwStandby = props.GetBool(RwStandbyKey, c.rwStandby)
+
+ if b := props.GetBool(IsCompressKey, false); b {
+ c.compress = Dm_build_680
+ }
+
+ c.compress = props.GetInt(CompressKey, c.compress, 0, 2)
+ c.compressID = int8(props.GetInt(CompressIdKey, int(c.compressID), 0, 1))
+ c.enRsCache = props.GetBool(EnRsCacheKey, c.enRsCache)
+ c.localTimezone = int16(props.GetInt(TimeZoneKey, int(c.localTimezone), -720, 720))
+ c.rsCacheSize = props.GetInt(RsCacheSizeKey, c.rsCacheSize, 0, int(INT32_MAX))
+ c.rsRefreshFreq = props.GetInt(RsRefreshFreqKey, c.rsRefreshFreq, 0, int(INT32_MAX))
+ c.loginMode = int32(props.GetInt(LoginModeKey, int(c.loginMode), 0, 4))
+ c.loginStatus = props.GetInt(LoginStatusKey, c.loginStatus, 0, int(INT32_MAX))
+ c.loginDscCtrl = props.GetBool(LoginDscCtrlKey, c.loginDscCtrl)
+ c.switchTimes = int32(props.GetInt(SwitchTimesKey, int(c.switchTimes), 0, int(INT32_MAX)))
+ c.switchInterval = props.GetInt(SwitchIntervalKey, c.switchInterval, 0, int(INT32_MAX))
+ c.epSelector = int32(props.GetInt(EpSelectorKey, int(c.epSelector), 0, 1))
+ c.loginEncrypt = props.GetBool(LoginEncryptKey, c.loginEncrypt)
+ c.loginCertificate = props.GetTrimString(LoginCertificateKey, c.loginCertificate)
+ c.dec2Double = props.GetBool(Dec2DoubleKey, c.dec2Double)
+
+ c.rwSeparate = props.GetBool(RwSeparateKey, c.rwSeparate)
+ c.rwAutoDistribute = props.GetBool(RwAutoDistributeKey, c.rwAutoDistribute)
+ c.rwPercent = int32(props.GetInt(RwPercentKey, int(c.rwPercent), 0, 100))
+ c.rwHA = props.GetBool(RwHAKey, c.rwHA)
+ c.rwStandbyRecoverTime = props.GetInt(RwStandbyRecoverTimeKey, c.rwStandbyRecoverTime, 0, int(INT32_MAX))
+ c.rwIgnoreSql = props.GetBool(RwIgnoreSqlKey, c.rwIgnoreSql)
+ c.doSwitch = int32(props.GetInt(DoSwitchKey, int(c.doSwitch), 0, 2))
+ c.parseCluster(props)
+ c.cipherPath = props.GetTrimString(CipherPathKey, c.cipherPath)
+
+ if props.GetBool(CompatibleOraKey, false) {
+ c.compatibleMode = int(COMPATIBLE_MODE_ORACLE)
+ }
+ c.parseCompatibleMode(props)
+ c.keyWords = props.GetStringArray(KeywordsKey, c.keyWords)
+
+ c.appName = props.GetTrimString(AppNameKey, c.appName)
+ c.osName = props.GetTrimString(OsNameKey, c.osName)
+ c.mppLocal = props.GetBool(MppLocalKey, c.mppLocal)
+ c.socketTimeout = props.GetInt(SocketTimeoutKey, c.socketTimeout, 0, int(INT32_MAX))
+ c.connectTimeout = props.GetInt(ConnectTimeoutKey, c.connectTimeout, 0, int(INT32_MAX))
+ c.sessionTimeout = props.GetInt(SessionTimeoutKey, c.sessionTimeout, 0, int(INT32_MAX))
+
+ err := c.parseOsAuthType(props)
+ if err != nil {
+ return err
+ }
+ c.continueBatchOnError = props.GetBool(ContinueBatchOnErrorKey, c.continueBatchOnError)
+ c.batchAllowMaxErrors = int32(props.GetInt(BatchAllowMaxErrorsKey, int(c.batchAllowMaxErrors), 0, int(INT32_MAX)))
+ c.escapeProcess = props.GetBool(EscapeProcessKey, c.escapeProcess)
+ c.autoCommit = props.GetBool(AutoCommitKey, c.autoCommit)
+ c.maxRows = props.GetInt(MaxRowsKey, c.maxRows, 0, int(INT32_MAX))
+ c.rowPrefetch = props.GetInt(RowPrefetchKey, c.rowPrefetch, 0, int(INT32_MAX))
+ c.bufPrefetch = props.GetInt(BufPrefetchKey, c.bufPrefetch, int(Dm_build_666), int(Dm_build_667))
+ c.lobMode = props.GetInt(LobModeKey, c.lobMode, 1, 2)
+ c.stmtPoolMaxSize = props.GetInt(StmtPoolSizeKey, c.stmtPoolMaxSize, 0, int(INT32_MAX))
+ c.ignoreCase = props.GetBool(IgnoreCaseKey, c.ignoreCase)
+ c.alwayseAllowCommit = props.GetBool(AlwayseAllowCommitKey, c.alwayseAllowCommit)
+ c.batchType = props.GetInt(BatchTypeKey, c.batchType, 1, 2)
+ c.batchNotOnCall = props.GetBool(BatchNotOnCallKey, c.batchNotOnCall)
+ c.isBdtaRS = props.GetBool(IsBdtaRSKey, c.isBdtaRS)
+ c.sslFilesPath = props.GetTrimString(SslFilesPathKey, c.sslFilesPath)
+ c.sslCertPath = props.GetTrimString(SslCertPathKey, c.sslCertPath)
+ if c.sslCertPath == "" && c.sslFilesPath != "" {
+ c.sslCertPath = filepath.Join(c.sslFilesPath, "client-cert.pem")
+ }
+ c.sslKeyPath = props.GetTrimString(SslKeyPathKey, c.sslKeyPath)
+ if c.sslKeyPath == "" && c.sslFilesPath != "" {
+ c.sslKeyPath = filepath.Join(c.sslKeyPath, "client-key.pem")
+ }
+
+ c.kerberosLoginConfPath = props.GetTrimString(KerberosLoginConfPathKey, c.kerberosLoginConfPath)
+
+ c.uKeyName = props.GetTrimString(UKeyNameKey, c.uKeyName)
+ c.uKeyPin = props.GetTrimString(UKeyPinKey, c.uKeyPin)
+
+ c.svcConfPath = props.GetString("confPath", "")
+
+ if props.GetBool(ColumnNameUpperCaseKey, false) {
+ c.columnNameCase = COLUMN_NAME_UPPER_CASE
+ }
+
+ v := props.GetTrimString(ColumnNameCaseKey, "")
+ if util.StringUtil.EqualsIgnoreCase(v, "upper") {
+ c.columnNameCase = COLUMN_NAME_UPPER_CASE
+ } else if util.StringUtil.EqualsIgnoreCase(v, "lower") {
+ c.columnNameCase = COLUMN_NAME_LOWER_CASE
+ }
+
+ c.schema = props.GetTrimString(SchemaKey, c.schema)
+
+ c.logLevel = ParseLogLevel(props)
+ LogLevel = c.logLevel
+ c.logDir = util.StringUtil.FormatDir(props.GetTrimString(LogDirKey, LogDirDef))
+ LogDir = c.logDir
+ c.logBufferSize = props.GetInt(LogBufferSizeKey, LogBufferSizeDef, 1, int(INT32_MAX))
+ LogBufferSize = c.logBufferSize
+ c.logFlushFreq = props.GetInt(LogFlushFreqKey, LogFlushFreqDef, 1, int(INT32_MAX))
+ LogFlushFreq = c.logFlushFreq
+ c.logFlushQueueSize = props.GetInt(LogFlusherQueueSizeKey, LogFlushQueueSizeDef, 1, int(INT32_MAX))
+ LogFlushQueueSize = c.logFlushQueueSize
+
+ c.statEnable = props.GetBool(StatEnableKey, StatEnableDef)
+ StatEnable = c.statEnable
+ c.statDir = util.StringUtil.FormatDir(props.GetTrimString(StatDirKey, StatDirDef))
+ StatDir = c.statDir
+ c.statFlushFreq = props.GetInt(StatFlushFreqKey, StatFlushFreqDef, 1, int(INT32_MAX))
+ StatFlushFreq = c.statFlushFreq
+ c.statHighFreqSqlCount = props.GetInt(StatHighFreqSqlCountKey, StatHighFreqSqlCountDef, 0, 1000)
+ StatHighFreqSqlCount = c.statHighFreqSqlCount
+ c.statSlowSqlCount = props.GetInt(StatSlowSqlCountKey, StatSlowSqlCountDef, 0, 1000)
+ StatSlowSqlCount = c.statSlowSqlCount
+ c.statSqlMaxCount = props.GetInt(StatSqlMaxCountKey, StatSqlMaxCountDef, 0, 100000)
+ StatSqlMaxCount = c.statSqlMaxCount
+ c.parseStatSqlRemoveMode(props)
+ return nil
+}
+
+func (c *DmConnector) parseOsAuthType(props *Properties) error {
+ value := props.GetString(OsAuthTypeKey, "")
+ if value != "" && !util.StringUtil.IsDigit(value) {
+ if util.StringUtil.EqualsIgnoreCase(value, "ON") {
+ c.osAuthType = Dm_build_664
+ } else if util.StringUtil.EqualsIgnoreCase(value, "SYSDBA") {
+ c.osAuthType = Dm_build_660
+ } else if util.StringUtil.EqualsIgnoreCase(value, "SYSAUDITOR") {
+ c.osAuthType = Dm_build_662
+ } else if util.StringUtil.EqualsIgnoreCase(value, "SYSSSO") {
+ c.osAuthType = Dm_build_661
+ } else if util.StringUtil.EqualsIgnoreCase(value, "AUTO") {
+ c.osAuthType = Dm_build_663
+ } else if util.StringUtil.EqualsIgnoreCase(value, "OFF") {
+ c.osAuthType = Dm_build_659
+ }
+ } else {
+ c.osAuthType = byte(props.GetInt(OsAuthTypeKey, int(c.osAuthType), 0, 4))
+ }
+ if c.user == "" && c.osAuthType == Dm_build_659 {
+ c.user = "SYSDBA"
+ } else if c.osAuthType != Dm_build_659 && c.user != "" {
+ return ECGO_OSAUTH_ERROR.throw()
+ } else if c.osAuthType != Dm_build_659 {
+ c.user = os.Getenv("user")
+ c.password = ""
+ }
+ return nil
+}
+
+func (c *DmConnector) parseCompatibleMode(props *Properties) {
+ value := props.GetString(CompatibleModeKey, "")
+ if value != "" && !util.StringUtil.IsDigit(value) {
+ if util.StringUtil.EqualsIgnoreCase(value, "oracle") {
+ c.compatibleMode = COMPATIBLE_MODE_ORACLE
+ } else if util.StringUtil.EqualsIgnoreCase(value, "mysql") {
+ c.compatibleMode = COMPATIBLE_MODE_MYSQL
+ }
+ } else {
+ c.compatibleMode = props.GetInt(CompatibleModeKey, c.compatibleMode, 0, 2)
+ }
+}
+
+func (c *DmConnector) parseStatSqlRemoveMode(props *Properties) {
+ value := props.GetString(StatSqlRemoveModeKey, "")
+ if value != "" && !util.StringUtil.IsDigit(value) {
+ if util.StringUtil.EqualsIgnoreCase("oldest", value) || util.StringUtil.EqualsIgnoreCase("eldest", value) {
+ c.statSqlRemoveMode = STAT_SQL_REMOVE_OLDEST
+ } else if util.StringUtil.EqualsIgnoreCase("latest", value) {
+ c.statSqlRemoveMode = STAT_SQL_REMOVE_LATEST
+ }
+ } else {
+ c.statSqlRemoveMode = props.GetInt(StatSqlRemoveModeKey, StatSqlRemoveModeDef, 1, 2)
+ }
+}
+
+func (c *DmConnector) parseCluster(props *Properties) {
+ value := props.GetTrimString(ClusterKey, "")
+ if util.StringUtil.EqualsIgnoreCase(value, "DSC") {
+ c.cluster = CLUSTER_TYPE_DSC
+ } else if util.StringUtil.EqualsIgnoreCase(value, "RW") {
+ c.cluster = CLUSTER_TYPE_RW
+ } else if util.StringUtil.EqualsIgnoreCase(value, "DW") {
+ c.cluster = CLUSTER_TYPE_DW
+ } else if util.StringUtil.EqualsIgnoreCase(value, "MPP") {
+ c.cluster = CLUSTER_TYPE_MPP
+ } else {
+ c.cluster = CLUSTER_TYPE_NORMAL
+ }
+}
+
+func (c *DmConnector) parseDSN(dsn string) (*Properties, string, error) {
+ var dsnProps = NewProperties()
+ url, err := url.Parse(dsn)
+ if err != nil {
+ return nil, "", err
+ }
+ if url.Scheme != "dm" {
+ return nil, "", DSN_INVALID_SCHEMA
+ }
+
+ if url.User != nil {
+ c.user = url.User.Username()
+ c.password, _ = url.User.Password()
+ }
+
+ q := url.Query()
+ for k := range q {
+ dsnProps.Set(k, q.Get(k))
+ }
+
+ return dsnProps, url.Host, nil
+}
+
+func (c *DmConnector) BuildDSN() string {
+ var buf bytes.Buffer
+
+ buf.WriteString("dm://")
+
+ if len(c.user) > 0 {
+ buf.WriteString(url.QueryEscape(c.user))
+ if len(c.password) > 0 {
+ buf.WriteByte(':')
+ buf.WriteString(url.QueryEscape(c.password))
+ }
+ buf.WriteByte('@')
+ }
+
+ if len(c.host) > 0 {
+ buf.WriteString(c.host)
+ if c.port > 0 {
+ buf.WriteByte(':')
+ buf.WriteString(strconv.Itoa(int(c.port)))
+ }
+ }
+
+ hasParam := false
+ if c.connectTimeout > 0 {
+ if hasParam {
+ buf.WriteString("&timeout=")
+ } else {
+ buf.WriteString("?timeout=")
+ hasParam = true
+ }
+ buf.WriteString(strconv.Itoa(c.connectTimeout))
+ }
+ return buf.String()
+}
+
+func (c *DmConnector) mergeConfigs(dsn string) error {
+ props, host, err := c.parseDSN(dsn)
+ if err != nil {
+ return err
+ }
+
+ driverInit(props.GetString("svcConfPath", ""))
+
+ addressRemapStr := props.GetTrimString(AddressRemapKey, "")
+ userRemapStr := props.GetTrimString(UserRemapKey, "")
+ if addressRemapStr == "" {
+ addressRemapStr = GlobalProperties.GetTrimString(AddressRemapKey, "")
+ }
+ if userRemapStr == "" {
+ userRemapStr = GlobalProperties.GetTrimString(UserRemapKey, "")
+ }
+
+ host = c.remap(host, addressRemapStr)
+
+ c.user = c.remap(c.user, userRemapStr)
+
+ if group, ok := ServerGroupMap[strings.ToLower(host)]; ok {
+ c.group = group
+ } else {
+ host, port, err := net.SplitHostPort(host)
+ if err != nil || net.ParseIP(host) == nil {
+ c.host = hostDef
+ } else {
+ c.host = host
+ }
+ tmpPort, err := strconv.Atoi(port)
+ if err != nil {
+ c.port = portDef
+ } else {
+ c.port = int32(tmpPort)
+ }
+
+ c.group = newEPGroup(c.host+":"+strconv.Itoa(int(c.port)), []*ep{newEP(c.host, c.port)})
+ }
+
+ props.SetDiffProperties(c.group.props)
+
+ props.SetDiffProperties(GlobalProperties)
+
+ if props.GetBool(RwSeparateKey, false) {
+ props.SetIfNotExist(LoginModeKey, strconv.Itoa(int(LOGIN_MODE_PRIMARY_ONLY)))
+ props.SetIfNotExist(LoginStatusKey, strconv.Itoa(int(SERVER_STATUS_OPEN)))
+
+ props.SetIfNotExist(DoSwitchKey, "true")
+ }
+
+ if err = c.setAttributes(props); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (c *DmConnector) remap(origin string, cfgStr string) string {
+ if cfgStr == "" || origin == "" {
+ return origin
+ }
+
+ maps := regexp.MustCompile("\\(.*?,.*?\\)").FindAllString(cfgStr, -1)
+ for _, kvStr := range maps {
+ kv := strings.Split(strings.TrimSpace(kvStr[1:len(kvStr)-1]), ",")
+ if util.StringUtil.Equals(strings.TrimSpace(kv[0]), origin) {
+ return strings.TrimSpace(kv[1])
+ }
+ }
+ return origin
+}
+
+func (c *DmConnector) Connect(ctx context.Context) (driver.Conn, error) {
+ return c.filterChain.reset().DmConnectorConnect(c, ctx)
+}
+
+func (c *DmConnector) Driver() driver.Driver {
+ return c.filterChain.reset().DmConnectorDriver(c)
+}
+
+func (c *DmConnector) connect(ctx context.Context) (*DmConnection, error) {
+ if c.group != nil && len(c.group.epList) > 0 {
+ return c.group.connect(c)
+ } else {
+ return c.connectSingle(ctx)
+ }
+}
+
+func (c *DmConnector) driver() *DmDriver {
+ return c.dmDriver
+}
+
+func (c *DmConnector) connectSingle(ctx context.Context) (*DmConnection, error) {
+ var err error
+ var dc *DmConnection
+ if c.reConnection == nil {
+ dc = &DmConnection{
+ closech: make(chan struct{}),
+ }
+ dc.dmConnector = c
+ dc.autoCommit = c.autoCommit
+ dc.createFilterChain(c, nil)
+
+ dc.objId = -1
+ dc.init()
+ } else {
+ dc = c.reConnection
+ dc.reset()
+ }
+
+ dc.Access, err = dm_build_344(dc)
+ if err != nil {
+ return nil, err
+ }
+
+ dc.startWatcher()
+ if err = dc.watchCancel(ctx); err != nil {
+ return nil, err
+ }
+ defer dc.finish()
+
+ if err = dc.Access.dm_build_385(); err != nil {
+
+ if !dc.closed.IsSet() {
+ close(dc.closech)
+ if dc.Access != nil {
+ dc.Access.Close()
+ }
+ dc.closed.Set(true)
+ }
+ return nil, err
+ }
+
+ if c.schema != "" {
+ _, err = dc.exec("set schema "+c.schema, nil)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return dc, nil
+}
diff --git a/dmr/o.go b/dmr/o.go
new file mode 100644
index 0000000..627a56a
--- /dev/null
+++ b/dmr/o.go
@@ -0,0 +1,436 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "database/sql/driver"
+ "math/big"
+ "reflect"
+ "strconv"
+ "strings"
+)
+
+const (
+ XDEC_MAX_PREC int = 38
+ XDEC_SIZE = 21
+
+ FLAG_ZERO int = 0x80
+ FLAG_POSITIVE int = 0xC1
+ FLAG_NEGTIVE int = 0x3E
+ EXP_MAX int = 0xFF - 1 - FLAG_POSITIVE
+ EXP_MIN int = FLAG_NEGTIVE + 1 - 0x7F
+
+ NUM_POSITIVE int = 1
+ NUM_NEGTIVE int = 101
+)
+
+type DmDecimal struct {
+ sign int
+ weight int
+ prec int
+ scale int
+ digits string
+
+ Valid bool
+}
+
+func NewDecimalFromInt64(x int64) (*DmDecimal, error) {
+ return NewDecimalFromBigInt(big.NewInt(x))
+}
+
+func (d DmDecimal) ToInt64() int64 {
+ return d.ToBigInt().Int64()
+}
+
+func NewDecimalFromFloat64(x float64) (*DmDecimal, error) {
+ return NewDecimalFromBigFloat(big.NewFloat(x))
+}
+
+func (d DmDecimal) ToFloat64() float64 {
+ f, _ := d.ToBigFloat().Float64()
+ return f
+}
+
+func NewDecimalFromBigInt(bigInt *big.Int) (*DmDecimal, error) {
+ return newDecimal(bigInt, len(bigInt.String()), 0)
+}
+
+func (d DmDecimal) ToBigInt() *big.Int {
+ if d.isZero() {
+ return big.NewInt(0)
+ }
+ var digits = d.digits
+ if d.sign < 0 {
+ digits = "-" + digits
+ }
+ i1, ok := new(big.Int).SetString(digits, 10)
+ if !ok {
+ return nil
+ }
+ if d.weight > 0 {
+ i2, ok := new(big.Int).SetString("1"+strings.Repeat("0", d.weight), 10)
+ if !ok {
+ return nil
+ }
+ i1.Mul(i1, i2)
+ } else if d.weight < 0 {
+ i2, ok := new(big.Int).SetString("1"+strings.Repeat("0", -d.weight), 10)
+ if !ok {
+ return nil
+ }
+ i1.Quo(i1, i2)
+ }
+ return i1
+}
+
+func NewDecimalFromBigFloat(bigFloat *big.Float) (*DmDecimal, error) {
+ return newDecimal(bigFloat, int(bigFloat.Prec()), int(bigFloat.Prec()))
+}
+
+func (d DmDecimal) ToBigFloat() *big.Float {
+ if d.isZero() {
+ return big.NewFloat(0.0)
+ }
+ var digits = d.digits
+ if d.sign < 0 {
+ digits = "-" + digits
+ }
+ f1, ok := new(big.Float).SetString(digits)
+ if !ok {
+ return nil
+ }
+ if d.weight > 0 {
+ f2, ok := new(big.Float).SetString("1" + strings.Repeat("0", d.weight))
+ if !ok {
+ return nil
+ }
+ f1.Mul(f1, f2)
+ } else if d.weight < 0 {
+ f2, ok := new(big.Float).SetString("1" + strings.Repeat("0", -d.weight))
+ if !ok {
+ return nil
+ }
+ f1.Quo(f1, f2)
+ }
+ return f1
+}
+
+func NewDecimalFromString(s string) (*DmDecimal, error) {
+ num, ok := new(big.Float).SetString(strings.TrimSpace(s))
+ if !ok {
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+ return NewDecimalFromBigFloat(num)
+}
+
+func (d DmDecimal) String() string {
+
+ if d.isZero() {
+ return "0"
+ }
+ digitsStr := d.digits
+ if d.weight > 0 {
+ digitsStr = digitsStr + strings.Repeat("0", d.weight)
+ } else if d.weight < 0 {
+ if len(digitsStr) < -d.weight {
+ digitsStr = strings.Repeat("0", -d.weight-len(digitsStr)+1) + digitsStr
+ }
+ indexOfDot := len(digitsStr) + d.weight
+ digitsStr = digitsStr[:indexOfDot] + "." + digitsStr[indexOfDot:]
+ }
+
+ if digitsStr[0] == '0' && digitsStr[1] != '.' {
+ digitsStr = digitsStr[1:]
+ }
+
+ if digitsStr[len(digitsStr)-1] == '0' && strings.IndexRune(digitsStr, '.') >= 0 {
+ digitsStr = digitsStr[0 : len(digitsStr)-1]
+ }
+
+ if d.sign < 0 {
+ digitsStr = "-" + digitsStr
+ }
+
+ return digitsStr
+}
+
+func (d DmDecimal) Sign() int {
+ return d.sign
+}
+
+func (dest *DmDecimal) Scan(src interface{}) error {
+ if dest == nil {
+ return ECGO_STORE_IN_NIL_POINTER.throw()
+ }
+ switch src := src.(type) {
+ case nil:
+ *dest = *new(DmDecimal)
+
+ (*dest).Valid = false
+ return nil
+ case int, int8, int16, int32, int64:
+ d, err := NewDecimalFromInt64(reflect.ValueOf(src).Int())
+ if err != nil {
+ return err
+ }
+ *dest = *d
+ return nil
+ case uint, uint8, uint16, uint32, uint64:
+ d, err := NewDecimalFromBigInt(new(big.Int).SetUint64(reflect.ValueOf(src).Uint()))
+ if err != nil {
+ return err
+ }
+ *dest = *d
+ return nil
+ case string:
+ d, err := NewDecimalFromString(src)
+ if err != nil {
+ return err
+ }
+ *dest = *d
+ return nil
+ case *DmDecimal:
+ *dest = *src
+ return nil
+ default:
+ return UNSUPPORTED_SCAN
+ }
+}
+
+func (d DmDecimal) Value() (driver.Value, error) {
+ if !d.Valid {
+ return nil, nil
+ }
+ return d, nil
+}
+
+func newDecimal(dec interface{}, prec int, scale int) (*DmDecimal, error) {
+ d := &DmDecimal{
+ prec: prec,
+ scale: scale,
+ Valid: true,
+ }
+ if isFloat(DECIMAL, scale) {
+ d.prec = getFloatPrec(prec)
+ d.scale = -1
+ }
+ switch de := dec.(type) {
+ case *big.Int:
+ d.sign = de.Sign()
+
+ if d.isZero() {
+ return d, nil
+ }
+ str := de.String()
+
+ if d.sign < 0 {
+ str = str[1:]
+ }
+
+ if err := checkPrec(len(str), prec); err != nil {
+ return d, err
+ }
+ i := 0
+ istart := len(str) - 1
+
+ for i = istart; i > 0; i-- {
+ if str[i] != '0' {
+ break
+ }
+ }
+ str = str[:i+1]
+ d.weight += istart - i
+
+ if isOdd(d.weight) {
+ str += "0"
+ d.weight -= 1
+ }
+ if isOdd(len(str)) {
+ str = "0" + str
+ }
+ d.digits = str
+ case *big.Float:
+ d.sign = de.Sign()
+
+ if d.isZero() {
+ return d, nil
+ }
+ str := de.Text('f', -1)
+
+ if d.sign < 0 {
+ str = str[1:]
+ }
+
+ pointIndex := strings.IndexByte(str, '.')
+ i, istart, length := 0, 0, len(str)
+
+ if pointIndex != -1 {
+ if str[0] == '0' {
+
+ istart = 2
+ for i = istart; i < length; i++ {
+ if str[i] != '0' {
+ break
+ }
+ }
+ str = str[i:]
+ d.weight -= i - istart + len(str)
+ } else {
+ str = str[:pointIndex] + str[pointIndex+1:]
+ d.weight -= length - pointIndex - 1
+ }
+ }
+
+ length = len(str)
+ istart = length - 1
+ for i = istart; i > 0; i-- {
+ if str[i] != '0' {
+ break
+ }
+ }
+ str = str[:i+1] + str[length:]
+ d.weight += istart - i
+
+ if isOdd(d.weight) {
+ str += "0"
+ d.weight -= 1
+ }
+ if isOdd(len(str)) {
+ str = "0" + str
+ }
+ d.digits = str
+ case []byte:
+ return decodeDecimal(de, prec, scale)
+ }
+ return d, nil
+}
+
+func (d DmDecimal) encodeDecimal() ([]byte, error) {
+ if d.isZero() {
+ return []byte{byte(FLAG_ZERO)}, nil
+ }
+ exp := (d.weight+len(d.digits))/2 - 1
+ if exp > EXP_MAX || exp < EXP_MIN {
+ return nil, ECGO_DATA_TOO_LONG.throw()
+ }
+ validLen := len(d.digits)/2 + 1
+
+ if d.sign < 0 && validLen >= XDEC_SIZE {
+ validLen = XDEC_SIZE - 1
+ } else if validLen > XDEC_SIZE {
+ validLen = XDEC_SIZE
+ }
+ retLen := validLen
+ if d.sign < 0 {
+ retLen = validLen + 1
+ }
+ retBytes := make([]byte, retLen)
+ if d.sign > 0 {
+ retBytes[0] = byte(exp + FLAG_POSITIVE)
+ } else {
+ retBytes[0] = byte(FLAG_NEGTIVE - exp)
+ }
+
+ ibytes := 1
+ for ichar := 0; ibytes < validLen; {
+ digit1, err := strconv.Atoi(string(d.digits[ichar]))
+ if err != nil {
+ return nil, err
+ }
+ ichar++
+ digit2, err := strconv.Atoi(string(d.digits[ichar]))
+ ichar++
+ if err != nil {
+ return nil, err
+ }
+
+ digit := digit1*10 + digit2
+ if d.sign > 0 {
+ retBytes[ibytes] = byte(digit + NUM_POSITIVE)
+ } else {
+ retBytes[ibytes] = byte(NUM_NEGTIVE - digit)
+ }
+ ibytes++
+ }
+ if d.sign < 0 && ibytes < retLen {
+ retBytes[ibytes] = 0x66
+ ibytes++
+ }
+ if ibytes < retLen {
+ retBytes[ibytes] = 0x00
+ }
+ return retBytes, nil
+}
+
+func decodeDecimal(values []byte, prec int, scale int) (*DmDecimal, error) {
+ var decimal = &DmDecimal{
+ prec: prec,
+ scale: scale,
+ sign: 0,
+ weight: 0,
+ Valid: true,
+ }
+ if values == nil || len(values) == 0 || len(values) > XDEC_SIZE {
+ return nil, ECGO_FATAL_ERROR.throw()
+ }
+ if values[0] == byte(FLAG_ZERO) || len(values) == 1 {
+ return decimal, nil
+ }
+ if values[0]&byte(FLAG_ZERO) != 0 {
+ decimal.sign = 1
+ } else {
+ decimal.sign = -1
+ }
+
+ var flag = int(Dm_build_1220.Dm_build_1340(values, 0))
+ var exp int
+ if decimal.sign > 0 {
+ exp = flag - FLAG_POSITIVE
+ } else {
+ exp = FLAG_NEGTIVE - flag
+ }
+ var digit = 0
+ var sf = ""
+ for ival := 1; ival < len(values); ival++ {
+ if decimal.sign > 0 {
+ digit = int(values[ival]) - NUM_POSITIVE
+ } else {
+ digit = NUM_NEGTIVE - int(values[ival])
+ }
+ if digit < 0 || digit > 99 {
+ break
+ }
+ if digit < 10 {
+ sf += "0"
+ }
+ sf += strconv.Itoa(digit)
+ }
+ decimal.digits = sf
+ decimal.weight = exp*2 - (len(decimal.digits) - 2)
+
+ return decimal, nil
+}
+
+func (d DmDecimal) isZero() bool {
+ return d.sign == 0
+}
+
+func checkPrec(len int, prec int) error {
+ if prec > 0 && len > prec || len > XDEC_MAX_PREC {
+ return ECGO_DATA_TOO_LONG.throw()
+ }
+ return nil
+}
+
+func isOdd(val int) bool {
+ return val%2 != 0
+}
+
+func (d *DmDecimal) checkValid() error {
+ if !d.Valid {
+ return ECGO_IS_NULL.throw()
+ }
+ return nil
+}
diff --git a/dmr/p.go b/dmr/p.go
new file mode 100644
index 0000000..3d83be1
--- /dev/null
+++ b/dmr/p.go
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "context"
+ "database/sql"
+ "database/sql/driver"
+ "sync"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/i18n"
+)
+
+// 发版标记
+var version = "8.1.2.94"
+var build_date = "2021.11.11"
+var svn = "8453"
+
+var globalDmDriver = newDmDriver()
+
+func init() {
+ sql.Register("dm", globalDmDriver)
+}
+
+func driverInit(svcConfPath string) {
+ load(svcConfPath)
+ if GlobalProperties != nil && GlobalProperties.Len() > 0 {
+ setDriverAttributes(GlobalProperties)
+ }
+ globalDmDriver.createFilterChain(nil, GlobalProperties)
+
+ switch Locale {
+ case 0:
+ i18n.InitConfig(i18n.Messages_zh_CN)
+ case 1:
+ i18n.InitConfig(i18n.Messages_en_US)
+ case 2:
+ i18n.InitConfig(i18n.Messages_zh_TW)
+ }
+}
+
+type DmDriver struct {
+ filterable
+ readPropMutex sync.Mutex
+}
+
+func newDmDriver() *DmDriver {
+ d := new(DmDriver)
+ d.idGenerator = dmDriverIDGenerator
+ return d
+}
+
+/*************************************************************
+ ** PUBLIC METHODS AND FUNCTIONS
+ *************************************************************/
+func (d *DmDriver) Open(dsn string) (driver.Conn, error) {
+ return d.open(dsn)
+}
+
+func (d *DmDriver) OpenConnector(dsn string) (driver.Connector, error) {
+ return d.openConnector(dsn)
+}
+
+func (d *DmDriver) open(dsn string) (*DmConnection, error) {
+ c, err := d.openConnector(dsn)
+ if err != nil {
+ return nil, err
+ }
+ return c.connect(context.Background())
+}
+
+func (d *DmDriver) openConnector(dsn string) (*DmConnector, error) {
+ connector := new(DmConnector).init()
+ connector.url = dsn
+ connector.dmDriver = d
+ d.readPropMutex.Lock()
+ err := connector.mergeConfigs(dsn)
+ d.readPropMutex.Unlock()
+ if err != nil {
+ return nil, err
+ }
+ connector.createFilterChain(connector, nil)
+ return connector, nil
+}
diff --git a/dmr/parser/zt.go b/dmr/parser/zt.go
new file mode 100644
index 0000000..04963dd
--- /dev/null
+++ b/dmr/parser/zt.go
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package parser
+
+import "strconv"
+
+const (
+ MAX_DEC_LEN = 38
+)
+
+const (
+ NORMAL int = iota
+ INT
+ DOUBLE
+ DECIMAL
+ STRING
+ HEX_INT
+ WHITESPACE_OR_COMMENT
+ NULL
+)
+
+type LVal struct {
+ Value string
+ Tp int
+ Position int
+}
+
+func newLValNoParams() *LVal {
+ return new(LVal).reset()
+}
+
+func newLVal(value string, tp int) *LVal {
+ return &LVal{Value: value, Tp: tp}
+}
+
+func (l *LVal) reset() *LVal {
+ l.Value = ""
+ l.Tp = NORMAL
+ return l
+}
+
+func (l *LVal) String() string {
+ return strconv.Itoa(l.Tp) + ":" + l.Value
+}
diff --git a/dmr/parser/zu.go b/dmr/parser/zu.go
new file mode 100644
index 0000000..f516536
--- /dev/null
+++ b/dmr/parser/zu.go
@@ -0,0 +1,1206 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package parser
+
+import (
+ "io"
+ "strconv"
+ "unicode/utf8"
+)
+
+const (
+ YYEOF = -1 /** This character denotes the end of file */
+ ZZ_BUFFERSIZE = 16384 /** initial size of the lookahead buffer */
+ /** lexical states */
+ YYINITIAL = 0
+ xc = 2
+ xq = 4
+ xdq = 6
+ xsb = 8
+ xbin = 10
+ xhex = 12
+ xhint = 14
+ xq2 = 16
+ xq2_2 = 18
+)
+
+/**
+* ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l
+* ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l
+* at the beginning of a line
+* l is of the form l = 2*k, k a non negative integer
+ */
+var ZZ_LEXSTATE []int = []int{0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 4, 4, 7, 7, 8, 8}
+
+/**
+* Translates characters to character classes
+ */
+var ZZ_CMAP_PACKED []rune = []rune{0011, 0000, 0001, 0026, 0001, 0025, 0001, 0030, 0001, 0026, 0001, 0025, 0022, 0000, 0001, 0026, 0001, 0017, 0001, 0002,
+ 0002, 0012, 0002, 0017, 0001, 0001, 0002, 0017, 0001, 0004, 0001, 0023, 0001, 0017, 0001, 0027, 0001, 0016, 0001, 0003,
+ 0001, 0020, 0011, 0013, 0001, 0014, 0001, 0017, 0001, 0017, 0001, 0015, 0003, 0017, 0001, 0021, 0001, 0010, 0001, 0021,
+ 0001, 0024, 0001, 0022, 0001, 0024, 0002, 0012, 0001, 0034, 0002, 0012, 0001, 0033, 0001, 0012, 0001, 0031, 0001, 0036,
+ 0001, 0012, 0001, 0007, 0001, 0012, 0001, 0035, 0001, 0037, 0001, 0032, 0002, 0012, 0001, 0011, 0002, 0012, 0001, 0005,
+ 0001, 0000, 0001, 0006, 0001, 0017, 0001, 0012, 0001, 0000, 0001, 0021, 0001, 0010, 0001, 0021, 0001, 0024, 0001, 0022,
+ 0001, 0024, 0002, 0012, 0001, 0034, 0002, 0012, 0001, 0033, 0001, 0012, 0001, 0031, 0001, 0036, 0001, 0012, 0001, 0007,
+ 0001, 0012, 0001, 0035, 0001, 0037, 0001, 0032, 0002, 0012, 0001, 0011, 0002, 0012, 0001, 0017, 0001, 0017, 0002, 0017,
+ 0001, 0000, 0005, 0012, 0001, 0012, 0172, 0012, 0x1f28, 0000, 0001, 0030, 0001, 0030, 0xffff, 0000, 0xffff, 0000, 0xffff, 0000, 0xffff, 0000, 0xffff, 0000, 0xffff, 0000, 0xffff, 0000, 0xffff, 0000, 0xffff, 0000, 0xffff, 0000, 0xffff, 0000, 0xffff, 0000, 0xffff, 0000, 0xffff, 0000, 0xffff, 0000, 0xffff, 0000, 0xdfe6, 0000}
+
+/**
+* Translates characters to character classes
+ */
+var ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED)
+
+/**
+* Translates DFA states to action switch labels.
+ */
+var ZZ_ACTION = zzUnpackActionNoParams()
+
+var ZZ_ACTION_PACKED_0 []rune = []rune{0011, 0000, 0001, 0001, 0001, 0002, 0001, 0003, 0002, 0004, 0004, 0005, 0001, 0006, 0002, 0004,
+ 0001, 0006, 0001, 0007, 0001, 0004, 0002, 0005, 0001, 0010, 0002, 0011, 0001, 0012, 0001, 0013,
+ 0001, 0014, 0001, 0015, 0001, 0016, 0001, 0017, 0001, 0020, 0001, 0021, 0001, 0022, 0001, 0023,
+ 0001, 0024, 0001, 0025, 0001, 0026, 0001, 0007, 0001, 0027, 0001, 0000, 0001, 0030, 0001, 0031,
+ 0001, 0032, 0001, 0000, 0001, 0033, 0001, 0034, 0001, 0035, 0001, 0032, 0001, 0036, 0001, 0000,
+ 0003, 0005, 0001, 0037, 0001, 0040, 0001, 0000, 0001, 0041, 0002, 0000, 0001, 0042, 0004, 0000,
+ 0001, 0043, 0001, 0044, 0001, 0033, 0001, 0000, 0001, 0045, 0002, 0005, 0003, 0000, 0001, 0046,
+ 0001, 0047, 0001, 0050, 0001, 0051, 0020, 0000, 0001, 0052, 0001, 0000, 0001, 0053, 0001, 0052,
+ 0001, 0053}
+
+func zzUnpackActionNoParams() []int {
+ result := make([]int, 104)
+ offset := 0
+ offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result)
+ return result
+}
+
+func zzUnpackAction(packed []rune, offset int, result []int) int {
+ i := 0 /* index in packed string */
+ j := offset /* index in unpacked array */
+ l := len(packed) //130
+ for i < l {
+ count := packed[i]
+ i++
+ value := packed[i]
+ i++
+ result[j] = int(value)
+ j++
+ count--
+ for count > 0 {
+ result[j] = int(value)
+ j++
+ count--
+ }
+ }
+ return j
+}
+
+/**
+* Translates a state to a row index in the transition table
+ */
+var ZZ_ROWMAP = zzUnpackRowMapNoParams()
+
+var ZZ_ROWMAP_PACKED_0 []rune = []rune{0000, 0000, 0000, 0040, 0000, 0100, 0000, 0140, 0000, 0200, 0000, 0240, 0000, 0300, 0000, 0340,
+ 0000, 0x0100, 0000, 0200, 0000, 0200, 0000, 0200, 0000, 0x0120, 0000, 0200, 0000, 0x0140, 0000, 0x0160,
+ 0000, 0x0180, 0000, 0x01a0, 0000, 0x01c0, 0000, 0x01e0, 0000, 0x0200, 0000, 0x0220, 0000, 0200, 0000, 0x0240,
+ 0000, 0x0260, 0000, 0x0280, 0000, 0x02a0, 0000, 0x02c0, 0000, 0x02e0, 0000, 0x0300, 0000, 0x0320, 0000, 0x0340,
+ 0000, 0x0360, 0000, 0x0380, 0000, 0x03a0, 0000, 0x03c0, 0000, 0x03e0, 0000, 0x0400, 0000, 0200, 0000, 0200,
+ 0000, 0200, 0000, 0200, 0000, 0x0420, 0000, 0200, 0000, 0x0440, 0000, 0200, 0000, 0200, 0000, 0x0460,
+ 0000, 0x0480, 0000, 0200, 0000, 0200, 0000, 0200, 0000, 0x04a0, 0000, 0200, 0000, 0x04c0, 0000, 0x04e0,
+ 0000, 0x0500, 0000, 0x0520, 0000, 0200, 0000, 0200, 0000, 0x02e0, 0000, 0200, 0000, 0x0540, 0000, 0x0560,
+ 0000, 0200, 0000, 0x0580, 0000, 0x03a0, 0000, 0x05a0, 0000, 0x03e0, 0000, 0200, 0000, 0200, 0000, 0x05c0,
+ 0000, 0x05c0, 0000, 0x04c0, 0000, 0x05e0, 0000, 0x0600, 0000, 0x0620, 0000, 0x0640, 0000, 0x0660, 0000, 0200,
+ 0000, 0200, 0000, 0200, 0000, 0x01a0, 0000, 0x0680, 0000, 0x06a0, 0000, 0x06c0, 0000, 0x06e0, 0000, 0x0700,
+ 0000, 0x0720, 0000, 0x0740, 0000, 0x0760, 0000, 0x0780, 0000, 0x07a0, 0000, 0x07c0, 0000, 0x07e0, 0000, 0x0800,
+ 0000, 0x0820, 0000, 0x0840, 0000, 0x0860, 0000, 0200, 0000, 0x0880, 0000, 0200, 0000, 0x06e0, 0000, 0x0720}
+
+func zzUnpackRowMapNoParams() []int {
+ result := make([]int, 104)
+ offset := 0
+ offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result)
+ return result
+}
+
+func zzUnpackRowMap(packed []rune, offset int, result []int) int {
+ i := 0 /* index in packed string */
+ j := offset /* index in unpacked array */
+ l := len(packed) //208
+ for i < l {
+ high := packed[i] << 16
+ i++
+ result[j] = int(high | packed[i])
+ i++
+ j++
+ }
+ return j
+}
+
+/**
+* The transition table of the DFA
+ */
+var ZZ_TRANS []int = zzUnpackTransNoParams()
+
+var ZZ_TRANS_PACKED_0 []rune = []rune{0001, 0012, 0001, 0013, 0001, 0014, 0001, 0015, 0003, 0016, 0001, 0017, 0001, 0020, 0001, 0021,
+ 0001, 0022, 0001, 0023, 0001, 0024, 0001, 0016, 0001, 0025, 0001, 0016, 0001, 0026, 0002, 0022,
+ 0001, 0016, 0001, 0022, 0002, 0027, 0001, 0030, 0001, 0000, 0001, 0031, 0002, 0022, 0001, 0032,
+ 0003, 0022, 0003, 0033, 0001, 0034, 0001, 0035, 0033, 0033, 0001, 0036, 0001, 0037, 0036, 0036,
+ 0002, 0040, 0001, 0041, 0035, 0040, 0040, 0000, 0001, 0042, 0001, 0043, 0036, 0042, 0001, 0044,
+ 0001, 0045, 0036, 0044, 0006, 0046, 0001, 0047, 0031, 0046, 0001, 0050, 0001, 0051, 0004, 0050,
+ 0001, 0052, 0031, 0050, 0003, 0000, 0001, 0053, 0001, 0054, 0034, 0000, 0001, 0055, 0005, 0000,
+ 0005, 0022, 0004, 0000, 0003, 0022, 0001, 0000, 0001, 0022, 0004, 0000, 0007, 0022, 0001, 0000,
+ 0001, 0056, 0005, 0000, 0005, 0022, 0004, 0000, 0003, 0022, 0001, 0000, 0001, 0022, 0004, 0000,
+ 0007, 0022, 0001, 0000, 0001, 0057, 0005, 0000, 0005, 0022, 0004, 0000, 0003, 0022, 0001, 0000,
+ 0001, 0022, 0004, 0000, 0007, 0022, 0007, 0000, 0005, 0022, 0004, 0000, 0003, 0022, 0001, 0000,
+ 0001, 0022, 0004, 0000, 0007, 0022, 0013, 0000, 0001, 0023, 0002, 0000, 0001, 0060, 0001, 0000,
+ 0001, 0023, 0001, 0000, 0001, 0061, 0001, 0000, 0001, 0062, 0030, 0000, 0001, 0063, 0026, 0000,
+ 0001, 0064, 0006, 0000, 0001, 0065, 0002, 0000, 0001, 0066, 0001, 0000, 0001, 0065, 0030, 0000,
+ 0001, 0067, 0001, 0000, 0001, 0023, 0002, 0000, 0001, 0060, 0001, 0000, 0001, 0023, 0001, 0000,
+ 0001, 0061, 0001, 0000, 0001, 0062, 0042, 0000, 0001, 0053, 0017, 0000, 0005, 0022, 0004, 0000,
+ 0003, 0022, 0001, 0000, 0001, 0022, 0004, 0000, 0001, 0022, 0001, 0070, 0003, 0022, 0001, 0071,
+ 0001, 0022, 0007, 0000, 0005, 0022, 0004, 0000, 0003, 0022, 0001, 0000, 0001, 0022, 0004, 0000,
+ 0004, 0022, 0001, 0072, 0002, 0022, 0003, 0033, 0002, 0000, 0033, 0033, 0004, 0000, 0001, 0073,
+ 0036, 0000, 0001, 0074, 0001, 0075, 0033, 0000, 0001, 0036, 0001, 0000, 0036, 0036, 0001, 0000,
+ 0001, 0076, 0023, 0000, 0001, 0077, 0001, 0100, 0011, 0000, 0002, 0040, 0001, 0000, 0035, 0040,
+ 0002, 0000, 0001, 0101, 0035, 0000, 0001, 0042, 0001, 0000, 0036, 0042, 0025, 0000, 0001, 0102,
+ 0001, 0103, 0011, 0000, 0001, 0044, 0001, 0000, 0036, 0044, 0025, 0000, 0001, 0104, 0001, 0105,
+ 0011, 0000, 0006, 0046, 0001, 0000, 0031, 0046, 0025, 0053, 0001, 0000, 0012, 0053, 0005, 0000,
+ 0001, 0106, 0045, 0000, 0001, 0065, 0002, 0000, 0001, 0107, 0001, 0000, 0001, 0065, 0001, 0000,
+ 0001, 0061, 0001, 0000, 0001, 0062, 0026, 0000, 0001, 0110, 0004, 0000, 0001, 0110, 0002, 0000,
+ 0001, 0111, 0003, 0000, 0001, 0111, 0023, 0000, 0001, 0065, 0004, 0000, 0001, 0065, 0001, 0000,
+ 0001, 0061, 0001, 0000, 0001, 0062, 0023, 0000, 0001, 0112, 0002, 0000, 0001, 0112, 0004, 0000,
+ 0003, 0112, 0001, 0000, 0001, 0112, 0022, 0000, 0005, 0022, 0004, 0000, 0003, 0022, 0001, 0000,
+ 0001, 0022, 0004, 0000, 0002, 0022, 0001, 0113, 0004, 0022, 0007, 0000, 0005, 0022, 0004, 0000,
+ 0003, 0022, 0001, 0000, 0001, 0022, 0004, 0000, 0006, 0022, 0001, 0114, 0003, 0000, 0001, 0115,
+ 0003, 0000, 0005, 0022, 0004, 0000, 0003, 0022, 0001, 0000, 0001, 0022, 0002, 0116, 0001, 0117,
+ 0001, 0000, 0007, 0022, 0001, 0000, 0001, 0120, 0023, 0000, 0002, 0077, 0036, 0000, 0001, 0077,
+ 0001, 0100, 0012, 0000, 0001, 0121, 0023, 0000, 0002, 0102, 0012, 0000, 0001, 0122, 0023, 0000,
+ 0002, 0104, 0024, 0000, 0001, 0110, 0004, 0000, 0001, 0110, 0026, 0000, 0005, 0022, 0004, 0000,
+ 0003, 0022, 0001, 0000, 0001, 0022, 0004, 0000, 0002, 0022, 0001, 0123, 0004, 0022, 0003, 0000,
+ 0001, 0124, 0003, 0000, 0005, 0022, 0004, 0000, 0003, 0022, 0001, 0000, 0001, 0022, 0002, 0125,
+ 0001, 0126, 0001, 0000, 0007, 0022, 0003, 0000, 0001, 0127, 0037, 0000, 0001, 0115, 0021, 0000,
+ 0002, 0116, 0001, 0117, 0001, 0000, 0001, 0130, 0035, 0000, 0001, 0127, 0013, 0000, 0001, 0131,
+ 0037, 0000, 0001, 0124, 0021, 0000, 0002, 0125, 0001, 0126, 0001, 0000, 0001, 0132, 0035, 0000,
+ 0001, 0131, 0010, 0000, 0025, 0127, 0001, 0116, 0003, 0127, 0001, 0133, 0006, 0127, 0032, 0000,
+ 0001, 0134, 0005, 0000, 0025, 0131, 0001, 0125, 0003, 0131, 0001, 0135, 0006, 0131, 0032, 0000,
+ 0001, 0136, 0005, 0000, 0025, 0127, 0001, 0116, 0003, 0127, 0001, 0133, 0001, 0137, 0005, 0127,
+ 0033, 0000, 0001, 0140, 0004, 0000, 0025, 0131, 0001, 0125, 0003, 0131, 0001, 0135, 0001, 0141,
+ 0005, 0131, 0033, 0000, 0001, 0142, 0004, 0000, 0025, 0127, 0001, 0116, 0003, 0127, 0001, 0133,
+ 0001, 0127, 0001, 0143, 0004, 0127, 0033, 0000, 0001, 0144, 0004, 0000, 0025, 0131, 0001, 0125,
+ 0003, 0131, 0001, 0135, 0001, 0131, 0001, 0145, 0004, 0131, 0033, 0000, 0001, 0146, 0004, 0000,
+ 0025, 0127, 0001, 0116, 0003, 0127, 0001, 0133, 0001, 0127, 0001, 0147, 0004, 0127, 0025, 0131,
+ 0001, 0125, 0003, 0131, 0001, 0135, 0001, 0131, 0001, 0150, 0004, 0131}
+
+func zzUnpackTransNoParams() []int {
+ result := make([]int, 2208)
+ offset := 0
+ offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result)
+ return result
+}
+
+func zzUnpackTrans(packed []rune, offset int, result []int) int {
+ i := 0 /* index in packed string */
+ j := offset /* index in unpacked array */
+ l := len(packed) //780
+ for i < l {
+ count := packed[i]
+ i++
+ value := packed[i]
+ i++
+ value--
+ result[j] = int(value)
+ j++
+ count--
+ for count > 0 {
+ result[j] = int(value)
+ j++
+ count--
+ }
+ }
+ return j
+}
+
+/* error codes */
+const (
+ ZZ_UNKNOWN_ERROR = 0
+ ZZ_NO_MATCH = 1
+ ZZ_PUSHBACK_2BIG = 2
+)
+
+/* error messages for the codes above */
+var ZZ_ERROR_MSG []string = []string{
+ "Unknown internal scanner error",
+ "Error: could not match input",
+ "Error: pushback Value was too large"}
+
+/**
+* ZZ_ATTRIBUTE[aState] contains the attributes of state aState
+ */
+var ZZ_ATTRIBUTE []int = zzUnpackAttributeNoParams()
+
+var ZZ_ATTRIBUTE_PACKED_0 []rune = []rune{0004, 0000, 0001, 0010, 0004, 0000, 0003, 0011, 0001, 0001, 0001, 0011, 0010, 0001, 0001, 0011,
+ 0017, 0001, 0004, 0011, 0001, 0001, 0001, 0011, 0001, 0000, 0002, 0011, 0001, 0001, 0001, 0000,
+ 0003, 0011, 0001, 0001, 0001, 0011, 0001, 0000, 0003, 0001, 0002, 0011, 0001, 0000, 0001, 0011,
+ 0002, 0000, 0001, 0011, 0004, 0000, 0002, 0011, 0001, 0001, 0001, 0000, 0003, 0001, 0003, 0000,
+ 0003, 0011, 0001, 0001, 0020, 0000, 0001, 0011, 0001, 0000, 0001, 0011, 0002, 0001}
+
+func zzUnpackAttributeNoParams() []int {
+ result := make([]int, 104)
+ offset := 0
+ offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result)
+ return result
+}
+
+func zzUnpackAttribute(packed []rune, offset int, result []int) int {
+ i := 0 /* index in packed string */
+ j := offset /* index in unpacked array */
+ l := len(packed) //78
+ for i < l {
+ count := packed[i]
+ i++
+ value := packed[i]
+ i++
+ result[j] = int(value)
+ j++
+ count--
+
+ for count > 0 {
+ result[j] = int(value)
+ j++
+ count--
+ }
+ }
+ return j
+}
+
+type Lexer struct {
+ /** the input device */
+ zzReader io.RuneReader
+
+ /** the current state of the DFA */
+ zzState int
+
+ /** the current lexical state */
+ zzLexicalState int
+
+ /** this buffer contains the current text to be matched and is
+ the source of the yytext() string */
+ zzBuffer []rune
+
+ //zzBytesBuffer []byte
+
+ /** the textposition at the last accepting state */
+ zzMarkedPos int
+
+ /** the current text Position in the buffer */
+ zzCurrentPos int
+
+ /** startRead marks the beginning of the yytext() string in the buffer */
+ zzStartRead int
+
+ /** endRead marks the last character in the buffer, that has been read
+ from input */
+ zzEndRead int
+
+ /** number of newlines encountered up to the start of the matched text */
+ yyline int
+
+ /** the number of characters up to the start of the matched text */
+ yychar int
+
+ /**
+ * the number of characters from the last newline up to the start of the
+ * matched text
+ */
+ yycolumn int
+
+ /**
+ * zzAtBOL == true <=> the scanner is currently at the beginning of a line
+ */
+ zzAtBOL bool
+
+ /** zzAtEOF == true <=> the scanner is at the EOF */
+ zzAtEOF bool
+
+ /** denotes if the user-EOF-code has already been executed */
+ zzEOFDone bool
+
+ /**
+ * The number of occupied positions in zzBuffer beyond zzEndRead.
+ * When a lead/high surrogate has been read from the input stream
+ * into the final zzBuffer Position, this will have a Value of 1;
+ * otherwise, it will have a Value of 0.
+ */
+ zzFinalHighSurrogate int
+
+ /* user code: */
+ ltstr string
+ debugFlag bool
+}
+
+func (lexer *Lexer) init() {
+ lexer.zzLexicalState = YYINITIAL
+ lexer.zzBuffer = make([]rune, ZZ_BUFFERSIZE)
+ lexer.zzAtBOL = true
+}
+
+func (lexer *Lexer) Reset(in io.RuneReader) *Lexer {
+ lexer.zzLexicalState = YYINITIAL
+ lexer.zzAtBOL = true
+ lexer.zzReader = in
+ lexer.zzState = 0
+ lexer.zzMarkedPos = 0
+ lexer.zzCurrentPos = 0
+ lexer.zzStartRead = 0
+ lexer.zzEndRead = 0
+ lexer.yyline = 0
+ lexer.yychar = 0
+ lexer.yycolumn = 0
+ lexer.zzAtEOF = false
+ lexer.zzEOFDone = false
+ lexer.zzFinalHighSurrogate = 0
+ lexer.ltstr = ""
+ return lexer
+}
+
+func (lexer *Lexer) debug(info string) {
+ if !lexer.debugFlag {
+ return
+ }
+
+}
+
+func (lexer *Lexer) yyerror(msg string) {
+ locInfo := "(line: " + strconv.Itoa(lexer.yyline) + ", column: " + strconv.Itoa(lexer.yycolumn) + ", char: " + strconv.Itoa(lexer.yychar) + ")"
+ if msg == "" {
+ panic("syntex error" + locInfo)
+ } else {
+ panic("syntex error" + locInfo + ": " + msg)
+ }
+}
+
+/**
+* Creates a new scanner
+*
+* @param in the java.io.Reader to read input from.
+ */
+func NewLexer(in io.RuneReader, debug bool) *Lexer {
+ l := new(Lexer)
+ l.init()
+ l.debugFlag = debug
+ l.zzReader = in
+ return l
+}
+
+/**
+* Unpacks the compressed character translation table.
+*
+* @param packed the packed character translation table
+* @return the unpacked character translation table
+ */
+func zzUnpackCMap(packed []rune) []rune {
+ m := make([]rune, 0x110000)
+ i := 0 /* index in packed string */
+ j := 0 /* index in unpacked array */
+ for i < 208 {
+ count := packed[i]
+ i++
+ value := packed[i]
+ i++
+ m[j] = value
+ j++
+ count--
+ for count > 0 {
+ m[j] = value
+ j++
+ count--
+ }
+ }
+ return m
+}
+
+/**
+* Refills the input buffer.
+*
+* @return false
, iff there was new input.
+*
+* @exception java.io.IOException if any I/O-Error occurs
+ */
+func (lexer *Lexer) zzRefill() (bool, error) {
+
+ /* first: make room (if you can) */
+ if lexer.zzStartRead > 0 {
+ lexer.zzEndRead += lexer.zzFinalHighSurrogate
+ lexer.zzFinalHighSurrogate = 0
+ l := lexer.zzEndRead - lexer.zzStartRead
+ if l > 0 {
+ copy(lexer.zzBuffer[:l], lexer.zzBuffer[lexer.zzStartRead:lexer.zzEndRead])
+ }
+
+ /* translate stored positions */
+ lexer.zzEndRead -= lexer.zzStartRead
+ lexer.zzCurrentPos -= lexer.zzStartRead
+ lexer.zzMarkedPos -= lexer.zzStartRead
+ lexer.zzStartRead = 0
+ }
+
+ /* is the buffer big enough? */
+ if lexer.zzCurrentPos >= len(lexer.zzBuffer)-lexer.zzFinalHighSurrogate {
+ /* if not: blow it up */
+ newBuffer := make([]rune, len(lexer.zzBuffer)*2)
+
+ copy(newBuffer[:len(lexer.zzBuffer)], lexer.zzBuffer[:len(lexer.zzBuffer)])
+ lexer.zzBuffer = newBuffer
+ lexer.zzEndRead += lexer.zzFinalHighSurrogate
+ lexer.zzFinalHighSurrogate = 0
+ }
+
+ /* fill the buffer with new input */
+ requested := len(lexer.zzBuffer) - lexer.zzEndRead
+
+ var numRead = 0
+ for i := lexer.zzEndRead; i < lexer.zzEndRead + requested; i ++ {
+ r, _, err := lexer.zzReader.ReadRune()
+ if err == io.EOF {
+ if numRead == 0 {
+ numRead = -1
+ }
+ break
+ } else if err != nil {
+ return false, err
+ } else {
+ numRead++
+ lexer.zzBuffer[i] = r
+ }
+ }
+
+ /* not supposed to occur according to specification of java.io.Reader */
+ if numRead == 0 {
+ panic("Reader returned 0 characters. See JFlex examples for workaround.")
+ }
+
+ if numRead > 0 {
+
+ lexer.zzEndRead += numRead
+ /* If numRead == requested, we might have requested to few chars to
+ encode a full Unicode character. We assume that a Reader would
+ otherwise never return half characters. */
+ if numRead == requested {
+ if utf8.ValidRune(lexer.zzBuffer[lexer.zzEndRead-1]) {
+ lexer.zzEndRead--
+ lexer.zzFinalHighSurrogate = 1
+ }
+ }
+ /* potentially more input available */
+ return false, nil
+ }
+
+ /* numRead < 0 ==> end of stream */
+ return true, nil
+}
+
+/**
+* Closes the input stream.
+ */
+func (lexer *Lexer) yyclose() error {
+ lexer.zzAtEOF = true /* indicate end of file */
+ lexer.zzEndRead = lexer.zzStartRead /* invalidate buffer */
+
+ if lexer.zzReader != nil {
+ if c, ok := lexer.zzReader.(io.Closer); ok {
+ return c.Close()
+ }
+ }
+ return nil
+}
+
+/**
+* Resets the scanner to read from a new input stream.
+* Does not close the old reader.
+*
+* All internal variables are reset, the old input stream
+* cannot be reused (internal buffer is discarded and lost).
+* Lexical state is set to ZZ_INITIAL.
+*
+* Internal scan buffer is resized down to its initial length, if it has grown.
+*
+* @param reader the new input stream
+ */
+func (lexer *Lexer) yyreset(reader io.RuneReader) {
+ lexer.zzReader = reader
+ lexer.zzAtBOL = true
+ lexer.zzAtEOF = false
+ lexer.zzEOFDone = false
+ lexer.zzEndRead = 0
+ lexer.zzStartRead = 0
+ lexer.zzCurrentPos = 0
+ lexer.zzMarkedPos = 0
+ lexer.zzFinalHighSurrogate = 0
+ lexer.yyline = 0
+ lexer.yychar = 0
+ lexer.yycolumn = 0
+ lexer.zzLexicalState = YYINITIAL
+ if len(lexer.zzBuffer) > ZZ_BUFFERSIZE {
+ lexer.zzBuffer = make([]rune, ZZ_BUFFERSIZE)
+ }
+}
+
+/**
+* Returns the current lexical state.
+ */
+func (lexer *Lexer) yystate() int {
+ return lexer.zzLexicalState
+}
+
+/**
+* Enters a new lexical state
+*
+* @param newState the new lexical state
+ */
+func (lexer *Lexer) yybegin(newState int) {
+ lexer.zzLexicalState = newState
+}
+
+/**
+* Returns the text matched by the current regular expression.
+ */
+func (lexer *Lexer) yytext() string {
+ return string(lexer.zzBuffer[lexer.zzStartRead:lexer.zzMarkedPos])
+}
+
+/**
+* Returns the character at Position pos from the
+* matched text.
+*
+* It is equivalent to yytext().charAt(pos), but faster
+*
+* @param pos the Position of the character to fetch.
+* A Value from 0 to yylength()-1.
+*
+* @return the character at Position pos
+ */
+func (lexer *Lexer) yycharat(pos int) rune {
+ return lexer.zzBuffer[lexer.zzStartRead+pos]
+}
+
+/**
+* Returns the length of the matched text region.
+ */
+func (lexer *Lexer) yylength() int {
+ return lexer.zzMarkedPos - lexer.zzStartRead
+}
+
+/**
+* Reports an error that occured while scanning.
+*
+* In a wellformed scanner (no or only correct usage of
+* yypushback(int) and a match-all fallback rule) this method
+* will only be called with things that "Can't Possibly Happen".
+* If this method is called, something is seriously wrong
+* (e.g. a JFlex bug producing a faulty scanner etc.).
+*
+* Usual syntax/scanner level error handling should be done
+* in error fallback rules.
+*
+* @param errorCode the code of the errormessage to display
+ */
+func (lexer *Lexer) zzScanError(errorCode int) {
+ var message string
+
+ message = ZZ_ERROR_MSG[errorCode]
+ if message == "" {
+ message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]
+ }
+
+ panic(message)
+}
+
+/**
+* Pushes the specified amount of characters back into the input stream.
+*
+* They will be read again by then next call of the scanning method
+*
+* @param number the number of characters to be read again.
+* This number must not be greater than yylength()!
+ */
+func (lexer *Lexer) yypushback(number int) {
+ if number > lexer.yylength() {
+ lexer.zzScanError(ZZ_PUSHBACK_2BIG)
+ }
+
+ lexer.zzMarkedPos -= number
+}
+
+/**
+* Resumes scanning until the next regular expression is matched,
+* the end of input is encountered or an I/O-Error occurs.
+*
+* @return the next token
+* @exception java.io.IOException if any I/O-Error occurs
+ */
+func (lexer *Lexer) Yylex() (*LVal, error) {
+ var zzInput rune
+ var zzAction, zzCurrentPosL, zzMarkedPosL int
+ // cached fields:
+ zzEndReadL := lexer.zzEndRead
+ zzBufferL := lexer.zzBuffer
+ zzCMapL := ZZ_CMAP
+
+ zzTransL := ZZ_TRANS
+ zzRowMapL := ZZ_ROWMAP
+ zzAttrL := ZZ_ATTRIBUTE
+
+ for {
+ zzMarkedPosL = lexer.zzMarkedPos
+
+ lexer.yychar += zzMarkedPosL - lexer.zzStartRead
+
+ zzR := false
+ var zzCh rune
+ var zzCharCount int
+ zzCurrentPosL = lexer.zzStartRead
+ for zzCurrentPosL < zzMarkedPosL {
+ zzCh = zzBufferL[zzCurrentPosL]
+ zzCharCount = utf8.RuneLen(zzCh)
+ switch zzCh {
+ case '\u000B', '\u000C', '\u0085', '\u2028', '\u2029':
+ lexer.yyline++
+ lexer.yycolumn = 0
+ zzR = false
+ case '\r':
+ lexer.yyline++
+ lexer.yycolumn = 0
+ zzR = true
+ case '\n':
+ if zzR {
+ zzR = false
+ } else {
+ lexer.yyline++
+ lexer.yycolumn = 0
+ }
+ default:
+ zzR = false
+ lexer.yycolumn += zzCharCount
+ }
+ zzCurrentPosL += zzCharCount
+ }
+
+ if zzR {
+ // peek one character ahead if it is \n (if we have counted one line too much)
+ var zzPeek bool
+ if zzMarkedPosL < zzEndReadL {
+ zzPeek = zzBufferL[zzMarkedPosL] == '\n'
+ } else if lexer.zzAtEOF {
+ zzPeek = false
+ } else {
+ eof, err := lexer.zzRefill()
+ if err != nil {
+ return nil, err
+ }
+ zzEndReadL = lexer.zzEndRead
+ zzMarkedPosL = lexer.zzMarkedPos
+ zzBufferL = lexer.zzBuffer
+ if eof {
+ zzPeek = false
+ } else {
+ zzPeek = zzBufferL[zzMarkedPosL] == '\n'
+ }
+
+ }
+ if zzPeek {
+ lexer.yyline--
+ }
+ }
+ zzAction = -1
+
+ zzCurrentPosL = zzMarkedPosL
+ lexer.zzCurrentPos = zzMarkedPosL
+ lexer.zzStartRead = zzMarkedPosL
+ lexer.zzState = ZZ_LEXSTATE[lexer.zzLexicalState]
+
+ // set up zzAction for empty match case:
+ zzAttributes := zzAttrL[lexer.zzState]
+ if (zzAttributes & 1) == 1 {
+ zzAction = lexer.zzState
+ }
+
+ {
+ for true {
+
+ if zzCurrentPosL < zzEndReadL {
+ zzInput = zzBufferL[zzCurrentPosL]
+ zzCurrentPosL += 1//utf8.RuneLen(zzInput)
+ } else if lexer.zzAtEOF {
+ zzInput = YYEOF
+ goto zzForAction
+ } else {
+ // store back cached positions
+ lexer.zzCurrentPos = zzCurrentPosL
+ lexer.zzMarkedPos = zzMarkedPosL
+ eof, err := lexer.zzRefill()
+ if err != nil {
+ return nil, err
+ }
+ // get translated positions and possibly new buffer
+ zzCurrentPosL = lexer.zzCurrentPos
+ zzMarkedPosL = lexer.zzMarkedPos
+ zzBufferL = lexer.zzBuffer
+ zzEndReadL = lexer.zzEndRead
+ if eof {
+ zzInput = YYEOF
+ goto zzForAction
+ } else {
+ zzInput = zzBufferL[zzCurrentPosL]
+ zzCurrentPosL += 1//utf8.RuneLen(zzInput)
+ }
+ }
+
+ zzNext := zzTransL[zzRowMapL[lexer.zzState]+int(zzCMapL[zzInput])]
+ if zzNext == -1 {
+ goto zzForAction
+ }
+
+ lexer.zzState = zzNext
+
+ zzAttributes = zzAttrL[lexer.zzState]
+ if (zzAttributes & 1) == 1 {
+ zzAction = lexer.zzState
+ zzMarkedPosL = zzCurrentPosL
+ if (zzAttributes & 8) == 8 {
+ goto zzForAction
+ }
+ }
+
+ }
+ }
+
+ zzForAction:
+ // store back cached Position
+ lexer.zzMarkedPos = zzMarkedPosL
+
+ if zzInput == YYEOF && lexer.zzStartRead == lexer.zzCurrentPos {
+ lexer.zzAtEOF = true
+ switch lexer.zzLexicalState {
+ case xc:
+ {
+ lexer.debug("<>")
+
+ lexer.yybegin(YYINITIAL)
+ lexer.yyerror("unterminated /* comment")
+ }
+ case 105:
+ case xq:
+ {
+ lexer.debug("<>")
+
+ lexer.yybegin(YYINITIAL)
+ lexer.yyerror("unterminated quoted string")
+ }
+ fallthrough
+ case 106:
+ case xdq:
+ {
+ lexer.debug("<>")
+
+ lexer.yybegin(YYINITIAL)
+ lexer.yyerror("unterminated quoted identifier")
+ }
+ fallthrough
+ case 107:
+ case xbin:
+ {
+ lexer.debug("<>")
+
+ lexer.yybegin(YYINITIAL)
+ lexer.yyerror("unterminated binary string literal")
+ }
+ fallthrough
+ case 108:
+ case xhex:
+ {
+ lexer.debug("<>")
+
+ lexer.yybegin(YYINITIAL)
+ lexer.yyerror("unterminated hexadecimal integer")
+ }
+ fallthrough
+ case 109:
+ case xq2:
+ {
+ lexer.yybegin(YYINITIAL)
+ lexer.yyerror("unterminated q2 string")
+ }
+ fallthrough
+ case 110:
+ case xq2_2:
+ {
+ lexer.yybegin(YYINITIAL)
+ lexer.yyerror("unterminated q2 string")
+ }
+ fallthrough
+ case 111:
+ default:
+ return nil, nil
+ }
+ } else {
+ var action int
+ if zzAction < 0 {
+ action = zzAction
+ } else {
+ action = ZZ_ACTION[zzAction]
+ }
+ switch action {
+ case 1:
+ {
+ lexer.debug("{other}")
+
+ return newLVal(lexer.yytext(), NORMAL), nil
+ }
+ fallthrough
+ case 44:
+ case 2:
+ {
+ lexer.debug("{xq_start}")
+
+ lexer.yybegin(xq)
+ lexer.ltstr = ""
+ }
+ fallthrough
+ case 45:
+ case 3:
+ {
+ lexer.debug("{xdq_start}")
+
+ lexer.yybegin(xdq)
+ lexer.ltstr = ""
+ lexer.ltstr += lexer.yytext()
+ }
+ fallthrough
+ case 46:
+ case 4:
+ {
+ lexer.debug("{self} | {op_chars}")
+
+ return newLVal(lexer.yytext(), NORMAL), nil
+ }
+ fallthrough
+ case 47:
+ case 5:
+ {
+ lexer.debug("{identifier}")
+
+ return newLVal(lexer.yytext(), NORMAL), nil
+ }
+ fallthrough
+ case 48:
+ case 6:
+ {
+ lexer.debug("{integer}")
+
+ return newLVal(lexer.yytext(), INT), nil
+ }
+ fallthrough
+ case 49:
+ case 7:
+ {
+ lexer.debug("{whitespace} | {comment} | {c_line_comment}")
+
+ return newLVal(lexer.yytext(), WHITESPACE_OR_COMMENT), nil
+ }
+ fallthrough
+ case 50:
+ case 8:
+ {
+ lexer.debug("{xc_inside}")
+
+ lexer.ltstr += lexer.yytext()
+ }
+ fallthrough
+ case 51:
+ case 9:
+ {
+ lexer.debug("[\\/] | [\\*]")
+
+ lexer.ltstr += lexer.yytext()
+ }
+ fallthrough
+ case 52:
+ case 10:
+ {
+ lexer.debug("{xq_inside}")
+
+ lexer.ltstr += lexer.yytext()
+ }
+ fallthrough
+ case 53:
+ case 11:
+ {
+ lexer.debug("{xq_stop}")
+
+ lexer.yybegin(YYINITIAL)
+ return newLVal(lexer.ltstr, STRING), nil
+ }
+ fallthrough
+ case 54:
+ case 12:
+ {
+ lexer.debug("{xdq_inside}")
+
+ lexer.ltstr += lexer.yytext()
+ }
+ fallthrough
+ case 55:
+ case 13:
+ {
+ lexer.debug("{xdq_stop}")
+
+ lexer.yybegin(YYINITIAL)
+ lexer.ltstr += lexer.yytext()
+ return newLVal(lexer.ltstr, NORMAL), nil
+ }
+ fallthrough
+ case 56:
+ case 14:
+ {
+ lexer.debug("{xbin_inside}")
+
+ lexer.ltstr += lexer.yytext()
+ }
+ fallthrough
+ case 57:
+ case 15:
+ {
+ lexer.debug("{xbin_stop}")
+
+ lexer.yybegin(YYINITIAL)
+ lexer.ltstr += lexer.yytext()
+ return newLVal(lexer.ltstr, NORMAL), nil
+ }
+ fallthrough
+ case 58:
+ case 16:
+ {
+ lexer.debug("{xhex_inside}")
+
+ lexer.ltstr += lexer.yytext()
+ }
+ fallthrough
+ case 59:
+ case 17:
+ {
+ lexer.debug("{xhex_stop}")
+
+ lexer.yybegin(YYINITIAL)
+ lexer.ltstr += lexer.yytext()
+ return newLVal(lexer.ltstr, NORMAL), nil
+ }
+ fallthrough
+ case 60:
+ case 18:
+ {
+ lexer.ltstr += lexer.yytext()
+ }
+ fallthrough
+ case 61:
+ case 19:
+ {
+ lexer.yybegin(xq2_2)
+ }
+ fallthrough
+ case 62:
+ case 20:
+ {
+ lexer.ltstr += "]"
+ lexer.ltstr += lexer.yytext()
+ lexer.yybegin(xq2)
+ }
+ fallthrough
+ case 63:
+ case 21:
+ {
+ lexer.yybegin(YYINITIAL)
+
+ return newLVal(lexer.ltstr, STRING), nil
+ }
+ fallthrough
+ case 64:
+ case 22:
+ {
+ lexer.ltstr += "]"
+ lexer.yybegin(xq2_2)
+ }
+ fallthrough
+ case 65:
+ case 23:
+ {
+ lexer.debug("{xc_start}")
+
+ lexer.yybegin(xc)
+ lexer.ltstr = lexer.yytext()
+ }
+ fallthrough
+ case 66:
+ case 24:
+ {
+ lexer.debug("{xbin_start}")
+
+ lexer.yybegin(xbin)
+ lexer.ltstr = ""
+ lexer.ltstr += lexer.yytext()
+ }
+ fallthrough
+ case 67:
+ case 25:
+ {
+ lexer.debug("{xhex_start}")
+
+ lexer.yybegin(xhex)
+ lexer.ltstr = ""
+ lexer.ltstr += lexer.yytext()
+ }
+ fallthrough
+ case 68:
+ case 26:
+ {
+ lexer.debug("{decimal}")
+
+ return newLVal(lexer.yytext(), DECIMAL), nil
+ }
+ fallthrough
+ case 69:
+ case 27:
+ {
+ lexer.debug("{real}")
+
+ return newLVal(lexer.yytext(), DOUBLE), nil
+ }
+ fallthrough
+ case 70:
+ case 28:
+ {
+ lexer.debug("{assign}")
+
+ return newLVal(lexer.yytext(), NORMAL), nil
+ }
+ fallthrough
+ case 71:
+ case 29:
+ {
+ lexer.debug("{selstar}")
+
+ return newLVal(lexer.yytext(), NORMAL), nil
+ }
+ fallthrough
+ case 72:
+ case 30:
+ {
+ lexer.debug("{boundary}")
+
+ return newLVal(lexer.yytext(), NORMAL), nil
+ }
+ fallthrough
+ case 73:
+ case 31:
+ {
+ lexer.debug("{xc_start}")
+
+ lexer.ltstr += lexer.yytext()
+ }
+ fallthrough
+ case 74:
+ case 32:
+ {
+ lexer.debug("{xc_stop}")
+
+ lexer.yybegin(YYINITIAL)
+ lexer.ltstr += lexer.yytext()
+ return newLVal(lexer.ltstr, WHITESPACE_OR_COMMENT), nil
+ }
+ fallthrough
+ case 75:
+ case 33:
+ {
+ lexer.debug("{xq_double}")
+
+ lexer.ltstr += "\\'"
+ }
+ fallthrough
+ case 76:
+ case 34:
+ { // keep original string
+ lexer.debug("{xdq_double}")
+
+ lexer.ltstr += lexer.yytext()
+ }
+ fallthrough
+ case 77:
+ case 35:
+ {
+ lexer.yybegin(xq2)
+ lexer.ltstr = ""
+ }
+ fallthrough
+ case 78:
+ case 36:
+ {
+ lexer.debug("{integer_with_boundary}")
+
+ return newLVal(lexer.yytext(), NORMAL), nil
+ }
+ fallthrough
+ case 79:
+ case 37:
+ {
+ lexer.debug("{hex_integer}")
+
+ return newLVal(lexer.yytext(), HEX_INT), nil
+ }
+ fallthrough
+ case 80:
+ case 38:
+ {
+ lexer.debug("{xq_cat}")
+ }
+ fallthrough
+ case 81:
+ case 39:
+ { /* ignore */
+ lexer.debug("{xbin_cat}")
+ }
+ fallthrough
+ case 82:
+ case 40:
+ {
+ lexer.debug("{xhex_cat}")
+ }
+ fallthrough
+ case 83:
+ case 41:
+ {
+ lexer.debug("{null}")
+
+ return newLVal("null", NULL), nil
+ }
+ fallthrough
+ case 84:
+ case 42:
+ {
+ lexer.debug("{is_null}")
+
+ return newLVal(lexer.yytext(), NORMAL), nil
+ }
+ fallthrough
+ case 85:
+ case 43:
+ {
+ lexer.debug("{not_null}")
+
+ return newLVal(lexer.yytext(), NORMAL), nil
+ }
+ fallthrough
+ case 86:
+ default:
+ lexer.zzScanError(ZZ_NO_MATCH)
+ }
+ }
+ }
+}
diff --git a/dmr/q.go b/dmr/q.go
new file mode 100644
index 0000000..b5628cd
--- /dev/null
+++ b/dmr/q.go
@@ -0,0 +1,1451 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "database/sql/driver"
+ "math"
+ "strconv"
+ "strings"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+const (
+ LOADPREC_DEFAULT = 2
+
+ LOADPREC_MAX = 9
+
+ SECDPREC_DEFAULT = 6
+
+ SECDPREC_MAX = 6
+
+ QUA_D byte = 3
+
+ QUA_DH byte = 4
+
+ QUA_DHM byte = 5
+
+ QUA_DHMS byte = 6
+
+ QUA_H byte = 7
+
+ QUA_HM byte = 8
+
+ QUA_HMS byte = 9
+
+ QUA_M byte = 10
+
+ QUA_MS byte = 11
+
+ QUA_S byte = 12
+)
+
+type DmIntervalDT struct {
+ _type byte
+
+ leadScale int
+
+ secScale int
+
+ negative bool
+
+ days int
+
+ hours int
+
+ minutes int
+
+ seconds int
+
+ fraction int
+
+ scaleForSvr int
+
+ Valid bool
+}
+
+func (dt *DmIntervalDT) init() {
+ dt._type = QUA_D
+ dt.leadScale = 2
+ dt.secScale = 6
+ dt.negative = false
+ dt.days = 0
+ dt.hours = 0
+ dt.minutes = 0
+ dt.seconds = 0
+ dt.fraction = 0
+ dt.scaleForSvr = 0
+ dt.Valid = true
+}
+
+func newDmIntervalDTByBytes(bytes []byte) *DmIntervalDT {
+ dt := new(DmIntervalDT)
+ dt.init()
+
+ dt._type = bytes[21]
+ dt.scaleForSvr = int(Dm_build_1220.Dm_build_1322(bytes, 20))
+ dt.leadScale = (dt.scaleForSvr >> 4) & 0x0000000F
+ dt.secScale = dt.scaleForSvr & 0x0000000F
+
+ switch dt._type {
+ case QUA_D:
+ dt.days = int(Dm_build_1220.Dm_build_1322(bytes, 0))
+ case QUA_DH:
+ dt.days = int(Dm_build_1220.Dm_build_1322(bytes, 0))
+ dt.hours = int(Dm_build_1220.Dm_build_1322(bytes, 4))
+ case QUA_DHM:
+ dt.days = int(Dm_build_1220.Dm_build_1322(bytes, 0))
+ dt.hours = int(Dm_build_1220.Dm_build_1322(bytes, 4))
+ dt.minutes = int(Dm_build_1220.Dm_build_1322(bytes, 8))
+ case QUA_DHMS:
+ dt.days = int(Dm_build_1220.Dm_build_1322(bytes, 0))
+ dt.hours = int(Dm_build_1220.Dm_build_1322(bytes, 4))
+ dt.minutes = int(Dm_build_1220.Dm_build_1322(bytes, 8))
+ dt.seconds = int(Dm_build_1220.Dm_build_1322(bytes, 12))
+ dt.fraction = int(Dm_build_1220.Dm_build_1322(bytes, 16))
+ case QUA_H:
+ dt.hours = int(Dm_build_1220.Dm_build_1322(bytes, 4))
+ case QUA_HM:
+ dt.hours = int(Dm_build_1220.Dm_build_1322(bytes, 4))
+ dt.minutes = int(Dm_build_1220.Dm_build_1322(bytes, 8))
+ case QUA_HMS:
+ dt.hours = int(Dm_build_1220.Dm_build_1322(bytes, 4))
+ dt.minutes = int(Dm_build_1220.Dm_build_1322(bytes, 8))
+ dt.seconds = int(Dm_build_1220.Dm_build_1322(bytes, 12))
+ dt.fraction = int(Dm_build_1220.Dm_build_1322(bytes, 16))
+ case QUA_M:
+ dt.minutes = int(Dm_build_1220.Dm_build_1322(bytes, 8))
+ case QUA_MS:
+ dt.minutes = int(Dm_build_1220.Dm_build_1322(bytes, 8))
+ dt.seconds = int(Dm_build_1220.Dm_build_1322(bytes, 12))
+ dt.fraction = int(Dm_build_1220.Dm_build_1322(bytes, 16))
+ case QUA_S:
+ dt.seconds = int(Dm_build_1220.Dm_build_1322(bytes, 12))
+ dt.fraction = int(Dm_build_1220.Dm_build_1322(bytes, 16))
+ }
+ if dt.days < 0 {
+ dt.days = -dt.days
+ dt.negative = true
+ }
+ if dt.hours < 0 {
+ dt.hours = -dt.hours
+ dt.negative = true
+ }
+ if dt.minutes < 0 {
+ dt.minutes = -dt.minutes
+ dt.negative = true
+ }
+ if dt.seconds < 0 {
+ dt.seconds = -dt.seconds
+ dt.negative = true
+ }
+ if dt.fraction < 0 {
+ dt.fraction = -dt.fraction
+ dt.negative = true
+ }
+
+ return dt
+}
+
+func NewDmIntervalDTByString(str string) (dt *DmIntervalDT, err error) {
+ defer func() {
+ if p := recover(); p != nil {
+ err = ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ }()
+ dt = new(DmIntervalDT)
+ dt.init()
+
+ if str == "" {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ leadStr := strings.TrimSpace(strings.ToUpper(str))
+
+ if !(strings.Index(leadStr, "INTERVAL ") == 0) {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ leadStr = strings.TrimSpace(leadStr[strings.Index(leadStr, " "):])
+
+ endIndex := 0
+ var valueStr string
+
+ if endIndex = strings.Index(leadStr[1:], "'"); leadStr[0] == '\'' && endIndex != -1 {
+ endIndex += 1
+ valueStr = strings.TrimSpace(leadStr[1:endIndex])
+ valueStr = dt.checkSign(valueStr)
+ leadStr = strings.TrimSpace(leadStr[endIndex+1:])
+ }
+
+ if valueStr == "" {
+ leadStr = dt.checkSign(leadStr)
+ if endIndex = strings.Index(leadStr[1:], "'"); leadStr[0] != '\'' || endIndex == -1 {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ endIndex += 1
+ valueStr = strings.TrimSpace(leadStr[1:endIndex])
+ leadStr = strings.TrimSpace(leadStr[endIndex+1:])
+ }
+
+ strLeadPrec := ""
+ strSecPrec := ""
+
+ leadPrecIndex := 0
+ secPrecIndex := 0
+ toIndex := 0
+
+ if leadPrecIndex = strings.Index(leadStr, "DAY"); leadPrecIndex != -1 {
+ toIndex = strings.Index(leadStr[leadPrecIndex:], "TO")
+
+ if toIndex == -1 {
+ strLeadPrec = strings.TrimSpace(leadStr[leadPrecIndex:])
+ if err := dt.setDay(valueStr); err != nil {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ } else {
+ toIndex += leadPrecIndex
+ strLeadPrec = strings.TrimSpace(leadStr[leadPrecIndex:toIndex])
+
+ if strings.Index(leadStr[toIndex:], "HOUR") != -1 {
+ if err := dt.setDayToHour(valueStr); err != nil {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ } else if strings.Index(leadStr[toIndex:], "MINUTE") != -1 {
+ if err := dt.setDayToMinute(valueStr); err != nil {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ } else if secPrecIndex = strings.Index(leadStr[toIndex:], "SECOND"); secPrecIndex != -1 {
+ secPrecIndex += toIndex
+ strSecPrec = leadStr[secPrecIndex:]
+ if err := dt.setDayToSecond(valueStr); err != nil {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ } else {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ }
+
+ if err := dt.setPrecForSvr(leadStr, strLeadPrec, strSecPrec); err != nil {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ return dt, nil
+ }
+
+ if leadPrecIndex = strings.Index(leadStr, "HOUR"); leadPrecIndex != -1 {
+ toIndex = strings.Index(leadStr[leadPrecIndex:], "TO")
+
+ if toIndex == -1 {
+ toIndex += leadPrecIndex
+ strLeadPrec = leadStr[leadPrecIndex:]
+ if err := dt.setHour(valueStr); err != nil {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ } else {
+ strLeadPrec = leadStr[leadPrecIndex:toIndex]
+
+ if strings.Index(leadStr[toIndex:], "MINUTE") != -1 {
+ if err := dt.setHourToMinute(valueStr); err != nil {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ } else if secPrecIndex = strings.Index(leadStr[toIndex:], "SECOND"); secPrecIndex != -1 {
+ secPrecIndex += toIndex
+ strSecPrec = leadStr[secPrecIndex:]
+ if err := dt.setHourToSecond(valueStr); err != nil {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ } else {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ }
+
+ if err := dt.setPrecForSvr(leadStr, strLeadPrec, strSecPrec); err != nil {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ return dt, nil
+ }
+
+ if leadPrecIndex = strings.Index(leadStr, "MINUTE"); leadPrecIndex != -1 {
+ toIndex = strings.Index(leadStr, "TO")
+
+ if toIndex == -1 {
+ toIndex += leadPrecIndex
+ strLeadPrec = leadStr[leadPrecIndex:]
+ if err := dt.setMinute(valueStr); err != nil {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ } else {
+ strLeadPrec = leadStr[leadPrecIndex:toIndex]
+
+ if secPrecIndex = strings.Index(leadStr[toIndex:], "SECOND"); secPrecIndex != -1 {
+ strSecPrec = leadStr[secPrecIndex:]
+ if err := dt.setMinuteToSecond(valueStr); err != nil {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ } else {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ }
+
+ if err := dt.setPrecForSvr(leadStr, strLeadPrec, strSecPrec); err != nil {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ return dt, nil
+ }
+
+ if leadPrecIndex = strings.Index(leadStr, "SECOND"); leadPrecIndex != -1 {
+ if err := dt.setSecond(valueStr); err != nil {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ leadStr = strings.TrimSpace(leadStr[leadPrecIndex:])
+
+ colonIndex := strings.Index(leadStr, ",")
+ if colonIndex != -1 {
+ strLeadPrec = strings.TrimSpace(leadStr[:colonIndex]) + ")"
+ strSecPrec = "(" + strings.TrimSpace(leadStr[:colonIndex+1])
+ }
+
+ if err := dt.setPrecForSvr(leadStr, strLeadPrec, strSecPrec); err != nil {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ return dt, nil
+ }
+
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+}
+
+func (dt *DmIntervalDT) GetDay() int {
+ return dt.days
+}
+
+func (dt *DmIntervalDT) GetHour() int {
+ return dt.hours
+}
+
+func (dt *DmIntervalDT) GetMinute() int {
+ return dt.minutes
+}
+
+func (dt *DmIntervalDT) GetSecond() int {
+ return dt.seconds
+}
+
+func (dt *DmIntervalDT) GetMsec() int {
+ return dt.fraction
+}
+
+func (dt *DmIntervalDT) GetDTType() byte {
+ return dt._type
+}
+
+func (dt *DmIntervalDT) String() string {
+ if !dt.Valid {
+ return ""
+ }
+ var l, destLen int
+ var dStr, hStr, mStr, sStr, nStr string
+ interval := "INTERVAL "
+
+ switch dt._type {
+ case QUA_D:
+ dStr := strconv.FormatInt(int64(float64(dt.days)), 10)
+ if dt.negative {
+ interval += "-"
+ }
+
+ if len(dStr) < dt.leadScale {
+ l = len(dStr)
+ destLen = dt.leadScale
+
+ for destLen > l {
+ dStr = "0" + dStr
+ destLen--
+ }
+ }
+
+ interval += "'" + dStr + "' DAY(" + strconv.FormatInt(int64(dt.leadScale), 10) + ")"
+ case QUA_DH:
+ dStr = strconv.FormatInt(int64(float64(dt.days)), 10)
+ hStr = strconv.FormatInt(int64(float64(dt.hours)), 10)
+
+ if dt.negative {
+ interval += "-"
+ }
+
+ if len(dStr) < dt.leadScale {
+ l = len(dStr)
+ destLen = dt.leadScale
+
+ for destLen > l {
+ dStr = "0" + dStr
+ destLen--
+ }
+ }
+
+ if len(hStr) < 2 {
+ hStr = "0" + hStr
+ }
+
+ interval += "'" + dStr + " " + hStr + "' DAY(" + strconv.FormatInt(int64(dt.leadScale), 10) + ") TO HOUR"
+ case QUA_DHM:
+ dStr = strconv.FormatInt(int64(float64(dt.days)), 10)
+ hStr = strconv.FormatInt(int64(float64(dt.hours)), 10)
+ mStr = strconv.FormatInt(int64(float64(dt.minutes)), 10)
+
+ if dt.negative {
+ interval += "-"
+ }
+
+ if len(dStr) < dt.leadScale {
+ l = len(dStr)
+ destLen = dt.leadScale
+
+ for destLen > l {
+ dStr = "0" + dStr
+ destLen--
+ }
+ }
+ if len(hStr) < 2 {
+ hStr = "0" + hStr
+ }
+ if len(mStr) < 2 {
+ mStr = "0" + mStr
+ }
+ interval += "'" + dStr + " " + hStr + ":" + mStr + "' DAY(" + strconv.FormatInt(int64(dt.leadScale), 10) + ") TO MINUTE"
+ case QUA_DHMS:
+ dStr = strconv.FormatInt(int64(float64(dt.days)), 10)
+ hStr = strconv.FormatInt(int64(float64(dt.hours)), 10)
+ mStr = strconv.FormatInt(int64(float64(dt.minutes)), 10)
+ sStr = strconv.FormatInt(int64(float64(dt.seconds)), 10)
+ nStr = dt.getMsecString()
+ if dt.negative {
+ interval += "-"
+ }
+
+ if len(dStr) < dt.leadScale {
+ l = len(dStr)
+ destLen = dt.leadScale
+
+ for destLen > l {
+ dStr = "0" + dStr
+ destLen--
+ }
+ }
+ if len(hStr) < 2 {
+ hStr = "0" + hStr
+ }
+ if len(mStr) < 2 {
+ mStr = "0" + mStr
+ }
+ if len(sStr) < 2 {
+ sStr = "0" + sStr
+ }
+ interval += "'" + dStr + " " + hStr + ":" + mStr + ":" + sStr
+ if nStr != "" {
+ interval += "." + nStr
+ }
+
+ interval += "' DAY(" + strconv.FormatInt(int64(dt.leadScale), 10) + ") TO SECOND(" + strconv.FormatInt(int64(dt.secScale), 10) + ")"
+ case QUA_H:
+ hStr = strconv.FormatInt(int64(float64(dt.hours)), 10)
+ if dt.negative {
+ interval += "-"
+ }
+
+ if len(hStr) < dt.leadScale {
+ l = len(hStr)
+ destLen = dt.leadScale
+
+ for destLen > l {
+ hStr = "0" + hStr
+ destLen--
+ }
+ }
+
+ interval += "'" + hStr + "' HOUR(" + strconv.FormatInt(int64(dt.leadScale), 10) + ")"
+ case QUA_HM:
+ hStr = strconv.FormatInt(int64(float64(dt.hours)), 10)
+ mStr = strconv.FormatInt(int64(float64(dt.minutes)), 10)
+
+ if dt.negative {
+ interval += "-"
+ }
+
+ if len(hStr) < dt.leadScale {
+ l = len(hStr)
+ destLen = dt.leadScale
+
+ for destLen > l {
+ hStr = "0" + hStr
+ destLen--
+ }
+ }
+ if len(mStr) < 2 {
+ mStr = "0" + mStr
+ }
+
+ interval += "'" + hStr + ":" + mStr + "' HOUR(" + strconv.FormatInt(int64(dt.leadScale), 10) + ") TO MINUTE"
+ case QUA_HMS:
+ nStr = dt.getMsecString()
+ hStr = strconv.FormatInt(int64(float64(dt.hours)), 10)
+ mStr = strconv.FormatInt(int64(float64(dt.minutes)), 10)
+ sStr = strconv.FormatInt(int64(float64(dt.seconds)), 10)
+
+ if dt.negative {
+ interval += "-"
+ }
+
+ if len(hStr) < dt.leadScale {
+ l = len(hStr)
+ destLen = dt.leadScale
+
+ for destLen > l {
+ hStr = "0" + hStr
+ destLen--
+ }
+ }
+ if len(mStr) < 2 {
+ mStr = "0" + mStr
+ }
+ if len(sStr) < 2 {
+ sStr = "0" + sStr
+ }
+
+ interval += "'" + hStr + ":" + mStr + ":" + sStr
+ if nStr != "" {
+ interval += "." + nStr
+ }
+
+ interval += "' HOUR(" + strconv.FormatInt(int64(dt.leadScale), 10) + ") TO SECOND(" + strconv.FormatInt(int64(dt.secScale), 10) + ")"
+
+ case QUA_M:
+ mStr = strconv.FormatInt(int64(float64(dt.minutes)), 10)
+
+ if dt.negative {
+ interval += "-"
+ }
+
+ if len(mStr) < dt.leadScale {
+ l = len(mStr)
+ destLen = dt.leadScale
+
+ for destLen > l {
+ mStr = "0" + mStr
+ destLen--
+ }
+ }
+
+ interval += "'" + mStr + "' MINUTE(" + strconv.FormatInt(int64(dt.leadScale), 10) + ")"
+ case QUA_MS:
+ nStr = dt.getMsecString()
+ mStr = strconv.FormatInt(int64(float64(dt.minutes)), 10)
+ sStr = strconv.FormatInt(int64(float64(dt.seconds)), 10)
+
+ if dt.negative {
+ interval += "-"
+ }
+
+ if len(mStr) < dt.leadScale {
+ l = len(mStr)
+ destLen = dt.leadScale
+
+ for destLen > l {
+ mStr = "0" + mStr
+ destLen--
+ }
+ }
+ if len(sStr) < 2 {
+ sStr = "0" + sStr
+ }
+ interval += "'" + mStr + ":" + sStr
+ if nStr != "" {
+ interval += "." + nStr
+ }
+
+ interval += "' MINUTE(" + strconv.FormatInt(int64(dt.leadScale), 10) + ") TO SECOND(" + strconv.FormatInt(int64(dt.secScale), 10) + ")"
+ case QUA_S:
+ nStr = dt.getMsecString()
+ sStr = strconv.FormatInt(int64(float64(dt.seconds)), 10)
+
+ if dt.negative {
+ interval += "-"
+ }
+
+ if len(sStr) < dt.leadScale {
+ l = len(sStr)
+ destLen = dt.leadScale
+
+ for destLen > l {
+ sStr = "0" + sStr
+ destLen--
+ }
+ }
+
+ interval += "'" + sStr
+
+ if nStr != "" {
+ interval += "." + nStr
+ }
+
+ interval += "' SECOND(" + strconv.FormatInt(int64(dt.leadScale), 10) + ", " + strconv.FormatInt(int64(dt.secScale), 10) + ")"
+
+ }
+
+ return interval
+}
+
+func (dest *DmIntervalDT) Scan(src interface{}) error {
+ if dest == nil {
+ return ECGO_STORE_IN_NIL_POINTER.throw()
+ }
+ switch src := src.(type) {
+ case nil:
+ *dest = *new(DmIntervalDT)
+
+ (*dest).Valid = false
+ return nil
+ case *DmIntervalDT:
+ *dest = *src
+ return nil
+ case string:
+ ret, err := NewDmIntervalDTByString(src)
+ if err != nil {
+ return err
+ }
+ *dest = *ret
+ return nil
+ default:
+ return UNSUPPORTED_SCAN
+ }
+}
+
+func (dt DmIntervalDT) Value() (driver.Value, error) {
+ if !dt.Valid {
+ return nil, nil
+ }
+ return dt, nil
+}
+
+func (dt *DmIntervalDT) checkScale(leadScale int) (int, error) {
+ switch dt._type {
+ case QUA_D:
+ if leadScale == -1 {
+ leadScale = len(strconv.FormatInt(int64(math.Abs(float64(dt.days))), 10))
+ } else if leadScale < len(strconv.FormatInt(int64(math.Abs(float64(dt.days))), 10)) {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ case QUA_DH:
+ if leadScale == -1 {
+ leadScale = len(strconv.FormatInt(int64(math.Abs(float64(dt.days))), 10))
+ } else if leadScale < len(strconv.FormatInt(int64(math.Abs(float64(dt.days))), 10)) {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ if int64(math.Abs(float64((dt.hours)))) > 23 {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ case QUA_DHM:
+ if leadScale == -1 {
+ leadScale = len(strconv.FormatInt(int64(math.Abs(float64(dt.days))), 10))
+ } else if leadScale < len(strconv.FormatInt(int64(math.Abs(float64(dt.days))), 10)) {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ if int64(math.Abs(float64(dt.hours))) > 23 || int64(math.Abs(float64(dt.minutes))) > 59 {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ case QUA_DHMS:
+ if leadScale == -1 {
+ leadScale = len(strconv.FormatInt(int64(math.Abs(float64(dt.days))), 10))
+ } else if leadScale < len(strconv.FormatInt(int64(math.Abs(float64(dt.days))), 10)) {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ if int64(math.Abs(float64(dt.hours))) > 23 || int64(math.Abs(float64(dt.minutes))) > 59 ||
+ int64(math.Abs(float64(dt.seconds))) > 59 {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ case QUA_H:
+ if leadScale == -1 {
+ leadScale = len(strconv.FormatInt(int64(math.Abs(float64(dt.hours))), 10))
+ } else if leadScale < len(strconv.FormatInt(int64(math.Abs(float64(dt.hours))), 10)) {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ case QUA_HM:
+ if leadScale == -1 {
+ leadScale = len(strconv.FormatInt(int64(math.Abs(float64(dt.hours))), 10))
+ } else if leadScale < len(strconv.FormatInt(int64(math.Abs(float64(dt.hours))), 10)) {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ if int64(math.Abs(float64(dt.minutes))) > 59 {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ case QUA_HMS:
+ if leadScale == -1 {
+ leadScale = len(strconv.FormatInt(int64(math.Abs(float64(dt.hours))), 10))
+ } else if leadScale < len(strconv.FormatInt(int64(math.Abs(float64(dt.hours))), 10)) {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ if int64(math.Abs(float64(dt.minutes))) > 59 || int64(math.Abs(float64(dt.seconds))) > 59 {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ case QUA_M:
+ if leadScale == -1 {
+ leadScale = len(strconv.FormatInt(int64(math.Abs(float64(dt.minutes))), 10))
+ } else if leadScale < len(strconv.FormatInt(int64(math.Abs(float64(dt.minutes))), 10)) {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ case QUA_MS:
+ if leadScale == -1 {
+ leadScale = len(strconv.FormatInt(int64(math.Abs(float64(dt.minutes))), 10))
+ } else if leadScale < len(strconv.FormatInt(int64(math.Abs(float64(dt.minutes))), 10)) {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ if int64(math.Abs(float64(dt.seconds))) > 59 {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ case QUA_S:
+ if leadScale == -1 {
+ leadScale = len(strconv.FormatInt(int64(math.Abs(float64(dt.minutes))), 10))
+ } else if leadScale < len(strconv.FormatInt(int64(math.Abs(float64(dt.minutes))), 10)) {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ }
+
+ if leadScale > LOADPREC_MAX {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ return leadScale, nil
+}
+
+func (dt *DmIntervalDT) parsePrec(leadStr string) (int, error) {
+ leftBtId := strings.Index(leadStr, "(")
+ rightBtId := strings.Index(leadStr, ")")
+ var prec int64 = -1
+
+ if rightBtId != -1 && leftBtId != -1 && rightBtId > leftBtId+1 {
+ strPrec := strings.TrimSpace(leadStr[leftBtId+1 : rightBtId])
+ var err error
+ prec, err = strconv.ParseInt(strPrec, 10, 32)
+ if err != nil {
+ return -1, err
+ }
+ }
+
+ return int(prec), nil
+}
+
+func (dt *DmIntervalDT) setPrecForSvr(fullStr string, leadScale string, secScale string) error {
+ prec, err := dt.parsePrec(leadScale)
+ if err != nil {
+ return err
+ }
+
+ prec, err = dt.checkScale(prec)
+ if err != nil {
+ return err
+ }
+
+ if prec < LOADPREC_DEFAULT {
+ dt.leadScale = LOADPREC_DEFAULT
+ } else {
+ dt.leadScale = prec
+ }
+
+ prec, err = dt.parsePrec(secScale)
+ if err != nil {
+ return err
+ }
+
+ if prec >= 0 && prec < SECDPREC_MAX {
+ dt.secScale = prec
+ } else {
+ dt.secScale = SECDPREC_DEFAULT
+ }
+
+ dt.scaleForSvr = int(dt._type<<8) + (dt.leadScale << 4) + dt.secScale
+ return nil
+}
+
+func (dt *DmIntervalDT) checkSign(str string) string {
+
+ if str[0] == '-' {
+ str = strings.TrimSpace(str[1:])
+ dt.negative = true
+ } else if str[0] == '+' {
+ str = strings.TrimSpace(str[1:])
+ dt.negative = false
+ }
+
+ return str
+}
+
+func (dt *DmIntervalDT) setDay(value string) error {
+ list := util.Split(value, " :.")
+ if len(list) > 1 {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ dt._type = QUA_D
+ i, err := strconv.ParseInt(value, 10, 32)
+ if err != nil {
+ return err
+ }
+
+ if i < 0 {
+ dt.days = int(-i)
+ dt.negative = true
+ } else {
+ dt.days = int(i)
+ }
+ return nil
+}
+
+func (dt *DmIntervalDT) setHour(value string) error {
+ list := util.Split(value, " :.")
+ if len(list) > 1 {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ dt._type = QUA_H
+ i, err := strconv.ParseInt(value, 10, 32)
+ if err != nil {
+ return err
+ }
+
+ if i < 0 {
+ dt.hours = int(-i)
+ dt.negative = true
+ } else {
+ dt.hours = int(i)
+ }
+ return nil
+}
+
+func (dt *DmIntervalDT) setMinute(value string) error {
+ list := util.Split(value, " :.")
+ if len(list) > 1 {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ dt._type = QUA_M
+ i, err := strconv.ParseInt(value, 10, 32)
+ if err != nil {
+ return err
+ }
+
+ if i < 0 {
+ dt.minutes = int(-i)
+ dt.negative = true
+ } else {
+ dt.minutes = int(i)
+ }
+ return nil
+}
+
+func (dt *DmIntervalDT) setSecond(value string) error {
+ list := util.Split(value, " :.")
+ if len(list) > 2 {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ dt._type = QUA_S
+ i, err := strconv.ParseInt(list[0], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ nano := 0
+ if len(list) > 1 {
+ strNano := "0" + "." + list[1]
+ d_v, err := strconv.ParseFloat(strNano, 64)
+ if err != nil {
+ return err
+ }
+ nx := math.Pow10(dt.secScale)
+ nano = (int)(d_v * nx)
+ }
+
+ if i < 0 {
+ dt.seconds = int(-i)
+ } else {
+ dt.seconds = int(i)
+ }
+ if nano < 0 {
+ dt.fraction = -nano
+ } else {
+ dt.fraction = nano
+ }
+ if i < 0 || nano < 0 {
+ dt.negative = true
+ }
+ return nil
+
+}
+
+func (dt *DmIntervalDT) setHourToSecond(value string) error {
+ list := util.Split(value, " :.")
+ if len(list) > 4 {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ dt._type = QUA_HMS
+
+ h, err := strconv.ParseInt(list[0], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ m, err := strconv.ParseInt(list[1], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ s, err := strconv.ParseInt(list[2], 10, 32)
+ if err != nil {
+ return err
+ }
+ nano := 0
+ if len(list) > 3 {
+ strNano := "0" + "." + list[3]
+ d_v, err := strconv.ParseFloat(strNano, 64)
+ if err != nil {
+ return err
+ }
+ nx := math.Pow10(dt.secScale)
+ nano = (int)(d_v * nx)
+ }
+
+ if h < 0 {
+ dt.hours = int(-h)
+ } else {
+ dt.hours = int(h)
+ }
+ if m < 0 {
+ dt.minutes = int(-m)
+ } else {
+ dt.minutes = int(m)
+ }
+ if s < 0 {
+ dt.seconds = int(-s)
+ } else {
+ dt.seconds = int(s)
+ }
+ if nano < 0 {
+ dt.fraction = -nano
+ } else {
+ dt.fraction = nano
+ }
+ if h < 0 || m < 0 || s < 0 || nano < 0 {
+ dt.negative = true
+ }
+ return nil
+}
+
+func (dt *DmIntervalDT) setHourToMinute(value string) error {
+ value = strings.TrimSpace(value)
+ list := util.Split(value, " :.")
+ if len(list) > 2 {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ dt._type = QUA_HM
+
+ h, err := strconv.ParseInt(list[0], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ m, err := strconv.ParseInt(list[1], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ if h < 0 {
+ dt.hours = int(-h)
+ } else {
+ dt.hours = int(h)
+ }
+ if m < 0 {
+ dt.minutes = int(-m)
+ } else {
+ dt.minutes = int(m)
+ }
+ if h < 0 || m < 0 {
+ dt.negative = true
+ }
+ return nil
+}
+
+func (dt *DmIntervalDT) setMinuteToSecond(value string) error {
+ list := util.Split(value, " :.")
+ if len(list) > 3 {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ dt._type = QUA_MS
+
+ m, err := strconv.ParseInt(list[0], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ s, err := strconv.ParseInt(list[1], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ nano := 0
+ if len(list) > 2 {
+ strNano := "0" + "." + list[2]
+ d_v, err := strconv.ParseFloat(strNano, 64)
+ if err != nil {
+ return err
+ }
+
+ nx := math.Pow10(dt.secScale)
+ nano = (int)(d_v * nx)
+ }
+
+ if m < 0 {
+ dt.minutes = int(-m)
+ } else {
+ dt.minutes = int(m)
+ }
+ if s < 0 {
+ dt.seconds = int(-s)
+ } else {
+ dt.seconds = int(s)
+ }
+ if nano < 0 {
+ dt.fraction = -nano
+ } else {
+ dt.fraction = nano
+ }
+ if m < 0 || s < 0 || nano < 0 {
+ dt.negative = true
+ }
+ return nil
+}
+
+func (dt *DmIntervalDT) setDayToHour(value string) error {
+ list := util.Split(value, " :.")
+ if len(list) > 2 {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ dt._type = QUA_DH
+
+ d, err := strconv.ParseInt(list[0], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ h, err := strconv.ParseInt(list[1], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ if d < 0 {
+ dt.days = int(-d)
+ } else {
+ dt.days = int(d)
+ }
+ if h < 0 {
+ dt.hours = int(-h)
+ } else {
+ dt.hours = int(h)
+ }
+ if d < 0 || h < 0 {
+ dt.negative = true
+ }
+ return nil
+}
+
+func (dt *DmIntervalDT) setDayToMinute(value string) error {
+ list := util.Split(value, " :.")
+ if len(list) > 3 {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ dt._type = QUA_DHM
+
+ d, err := strconv.ParseInt(list[0], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ h, err := strconv.ParseInt(list[1], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ m, err := strconv.ParseInt(list[2], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ if d < 0 {
+ dt.days = int(-d)
+ } else {
+ dt.days = int(d)
+ }
+ if h < 0 {
+ dt.hours = int(-h)
+ } else {
+ dt.hours = int(h)
+ }
+ if m < 0 {
+ dt.minutes = int(-m)
+ } else {
+ dt.minutes = int(m)
+ }
+ if d < 0 || h < 0 || m < 0 {
+ dt.negative = true
+ }
+ return nil
+}
+
+func (dt *DmIntervalDT) setDayToSecond(value string) error {
+ list := util.Split(value, " :.")
+ if len(list) > 5 {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ dt._type = QUA_DHMS
+
+ d, err := strconv.ParseInt(list[0], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ h, err := strconv.ParseInt(list[1], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ m, err := strconv.ParseInt(list[2], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ s, err := strconv.ParseInt(list[3], 10, 32)
+ if err != nil {
+ return err
+ }
+
+ nano := 0
+ if len(list) > 4 {
+ strNano := "0" + "." + list[4]
+ d_v, err := strconv.ParseFloat(strNano, 64)
+ if err != nil {
+ return err
+ }
+
+ nx := math.Pow10(dt.secScale)
+ nano = (int)(d_v * nx)
+ }
+
+ if d < 0 {
+ dt.days = int(-d)
+ } else {
+ dt.days = int(d)
+ }
+ if h < 0 {
+ dt.hours = int(-h)
+ } else {
+ dt.hours = int(h)
+ }
+ if m < 0 {
+ dt.minutes = int(-m)
+ } else {
+ dt.minutes = int(m)
+ }
+ if s < 0 {
+ dt.seconds = int(-s)
+ } else {
+ dt.seconds = int(s)
+ }
+ if nano < 0 {
+ dt.fraction = -nano
+ } else {
+ dt.fraction = nano
+ }
+ if d < 0 || h < 0 || m < 0 || s < 0 || nano < 0 {
+ dt.negative = true
+ }
+ return nil
+}
+
+func (dt *DmIntervalDT) getMsecString() string {
+ nano := strconv.Itoa(dt.fraction)
+
+ for i := 6 - len(nano); i > 0; i-- {
+ nano = "0" + nano
+ }
+
+ if len(nano) > dt.secScale {
+ nano = nano[:dt.secScale]
+ }
+
+ return nano
+}
+
+func (dt *DmIntervalDT) encode(scale int) ([]byte, error) {
+ if scale == 0 {
+ scale = dt.scaleForSvr
+ }
+ day, hour, minute, second, f := dt.days, dt.hours, dt.minutes, dt.seconds, dt.fraction
+ if scale != dt.scaleForSvr {
+ convertDT, err := dt.convertTo(scale)
+ if err != nil {
+ return nil, err
+ }
+ day, hour, minute, second, f = convertDT.days, convertDT.hours, convertDT.minutes, convertDT.seconds, convertDT.fraction
+ } else {
+ loadPrec := (scale >> 4) & 0x0000000F
+ if _, err := dt.checkScale(loadPrec); err != nil {
+ return nil, err
+ }
+ }
+
+ bytes := make([]byte, 24)
+ if dt.negative {
+ Dm_build_1220.Dm_build_1236(bytes, 0, int32(-day))
+ Dm_build_1220.Dm_build_1236(bytes, 4, int32(-hour))
+ Dm_build_1220.Dm_build_1236(bytes, 8, int32(-minute))
+ Dm_build_1220.Dm_build_1236(bytes, 12, int32(-second))
+ Dm_build_1220.Dm_build_1236(bytes, 16, int32(-f))
+ Dm_build_1220.Dm_build_1236(bytes, 20, int32(scale))
+ } else {
+ Dm_build_1220.Dm_build_1236(bytes, 0, int32(day))
+ Dm_build_1220.Dm_build_1236(bytes, 4, int32(hour))
+ Dm_build_1220.Dm_build_1236(bytes, 8, int32(minute))
+ Dm_build_1220.Dm_build_1236(bytes, 12, int32(second))
+ Dm_build_1220.Dm_build_1236(bytes, 16, int32(f))
+ Dm_build_1220.Dm_build_1236(bytes, 20, int32(scale))
+ }
+ return bytes, nil
+}
+
+func (dt *DmIntervalDT) convertTo(scale int) (*DmIntervalDT, error) {
+ destType := (scale & 0x0000FF00) >> 8
+ leadPrec := (scale >> 4) & 0x0000000F
+ secScale := scale & 0x0000000F
+ dayIndex := 0
+ hourIndex := 1
+ minuteIndex := 2
+ secondIndex := 3
+ fractionIndex := 4
+ orgDT := make([]int, 5)
+ destDT := make([]int, 5)
+
+ switch dt._type {
+ case QUA_D:
+ orgDT[dayIndex] = dt.days
+ case QUA_DH:
+ orgDT[dayIndex] = dt.days
+ orgDT[hourIndex] = dt.hours
+ case QUA_DHM:
+ orgDT[dayIndex] = dt.days
+ orgDT[hourIndex] = dt.hours
+ orgDT[minuteIndex] = dt.minutes
+ case QUA_DHMS:
+ orgDT[dayIndex] = dt.days
+ orgDT[hourIndex] = dt.hours
+ orgDT[minuteIndex] = dt.minutes
+ orgDT[secondIndex] = dt.seconds
+ orgDT[fractionIndex] = dt.fraction
+ case QUA_H:
+ orgDT[dayIndex] = dt.hours / 24
+ orgDT[hourIndex] = dt.hours % 24
+ case QUA_HM:
+ orgDT[dayIndex] = dt.hours / 24
+ orgDT[hourIndex] = dt.hours % 24
+ orgDT[minuteIndex] = dt.minutes
+ case QUA_HMS:
+ orgDT[dayIndex] = dt.hours / 24
+ orgDT[hourIndex] = dt.hours % 24
+ orgDT[minuteIndex] = dt.minutes
+ orgDT[secondIndex] = dt.seconds
+ orgDT[fractionIndex] = dt.fraction
+ case QUA_M:
+ orgDT[dayIndex] = dt.minutes / (24 * 60)
+ orgDT[hourIndex] = (dt.minutes % (24 * 60)) / 60
+ orgDT[minuteIndex] = (dt.minutes % (24 * 60)) % 60
+ case QUA_MS:
+ orgDT[dayIndex] = dt.minutes / (24 * 60)
+ orgDT[hourIndex] = (dt.minutes % (24 * 60)) / 60
+ orgDT[minuteIndex] = (dt.minutes % (24 * 60)) % 60
+ orgDT[secondIndex] = dt.seconds
+ orgDT[fractionIndex] = dt.fraction
+ case QUA_S:
+ orgDT[dayIndex] = dt.seconds / (24 * 60 * 60)
+ orgDT[hourIndex] = (dt.seconds % (24 * 60 * 60)) / (60 * 60)
+ orgDT[minuteIndex] = ((dt.seconds % (24 * 60 * 60)) % (60 * 60)) / 60
+ orgDT[secondIndex] = ((dt.seconds % (24 * 60 * 60)) % (60 * 60)) % 60
+ orgDT[fractionIndex] = dt.fraction
+ }
+
+ switch byte(destType) {
+ case QUA_D:
+ destDT[dayIndex] = orgDT[dayIndex]
+ if orgDT[hourIndex] >= 12 {
+ incrementDay(QUA_D, destDT)
+ }
+ if leadPrec < len(strconv.Itoa(int(math.Abs(float64(destDT[dayIndex]))))) {
+ return nil, ECGO_INTERVAL_OVERFLOW.throw()
+ }
+ case QUA_DH:
+ destDT[dayIndex] = orgDT[dayIndex]
+ destDT[hourIndex] = orgDT[hourIndex]
+ if orgDT[minuteIndex] >= 30 {
+ incrementHour(QUA_DH, destDT)
+ }
+ if leadPrec < len(strconv.Itoa(int(math.Abs(float64(destDT[dayIndex]))))) {
+ return nil, ECGO_INTERVAL_OVERFLOW.throw()
+ }
+ case QUA_DHM:
+ destDT[dayIndex] = orgDT[dayIndex]
+ destDT[hourIndex] = orgDT[hourIndex]
+ destDT[minuteIndex] = orgDT[minuteIndex]
+ if orgDT[secondIndex] >= 30 {
+ incrementMinute(QUA_DHM, destDT)
+ }
+ if leadPrec < len(strconv.Itoa(int(math.Abs(float64(destDT[dayIndex]))))) {
+ return nil, ECGO_INTERVAL_OVERFLOW.throw()
+ }
+ case QUA_DHMS:
+ destDT[dayIndex] = orgDT[dayIndex]
+ destDT[hourIndex] = orgDT[hourIndex]
+ destDT[minuteIndex] = orgDT[minuteIndex]
+ destDT[secondIndex] = orgDT[secondIndex]
+ destDT[fractionIndex] = orgDT[fractionIndex]
+ dt.convertMSecond(QUA_DHMS, destDT, secScale)
+ if leadPrec < len(strconv.Itoa(int(math.Abs(float64(destDT[dayIndex]))))) {
+ return nil, ECGO_INTERVAL_OVERFLOW.throw()
+ }
+ case QUA_H:
+ destDT[hourIndex] = orgDT[dayIndex]*24 + orgDT[hourIndex]
+ if orgDT[minuteIndex] >= 30 {
+ incrementHour(QUA_H, destDT)
+ }
+ if leadPrec < len(strconv.Itoa(int(math.Abs(float64(destDT[hourIndex]))))) {
+ return nil, ECGO_INTERVAL_OVERFLOW.throw()
+ }
+ case QUA_HM:
+ destDT[hourIndex] = orgDT[dayIndex]*24 + orgDT[hourIndex]
+ destDT[minuteIndex] = orgDT[minuteIndex]
+ if orgDT[secondIndex] >= 30 {
+ incrementMinute(QUA_HM, destDT)
+ }
+ if leadPrec < len(strconv.Itoa(int(math.Abs(float64(destDT[hourIndex]))))) {
+ return nil, ECGO_INTERVAL_OVERFLOW.throw()
+ }
+ case QUA_HMS:
+ destDT[hourIndex] = orgDT[dayIndex]*24 + orgDT[hourIndex]
+ destDT[minuteIndex] = orgDT[minuteIndex]
+ destDT[secondIndex] = orgDT[secondIndex]
+ destDT[fractionIndex] = orgDT[fractionIndex]
+ dt.convertMSecond(QUA_HMS, destDT, secScale)
+ if leadPrec < len(strconv.Itoa(int(math.Abs(float64(destDT[hourIndex]))))) {
+ return nil, ECGO_INTERVAL_OVERFLOW.throw()
+ }
+ case QUA_M:
+ destDT[minuteIndex] = orgDT[dayIndex]*24*60 + orgDT[hourIndex]*60 + orgDT[minuteIndex]
+ if orgDT[secondIndex] >= 30 {
+ incrementMinute(QUA_M, destDT)
+ }
+ if leadPrec < len(strconv.Itoa(int(math.Abs(float64(destDT[minuteIndex]))))) {
+ return nil, ECGO_INTERVAL_OVERFLOW.throw()
+ }
+ case QUA_MS:
+ destDT[minuteIndex] = orgDT[dayIndex]*24*60 + orgDT[hourIndex]*60 + orgDT[minuteIndex]
+ destDT[secondIndex] = orgDT[secondIndex]
+ destDT[fractionIndex] = orgDT[fractionIndex]
+ dt.convertMSecond(QUA_MS, destDT, secScale)
+ if leadPrec < len(strconv.Itoa(int(math.Abs(float64(destDT[minuteIndex]))))) {
+ return nil, ECGO_INTERVAL_OVERFLOW.throw()
+ }
+ case QUA_S:
+ destDT[secondIndex] = orgDT[dayIndex]*24*60*60 + orgDT[hourIndex]*60*60 + orgDT[minuteIndex]*60 + orgDT[secondIndex]
+ destDT[fractionIndex] = orgDT[fractionIndex]
+ dt.convertMSecond(QUA_S, destDT, secScale)
+ if leadPrec < len(strconv.Itoa(int(math.Abs(float64(destDT[secondIndex]))))) {
+ return nil, ECGO_INTERVAL_OVERFLOW.throw()
+ }
+ }
+
+ return &DmIntervalDT{
+ _type: byte(destType),
+ negative: dt.negative,
+ leadScale: (scale >> 4) & 0x0000000F,
+ secScale: scale & 0x0000000F,
+ scaleForSvr: scale,
+ days: destDT[dayIndex],
+ hours: destDT[hourIndex],
+ minutes: destDT[minuteIndex],
+ seconds: destDT[secondIndex],
+ fraction: destDT[fractionIndex],
+ Valid: true,
+ }, nil
+}
+
+func (dt DmIntervalDT) convertMSecond(destType byte, destDT []int, destSecScale int) {
+ fractionIndex := 4
+ orgFraction := destDT[fractionIndex]
+ if destSecScale == 0 || destSecScale < dt.secScale {
+ n := int(math.Pow(10, 6-float64(destSecScale)-1))
+ f := orgFraction / n / 10
+
+ if (orgFraction/n)%10 >= 5 {
+ f++
+ f = f * n * 10
+ if f == 1000000 {
+ destDT[fractionIndex] = 0
+ incrementSecond(destType, destDT)
+ return
+ }
+ }
+ destDT[fractionIndex] = f
+ }
+}
+
+func incrementDay(destType byte, dt []int) {
+ dayIndex := 0
+ dt[dayIndex]++
+}
+
+func incrementHour(destType byte, dt []int) {
+ hourIndex := 1
+ dt[hourIndex]++
+ if dt[hourIndex] == 24 && destType < QUA_H {
+ incrementDay(destType, dt)
+ dt[hourIndex] = 0
+ }
+}
+
+func incrementMinute(destType byte, dt []int) {
+ minuteIndex := 2
+ dt[minuteIndex]++
+ if dt[minuteIndex] == 60 && destType < QUA_M {
+ incrementHour(destType, dt)
+ dt[minuteIndex] = 0
+ }
+}
+
+func incrementSecond(destType byte, dt []int) {
+ secondIndex := 3
+ dt[secondIndex]++
+ if dt[secondIndex] == 60 && destType < QUA_S {
+ incrementMinute(destType, dt)
+ dt[secondIndex] = 0
+ }
+}
+
+func (dt *DmIntervalDT) checkValid() error {
+ if !dt.Valid {
+ return ECGO_IS_NULL.throw()
+ }
+ return nil
+}
diff --git a/dmr/r.go b/dmr/r.go
new file mode 100644
index 0000000..912e58d
--- /dev/null
+++ b/dmr/r.go
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "database/sql/driver"
+ "math"
+ "strconv"
+ "strings"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+const (
+ QUA_Y = 0
+ QUA_YM = 1
+ QUA_MO = 2
+)
+
+type DmIntervalYM struct {
+ leadScale int
+ isLeadScaleSet bool
+ _type byte
+ years int
+ months int
+ scaleForSvr int
+
+ Valid bool
+}
+
+func newDmIntervalYM() *DmIntervalYM {
+ return &DmIntervalYM{
+ Valid: true,
+ }
+}
+
+func NewDmIntervalYMByString(str string) (ym *DmIntervalYM, err error) {
+ defer func() {
+ if p := recover(); p != nil {
+ err = ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ }()
+ ym = newDmIntervalYM()
+ ym.isLeadScaleSet = false
+ if err = ym.parseIntervYMString(strings.TrimSpace(str)); err != nil {
+ return nil, err
+ }
+ return ym, nil
+}
+
+func newDmIntervalYMByBytes(bytes []byte) *DmIntervalYM {
+ ym := newDmIntervalYM()
+
+ ym.scaleForSvr = int(Dm_build_1220.Dm_build_1322(bytes, 8))
+ ym.leadScale = (ym.scaleForSvr >> 4) & 0x0000000F
+ ym._type = bytes[9]
+ switch ym._type {
+ case QUA_Y:
+ ym.years = int(Dm_build_1220.Dm_build_1322(bytes, 0))
+ case QUA_YM:
+ ym.years = int(Dm_build_1220.Dm_build_1322(bytes, 0))
+ ym.months = int(Dm_build_1220.Dm_build_1322(bytes, 4))
+ case QUA_MO:
+ ym.months = int(Dm_build_1220.Dm_build_1322(bytes, 4))
+ }
+ return ym
+}
+
+func (ym *DmIntervalYM) GetYear() int {
+ return ym.years
+}
+
+func (ym *DmIntervalYM) GetMonth() int {
+ return ym.months
+}
+
+func (ym *DmIntervalYM) GetYMType() byte {
+ return ym._type
+}
+
+func (ym *DmIntervalYM) String() string {
+ if !ym.Valid {
+ return ""
+ }
+ str := "INTERVAL "
+ var year, month string
+ var l int
+ var destLen int
+
+ switch ym._type {
+ case QUA_Y:
+ year = strconv.FormatInt(int64(math.Abs(float64(ym.years))), 10)
+ if ym.years < 0 {
+ str += "-"
+ }
+
+ if ym.leadScale > len(year) {
+ l = len(year)
+ destLen = ym.leadScale
+
+ for destLen > l {
+ year = "0" + year
+ destLen--
+ }
+ }
+
+ str += "'" + year + "' YEAR(" + strconv.FormatInt(int64(ym.leadScale), 10) + ")"
+ case QUA_YM:
+ year = strconv.FormatInt(int64(math.Abs(float64(ym.years))), 10)
+ month = strconv.FormatInt(int64(math.Abs(float64(ym.months))), 10)
+
+ if ym.years < 0 || ym.months < 0 {
+ str += "-"
+ }
+
+ if ym.leadScale > len(year) {
+ l = len(year)
+ destLen = ym.leadScale
+
+ for destLen > l {
+ year = "0" + year
+ destLen--
+ }
+ }
+
+ if len(month) < 2 {
+ month = "0" + month
+ }
+
+ str += "'" + year + "-" + month + "' YEAR(" + strconv.FormatInt(int64(ym.leadScale), 10) + ") TO MONTH"
+ case QUA_MO:
+
+ month = strconv.FormatInt(int64(math.Abs(float64(ym.months))), 10)
+ if ym.months < 0 {
+ str += "-"
+ }
+
+ if ym.leadScale > len(month) {
+ l = len(month)
+ destLen = ym.leadScale
+ for destLen > l {
+ month = "0" + month
+ destLen--
+ }
+ }
+
+ str += "'" + month + "' MONTH(" + strconv.FormatInt(int64(ym.leadScale), 10) + ")"
+ }
+ return str
+}
+
+func (dest *DmIntervalYM) Scan(src interface{}) error {
+ if dest == nil {
+ return ECGO_STORE_IN_NIL_POINTER.throw()
+ }
+ switch src := src.(type) {
+ case nil:
+ *dest = *new(DmIntervalYM)
+
+ (*dest).Valid = false
+ return nil
+ case *DmIntervalYM:
+ *dest = *src
+ return nil
+ case string:
+ ret, err := NewDmIntervalYMByString(src)
+ if err != nil {
+ return err
+ }
+ *dest = *ret
+ return nil
+ default:
+ return UNSUPPORTED_SCAN
+ }
+}
+
+func (ym DmIntervalYM) Value() (driver.Value, error) {
+ if !ym.Valid {
+ return nil, nil
+ }
+ return ym, nil
+}
+
+func (ym *DmIntervalYM) parseIntervYMString(str string) error {
+ str = strings.ToUpper(str)
+ ret := strings.Split(str, " ")
+ l := len(ret)
+ if l < 3 || !util.StringUtil.EqualsIgnoreCase(ret[0], "INTERVAL") || !(strings.HasPrefix(ret[2], "YEAR") || strings.HasPrefix(ret[2], "MONTH")) {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ ym._type = QUA_YM
+ yearId := strings.Index(str, "YEAR")
+ monthId := strings.Index(str, "MONTH")
+ toId := strings.Index(str, "TO")
+ var err error
+ if toId == -1 {
+ if yearId != -1 && monthId == -1 {
+ ym._type = QUA_Y
+ ym.leadScale, err = ym.getLeadPrec(str, yearId)
+ if err != nil {
+ return err
+ }
+ } else if monthId != -1 && yearId == -1 {
+ ym._type = QUA_MO
+ ym.leadScale, err = ym.getLeadPrec(str, monthId)
+ if err != nil {
+ return err
+ }
+ } else {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ } else {
+ if yearId == -1 || monthId == -1 {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ ym._type = QUA_YM
+ ym.leadScale, err = ym.getLeadPrec(str, yearId)
+ if err != nil {
+ return err
+ }
+ }
+
+ ym.scaleForSvr = (int(ym._type) << 8) + (ym.leadScale << 4)
+ timeVals, err := ym.getTimeValue(ret[1], int(ym._type))
+ if err != nil {
+ return err
+ }
+ ym.years = timeVals[0]
+ ym.months = timeVals[1]
+ return ym.checkScale(ym.leadScale)
+}
+
+func (ym *DmIntervalYM) getLeadPrec(str string, startIndex int) (int, error) {
+ if ym.isLeadScaleSet {
+ return ym.leadScale, nil
+ }
+
+ leftBtId := strings.Index(str[startIndex:], "(")
+ rightBtId := strings.Index(str[startIndex:], ")")
+ leadPrec := 0
+
+ if rightBtId == -1 && leftBtId == -1 {
+ leftBtId += startIndex
+ rightBtId += startIndex
+ l := strings.Index(str, "'")
+ var r int
+ var dataStr string
+ if l != -1 {
+ r = strings.Index(str[l+1:], "'")
+ if r != -1 {
+ r += l + 1
+ }
+ } else {
+ r = -1
+ }
+
+ if r != -1 {
+ dataStr = strings.TrimSpace(str[l+1 : r])
+ } else {
+ dataStr = ""
+ }
+
+ if dataStr != "" {
+ sign := dataStr[0]
+ if sign == '+' || sign == '-' {
+ dataStr = strings.TrimSpace(dataStr[1:])
+ }
+ end := strings.Index(dataStr, "-")
+
+ if end != -1 {
+ dataStr = dataStr[:end]
+ }
+
+ leadPrec = len(dataStr)
+ } else {
+ leadPrec = 2
+ }
+ } else if rightBtId != -1 && leftBtId != -1 && rightBtId > leftBtId+1 {
+ leftBtId += startIndex
+ rightBtId += startIndex
+ strPrec := strings.TrimSpace(str[leftBtId+1 : rightBtId])
+ temp, err := strconv.ParseInt(strPrec, 10, 32)
+ if err != nil {
+ return 0, err
+ }
+
+ leadPrec = int(temp)
+ } else {
+ return 0, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ return leadPrec, nil
+}
+
+func (ym *DmIntervalYM) checkScale(prec int) error {
+ switch ym._type {
+ case QUA_Y:
+ if prec < len(strconv.FormatInt(int64(math.Abs(float64(ym.years))), 10)) {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ case QUA_YM:
+ if prec < len(strconv.FormatInt(int64(math.Abs(float64(ym.years))), 10)) {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ if int64(math.Abs(float64(ym.months))) > 11 {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ case QUA_MO:
+ if prec < len(strconv.FormatInt(int64(math.Abs(float64(ym.months))), 10)) {
+ return ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ }
+ return nil
+}
+
+func (ym *DmIntervalYM) getTimeValue(subStr string, _type int) ([]int, error) {
+ hasQuate := false
+ if subStr[0] == '\'' && subStr[len(subStr)-1] == '\'' {
+ hasQuate = true
+ subStr = strings.TrimSpace(subStr[1 : len(subStr)-1])
+ }
+
+ negative := false
+ if strings.Index(subStr, "-") == 0 {
+ negative = true
+ subStr = subStr[1:]
+ } else if strings.Index(subStr, "+") == 0 {
+ negative = false
+ subStr = subStr[1:]
+ }
+
+ if subStr[0] == '\'' && subStr[len(subStr)-1] == '\'' {
+ hasQuate = true
+ subStr = strings.TrimSpace(subStr[1 : len(subStr)-1])
+ }
+
+ if !hasQuate {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+
+ lastSignIndex := strings.LastIndex(subStr, "-")
+
+ list := make([]string, 2)
+ if lastSignIndex == -1 || lastSignIndex == 0 {
+ list[0] = subStr
+ list[1] = ""
+ } else {
+ list[0] = subStr[0:lastSignIndex]
+ list[1] = subStr[lastSignIndex+1:]
+ }
+
+ var yearVal, monthVal int64
+ var err error
+ if ym._type == QUA_YM {
+ yearVal, err = strconv.ParseInt(list[0], 10, 32)
+ if err != nil {
+ return nil, err
+ }
+
+ if util.StringUtil.EqualsIgnoreCase(list[1], "") {
+ monthVal = 0
+ } else {
+ monthVal, err = strconv.ParseInt(list[1], 10, 32)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if negative {
+ yearVal *= -1
+ monthVal *= -1
+ }
+
+ if yearVal > int64(math.Pow10(ym.leadScale))-1 || yearVal < 1-int64(math.Pow10(ym.leadScale)) {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ } else if ym._type == QUA_Y {
+ yearVal, err = strconv.ParseInt(list[0], 10, 32)
+ if err != nil {
+ return nil, err
+ }
+ monthVal = 0
+
+ if negative {
+ yearVal *= -1
+ }
+
+ if yearVal > int64(math.Pow10(ym.leadScale))-1 || yearVal < 1-int64(math.Pow10(ym.leadScale)) {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ } else {
+ yearVal = 0
+ monthVal, err = strconv.ParseInt(list[0], 10, 32)
+ if err != nil {
+ return nil, err
+ }
+ if negative {
+ monthVal *= -1
+ }
+
+ if monthVal > int64(math.Pow10(ym.leadScale))-1 || monthVal < 1-int64(math.Pow10(ym.leadScale)) {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ }
+
+ ret := make([]int, 2)
+ ret[0] = int(yearVal)
+ ret[1] = int(monthVal)
+
+ return ret, nil
+}
+
+func (ym *DmIntervalYM) encode(scale int) ([]byte, error) {
+ if scale == 0 {
+ scale = ym.scaleForSvr
+ }
+ year, month := ym.years, ym.months
+ if err := ym.checkScale(ym.leadScale); err != nil {
+ return nil, err
+ }
+ if scale != ym.scaleForSvr {
+ convertYM, err := ym.convertTo(scale)
+ if err != nil {
+ return nil, err
+ }
+ year = convertYM.years
+ month = convertYM.months
+ } else {
+ if err := ym.checkScale(ym.leadScale); err != nil {
+ return nil, err
+ }
+ }
+
+ bytes := make([]byte, 12)
+ Dm_build_1220.Dm_build_1236(bytes, 0, int32(year))
+ Dm_build_1220.Dm_build_1236(bytes, 4, int32(month))
+ Dm_build_1220.Dm_build_1236(bytes, 8, int32(scale))
+ return bytes, nil
+}
+
+func (ym *DmIntervalYM) convertTo(scale int) (*DmIntervalYM, error) {
+ destType := (scale & 0x0000FF00) >> 8
+ leadPrec := (scale >> 4) & 0x0000000F
+ totalMonths := ym.years*12 + ym.months
+ year := 0
+ month := 0
+ switch destType {
+ case QUA_Y:
+ year = totalMonths / 12
+
+ if totalMonths%12 >= 6 {
+ year++
+ } else if totalMonths%12 <= -6 {
+ year--
+ }
+ if leadPrec < len(strconv.Itoa(int(math.Abs(float64(year))))) {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ case QUA_YM:
+ year = totalMonths / 12
+ month = totalMonths % 12
+ if leadPrec < len(strconv.Itoa(int(math.Abs(float64(year))))) {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ case QUA_MO:
+ month = totalMonths
+ if leadPrec < len(strconv.Itoa(int(math.Abs(float64(month))))) {
+ return nil, ECGO_INVALID_TIME_INTERVAL.throw()
+ }
+ }
+ return &DmIntervalYM{
+ _type: byte(destType),
+ years: year,
+ months: month,
+ scaleForSvr: scale,
+ leadScale: (scale >> 4) & 0x0000000F,
+ Valid: true,
+ }, nil
+}
+
+func (ym *DmIntervalYM) checkValid() error {
+ if !ym.Valid {
+ return ECGO_IS_NULL.throw()
+ }
+ return nil
+}
diff --git a/dmr/s.go b/dmr/s.go
new file mode 100644
index 0000000..b9f50bc
--- /dev/null
+++ b/dmr/s.go
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+type DmResult struct {
+ filterable
+ dmStmt *DmStatement
+ affectedRows int64
+ insertId int64
+}
+
+func newDmResult(bs *DmStatement, execInfo *execRetInfo) *DmResult {
+ result := DmResult{}
+ result.resetFilterable(&bs.filterable)
+ result.dmStmt = bs
+ result.affectedRows = execInfo.updateCount
+ result.insertId = execInfo.lastInsertId
+ result.idGenerator = dmResultIDGenerator
+
+ return &result
+}
+
+/*************************************************************
+ ** PUBLIC METHODS AND FUNCTIONS
+ *************************************************************/
+func (r *DmResult) LastInsertId() (int64, error) {
+ //if err := r.dmStmt.checkClosed(); err != nil {
+ // return -1, err
+ //}
+ if len(r.filterChain.filters) == 0 {
+ return r.lastInsertId()
+ }
+ return r.filterChain.reset().DmResultLastInsertId(r)
+}
+
+func (r *DmResult) RowsAffected() (int64, error) {
+ //if err := r.dmStmt.checkClosed(); err != nil {
+ // return -1, err
+ //}
+ if len(r.filterChain.filters) == 0 {
+ return r.rowsAffected()
+ }
+ return r.filterChain.reset().DmResultRowsAffected(r)
+}
+
+func (result *DmResult) lastInsertId() (int64, error) {
+ return result.insertId, nil
+}
+
+func (result *DmResult) rowsAffected() (int64, error) {
+ return result.affectedRows, nil
+}
diff --git a/dmr/security/zy.go b/dmr/security/zy.go
new file mode 100644
index 0000000..5a1db64
--- /dev/null
+++ b/dmr/security/zy.go
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+// This is a mirror of golang.org/x/crypto/internal/subtle.
+package security
+
+import "unsafe"
+
+// AnyOverlap reports whether x and y share memory at any (not necessarily
+// corresponding) index. The memory beyond the slice length is ignored.
+func AnyOverlap(x, y []byte) bool {
+ return len(x) > 0 && len(y) > 0 &&
+ uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
+ uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
+}
+
+// InexactOverlap reports whether x and y share memory at any non-corresponding
+// index. The memory beyond the slice length is ignored. Note that x and y can
+// have different lengths and still not have any inexact overlap.
+//
+// InexactOverlap can be used to implement the requirements of the crypto/cipher
+// AEAD, Block, BlockMode and Stream interfaces.
+func InexactOverlap(x, y []byte) bool {
+ if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
+ return false
+ }
+ return AnyOverlap(x, y)
+}
\ No newline at end of file
diff --git a/dmr/security/zz.go b/dmr/security/zz.go
new file mode 100644
index 0000000..45b2c1a
--- /dev/null
+++ b/dmr/security/zz.go
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package security
+
+type Cipher interface {
+ Encrypt(plaintext []byte, genDigest bool) []byte
+ Decrypt(ciphertext []byte, checkDigest bool) ([]byte, error)
+}
diff --git a/dmr/security/zza.go b/dmr/security/zza.go
new file mode 100644
index 0000000..92062ce
--- /dev/null
+++ b/dmr/security/zza.go
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package security
+
+import (
+ "crypto/rand"
+ "errors"
+ "io"
+ "math/big"
+)
+
+type dhGroup struct {
+ p *big.Int
+ g *big.Int
+}
+
+func newDhGroup(prime, generator *big.Int) *dhGroup {
+ return &dhGroup{
+ p: prime,
+ g: generator,
+ }
+}
+
+func (dg *dhGroup) P() *big.Int {
+ p := new(big.Int)
+ p.Set(dg.p)
+ return p
+}
+
+func (dg *dhGroup) G() *big.Int {
+ g := new(big.Int)
+ g.Set(dg.g)
+ return g
+}
+
+// 生成本地公私钥
+func (dg *dhGroup) GeneratePrivateKey(randReader io.Reader) (key *DhKey, err error) {
+ if randReader == nil {
+ randReader = rand.Reader
+ }
+ // 0 < x < p
+ x, err := rand.Int(randReader, dg.p)
+ if err != nil {
+ return
+ }
+ zero := big.NewInt(0)
+ for x.Cmp(zero) == 0 {
+ x, err = rand.Int(randReader, dg.p)
+ if err != nil {
+ return
+ }
+ }
+ key = new(DhKey)
+ key.x = x
+
+ // y = g ^ x mod p
+ key.y = new(big.Int).Exp(dg.g, x, dg.p)
+ key.group = dg
+ return
+}
+
+func (dg *dhGroup) ComputeKey(pubkey *DhKey, privkey *DhKey) (kye *DhKey, err error) {
+ if dg.p == nil {
+ err = errors.New("DH: invalid group")
+ return
+ }
+ if pubkey.y == nil {
+ err = errors.New("DH: invalid public key")
+ return
+ }
+ if pubkey.y.Sign() <= 0 || pubkey.y.Cmp(dg.p) >= 0 {
+ err = errors.New("DH parameter out of bounds")
+ return
+ }
+ if privkey.x == nil {
+ err = errors.New("DH: invalid private key")
+ return
+ }
+ k := new(big.Int).Exp(pubkey.y, privkey.x, dg.p)
+ key := new(DhKey)
+ key.y = k
+ key.group = dg
+ return
+}
diff --git a/dmr/security/zzb.go b/dmr/security/zzb.go
new file mode 100644
index 0000000..f9af994
--- /dev/null
+++ b/dmr/security/zzb.go
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package security
+
+import "math/big"
+
+type DhKey struct {
+ x *big.Int
+ y *big.Int
+ group *dhGroup
+}
+
+func newPublicKey(s []byte) *DhKey {
+ key := new(DhKey)
+ key.y = new(big.Int).SetBytes(s)
+ return key
+}
+
+func (dk *DhKey) GetX() *big.Int {
+ x := new(big.Int)
+ x.Set(dk.x)
+ return x
+}
+
+func (dk *DhKey) GetY() *big.Int {
+ y := new(big.Int)
+ y.Set(dk.y)
+ return y
+}
+
+func (dk *DhKey) GetYBytes() []byte {
+ if dk.y == nil {
+ return nil
+ }
+ if dk.group != nil {
+ blen := (dk.group.p.BitLen() + 7) / 8
+ ret := make([]byte, blen)
+ copyWithLeftPad(ret, dk.y.Bytes())
+ return ret
+ }
+ return dk.y.Bytes()
+}
+
+func (dk *DhKey) GetYString() string {
+ if dk.y == nil {
+ return ""
+ }
+ return dk.y.String()
+}
+
+func (dk *DhKey) IsPrivateKey() bool {
+ return dk.x != nil
+}
+
+func copyWithLeftPad(dest, src []byte) {
+ numPaddingBytes := len(dest) - len(src)
+ for i := 0; i < numPaddingBytes; i++ {
+ dest[i] = 0
+ }
+ copy(dest[:numPaddingBytes], src)
+}
diff --git a/dmr/security/zzc.go b/dmr/security/zzc.go
new file mode 100644
index 0000000..3841d68
--- /dev/null
+++ b/dmr/security/zzc.go
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+// go官方没有实现ecb加密模式
+package security
+
+import (
+ "crypto/cipher"
+)
+
+type ecb struct {
+ b cipher.Block
+ blockSize int
+}
+
+func newECB(b cipher.Block) *ecb {
+ return &ecb {
+ b: b,
+ blockSize: b.BlockSize(),
+ }
+}
+
+type ecbEncrypter ecb
+
+func NewECBEncrypter(b cipher.Block) cipher.BlockMode {
+ return (*ecbEncrypter)(newECB(b))
+}
+
+func (x *ecbEncrypter) BlockSize() int { return x.blockSize }
+
+func (x *ecbEncrypter) CryptBlocks(dst, src []byte) {
+ if len(src)%x.blockSize != 0 {
+ panic("dm/security: input not full blocks")
+ }
+ if len(dst) < len(src) {
+ panic("dm/security: output smaller than input")
+ }
+ if InexactOverlap(dst[:len(src)], src) {
+ panic("dm/security: invalid buffer overlap")
+ }
+ for bs, be := 0, x.blockSize; bs < len(src); bs, be = bs + x.blockSize, be + x.blockSize {
+ x.b.Encrypt(dst[bs:be], src[bs:be])
+ }
+}
+
+type ecbDecrypter ecb
+
+func NewECBDecrypter(b cipher.Block) cipher.BlockMode {
+ return (*ecbDecrypter)(newECB(b))
+}
+
+func (x *ecbDecrypter) BlockSize() int { return x.blockSize }
+
+func (x *ecbDecrypter) CryptBlocks(dst, src []byte) {
+ if len(src)%x.blockSize != 0 {
+ panic("dm/security: input not full blocks")
+ }
+ if len(dst) < len(src) {
+ panic("dm/security: output smaller than input")
+ }
+ if InexactOverlap(dst[:len(src)], src) {
+ panic("dm/security: invalid buffer overlap")
+ }
+ for bs, be := 0, x.blockSize; bs < len(src); bs, be = bs + x.blockSize, be + x.blockSize {
+ x.b.Decrypt(dst[bs:be], src[bs:be])
+ }
+}
diff --git a/dmr/security/zzd.go b/dmr/security/zzd.go
new file mode 100644
index 0000000..bedbc54
--- /dev/null
+++ b/dmr/security/zzd.go
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package security
+
+import (
+ "math/big"
+)
+
+const (
+ DH_KEY_LENGTH int = 64
+ /* 低7位用于保存分组加密算法中的工作模式 */
+ WORK_MODE_MASK int = 0x007f
+ ECB_MODE int = 0x1
+ CBC_MODE int = 0x2
+ CFB_MODE int = 0x4
+ OFB_MODE int = 0x8
+ /* 高位保存加密算法 */
+ ALGO_MASK int = 0xff80
+ DES int = 0x0080
+ DES3 int = 0x0100
+ AES128 int = 0x0200
+ AES192 int = 0x0400
+ AES256 int = 0x0800
+ RC4 int = 0x1000
+ MD5 int = 0x1100
+
+ // 用户名密码加密算法
+ DES_CFB int = 132
+ // 消息加密摘要长度
+ MD5_DIGEST_SIZE int = 16
+
+ MIN_EXTERNAL_CIPHER_ID int = 5000
+)
+
+var dhParaP = "C009D877BAF5FAF416B7F778E6115DCB90D65217DCC2F08A9DFCB5A192C593EBAB02929266B8DBFC2021039FDBD4B7FDE2B996E00008F57AE6EFB4ED3F17B6D3"
+var dhParaG = "5"
+var defaultIV = []byte{0x20, 0x21, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
+ 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
+ 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x20}
+var p *big.Int
+var g *big.Int
+
+func NewClientKeyPair() (key *DhKey, err error) {
+ p, _ = new(big.Int).SetString(dhParaP, 16)
+ g, _ = new(big.Int).SetString(dhParaG, 16)
+ dhGroup := newDhGroup(p, g)
+ key, err = dhGroup.GeneratePrivateKey(nil)
+ if err != nil {
+ return nil, err
+ }
+ return key, nil
+}
+
+func ComputeSessionKey(clientPrivKey *DhKey, serverPubKey []byte) []byte {
+ serverKeyX := bytes2Bn(serverPubKey)
+ clientPrivKeyX := clientPrivKey.GetX()
+ sessionKeyBN := serverKeyX.Exp(serverKeyX, clientPrivKeyX, p)
+ return Bn2Bytes(sessionKeyBN, 0)
+}
+
+func bytes2Bn(bnBytesSrc []byte) *big.Int {
+ if bnBytesSrc == nil {
+ return nil
+ }
+ if bnBytesSrc[0] == 0 {
+ return new(big.Int).SetBytes(bnBytesSrc)
+ }
+ validBytesCount := len(bnBytesSrc) + 1
+ bnBytesTo := make([]byte, validBytesCount)
+ bnBytesTo[0] = 0
+ copy(bnBytesTo[1:validBytesCount], bnBytesSrc)
+ return new(big.Int).SetBytes(bnBytesTo)
+}
+
+func Bn2Bytes(bn *big.Int, bnLen int) []byte {
+ var bnBytesSrc, bnBytesTemp, bnBytesTo []byte
+ var leading_zero_count int
+ validBytesCount := 0
+ if bn == nil {
+ return nil
+ }
+ bnBytesSrc = bn.Bytes()
+
+ // 去除首位0
+ if bnBytesSrc[0] != 0 {
+ bnBytesTemp = bnBytesSrc
+ validBytesCount = len(bnBytesTemp)
+ } else {
+ validBytesCount = len(bnBytesSrc) - 1
+ bnBytesTemp = make([]byte, validBytesCount)
+ copy(bnBytesTemp, bnBytesSrc[1:validBytesCount+1])
+ }
+
+ if bnLen == 0 {
+ leading_zero_count = 0
+ } else {
+ leading_zero_count = bnLen - validBytesCount
+ }
+ // 如果位数不足DH_KEY_LENGTH则在前面补0
+ if leading_zero_count > 0 {
+ bnBytesTo = make([]byte, DH_KEY_LENGTH)
+ i := 0
+ for i = 0; i < leading_zero_count; i++ {
+ bnBytesTo[i] = 0
+ }
+ copy(bnBytesTo[i:i+validBytesCount], bnBytesTemp)
+ } else {
+ bnBytesTo = bnBytesTemp
+ }
+ return bnBytesTo
+}
diff --git a/dmr/security/zze.go b/dmr/security/zze.go
new file mode 100644
index 0000000..4dcf7f5
--- /dev/null
+++ b/dmr/security/zze.go
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package security
+
+import (
+ "bytes"
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/des"
+ "crypto/md5"
+ "crypto/rc4"
+ "errors"
+ "reflect"
+)
+
+type SymmCipher struct {
+ encryptCipher interface{} //cipher.BlockMode | cipher.Stream
+ decryptCipher interface{} //cipher.BlockMode | cipher.Stream
+ key []byte
+ block cipher.Block // 分组加密算法
+ algorithmType int
+ workMode int
+ needPadding bool
+}
+
+func NewSymmCipher(algorithmID int, key []byte) (SymmCipher, error) {
+ var sc SymmCipher
+ var err error
+ sc.key = key
+ sc.algorithmType = algorithmID & ALGO_MASK
+ sc.workMode = algorithmID & WORK_MODE_MASK
+ switch sc.algorithmType {
+ case AES128:
+ if sc.block, err = aes.NewCipher(key[:16]); err != nil {
+ return sc, err
+ }
+ case AES192:
+ if sc.block, err = aes.NewCipher(key[:24]); err != nil {
+ return sc, err
+ }
+ case AES256:
+ if sc.block, err = aes.NewCipher(key[:32]); err != nil {
+ return sc, err
+ }
+ case DES:
+ if sc.block, err = des.NewCipher(key[:8]); err != nil {
+ return sc, err
+ }
+ case DES3:
+ var tripleDESKey []byte
+ tripleDESKey = append(tripleDESKey, key[:16]...)
+ tripleDESKey = append(tripleDESKey, key[:8]...)
+ if sc.block, err = des.NewTripleDESCipher(tripleDESKey); err != nil {
+ return sc, err
+ }
+ case RC4:
+ if sc.encryptCipher, err = rc4.NewCipher(key[:16]); err != nil {
+ return sc, err
+ }
+ if sc.decryptCipher, err = rc4.NewCipher(key[:16]); err != nil {
+ return sc, err
+ }
+ return sc, nil
+ default:
+ return sc, errors.New("invalidCipher")
+ }
+ blockSize := sc.block.BlockSize()
+ if sc.encryptCipher, err = sc.getEncrypter(sc.workMode, sc.block, defaultIV[:blockSize]); err != nil {
+ return sc, err
+ }
+ if sc.decryptCipher, err = sc.getDecrypter(sc.workMode, sc.block, defaultIV[:blockSize]); err != nil {
+ return sc, err
+ }
+ return sc, nil
+}
+
+func (sc SymmCipher) Encrypt(plaintext []byte, genDigest bool) []byte {
+ // 执行过加密后,IV值变了,需要重新初始化encryptCipher对象(因为没有类似resetIV的方法)
+ if sc.algorithmType != RC4 {
+ sc.encryptCipher, _ = sc.getEncrypter(sc.workMode, sc.block, defaultIV[:sc.block.BlockSize()])
+ } else {
+ sc.encryptCipher, _ = rc4.NewCipher(sc.key[:16])
+ }
+ // 填充
+ var paddingtext = make([]byte, len(plaintext))
+ copy(paddingtext, plaintext)
+ if sc.needPadding {
+ paddingtext = pkcs5Padding(paddingtext)
+ }
+
+ ret := make([]byte, len(paddingtext))
+
+ if v, ok := sc.encryptCipher.(cipher.Stream); ok {
+ v.XORKeyStream(ret, paddingtext)
+ } else if v, ok := sc.encryptCipher.(cipher.BlockMode); ok {
+ v.CryptBlocks(ret, paddingtext)
+ }
+
+ // md5摘要
+ if genDigest {
+ digest := md5.Sum(plaintext)
+ encrypt := ret
+ ret = make([]byte, len(encrypt)+len(digest))
+ copy(ret[:len(encrypt)], encrypt)
+ copy(ret[len(encrypt):], digest[:])
+ }
+ return ret
+}
+
+func (sc SymmCipher) Decrypt(ciphertext []byte, checkDigest bool) ([]byte, error) {
+ // 执行过解密后,IV值变了,需要重新初始化decryptCipher对象(因为没有类似resetIV的方法)
+ if sc.algorithmType != RC4 {
+ sc.decryptCipher, _ = sc.getDecrypter(sc.workMode, sc.block, defaultIV[:sc.block.BlockSize()])
+ } else {
+ sc.decryptCipher, _ = rc4.NewCipher(sc.key[:16])
+ }
+ var ret []byte
+ if checkDigest {
+ var digest = ciphertext[len(ciphertext)-MD5_DIGEST_SIZE:]
+ ret = ciphertext[:len(ciphertext)-MD5_DIGEST_SIZE]
+ ret = sc.decrypt(ret)
+ var msgDigest = md5.Sum(ret)
+ if !reflect.DeepEqual(msgDigest[:], digest) {
+ return nil, errors.New("Decrypt failed/Digest not match\n")
+ }
+ } else {
+ ret = sc.decrypt(ciphertext)
+ }
+ return ret, nil
+}
+
+func (sc SymmCipher) decrypt(ciphertext []byte) []byte {
+ ret := make([]byte, len(ciphertext))
+ if v, ok := sc.decryptCipher.(cipher.Stream); ok {
+ v.XORKeyStream(ret, ciphertext)
+ } else if v, ok := sc.decryptCipher.(cipher.BlockMode); ok {
+ v.CryptBlocks(ret, ciphertext)
+ }
+ // 去除填充
+ if sc.needPadding {
+ ret = pkcs5UnPadding(ret)
+ }
+ return ret
+}
+
+func (sc *SymmCipher) getEncrypter(workMode int, block cipher.Block, iv []byte) (ret interface{}, err error) {
+ switch workMode {
+ case ECB_MODE:
+ ret = NewECBEncrypter(block)
+ sc.needPadding = true
+ case CBC_MODE:
+ ret = cipher.NewCBCEncrypter(block, iv)
+ sc.needPadding = true
+ case CFB_MODE:
+ ret = cipher.NewCFBEncrypter(block, iv)
+ sc.needPadding = false
+ case OFB_MODE:
+ ret = cipher.NewOFB(block, iv)
+ sc.needPadding = false
+ default:
+ err = errors.New("invalidCipherMode")
+ }
+ return
+}
+
+func (sc *SymmCipher) getDecrypter(workMode int, block cipher.Block, iv []byte) (ret interface{}, err error) {
+ switch workMode {
+ case ECB_MODE:
+ ret = NewECBDecrypter(block)
+ sc.needPadding = true
+ case CBC_MODE:
+ ret = cipher.NewCBCDecrypter(block, iv)
+ sc.needPadding = true
+ case CFB_MODE:
+ ret = cipher.NewCFBDecrypter(block, iv)
+ sc.needPadding = false
+ case OFB_MODE:
+ ret = cipher.NewOFB(block, iv)
+ sc.needPadding = false
+ default:
+ err = errors.New("invalidCipherMode")
+ }
+ return
+}
+
+
+// 补码
+func pkcs77Padding(ciphertext []byte, blocksize int) []byte {
+ padding := blocksize - len(ciphertext)%blocksize
+ padtext := bytes.Repeat([]byte{byte(padding)}, padding)
+ return append(ciphertext, padtext...)
+}
+
+// 去码
+func pkcs7UnPadding(origData []byte) []byte {
+ length := len(origData)
+ unpadding := int(origData[length-1])
+ return origData[:length-unpadding]
+}
+
+// 补码
+func pkcs5Padding(ciphertext []byte) []byte {
+ return pkcs77Padding(ciphertext, 8)
+}
+
+// 去码
+func pkcs5UnPadding(ciphertext []byte) []byte {
+ return pkcs7UnPadding(ciphertext)
+}
\ No newline at end of file
diff --git a/dmr/security/zzf.go b/dmr/security/zzf.go
new file mode 100644
index 0000000..8710712
--- /dev/null
+++ b/dmr/security/zzf.go
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package security
+
+import (
+ "crypto/md5"
+ "errors"
+ "fmt"
+ "reflect"
+ "unsafe"
+)
+
+type ThirdPartCipher struct {
+ encryptType int // 外部加密算法id
+ encryptName string // 外部加密算法名称
+ hashType int
+ key []byte
+ cipherCount int // 外部加密算法个数
+ //innerId int // 外部加密算法内部id
+ blockSize int // 分组块大小
+ khSize int // key/hash大小
+}
+
+func NewThirdPartCipher(encryptType int, key []byte, cipherPath string, hashType int) (ThirdPartCipher, error) {
+ var tpc = ThirdPartCipher{
+ encryptType: encryptType,
+ key: key,
+ hashType: hashType,
+ cipherCount: -1,
+ }
+ var err error
+ err = initThirdPartCipher(cipherPath)
+ if err != nil {
+ return tpc, err
+ }
+ tpc.getCount()
+ tpc.getInfo()
+ return tpc, nil
+}
+
+func (tpc *ThirdPartCipher) getCount() int {
+ if tpc.cipherCount == -1 {
+ tpc.cipherCount = cipherGetCount()
+ }
+ return tpc.cipherCount
+}
+
+func (tpc *ThirdPartCipher) getInfo() {
+ var cipher_id, ty, blk_size, kh_size int
+ //var strptr, _ = syscall.UTF16PtrFromString(tpc.encryptName)
+ var strptr *uint16 = new(uint16)
+ for i := 1; i <= tpc.getCount(); i++ {
+ cipherGetInfo(uintptr(i), uintptr(unsafe.Pointer(&cipher_id)), uintptr(unsafe.Pointer(&strptr)),
+ uintptr(unsafe.Pointer(&ty)), uintptr(unsafe.Pointer(&blk_size)), uintptr(unsafe.Pointer(&kh_size)))
+ if tpc.encryptType == cipher_id {
+ tpc.blockSize = blk_size
+ tpc.khSize = kh_size
+ tpc.encryptName = string(uintptr2bytes(uintptr(unsafe.Pointer(strptr))))
+ return
+ }
+ }
+ panic(fmt.Sprintf("ThirdPartyCipher: cipher id:%d not found", tpc.encryptType))
+}
+
+func (tpc ThirdPartCipher) Encrypt(plaintext []byte, genDigest bool) []byte {
+ var tmp_para uintptr
+ cipherEncryptInit(uintptr(tpc.encryptType), uintptr(unsafe.Pointer(&tpc.key[0])), uintptr(len(tpc.key)), tmp_para)
+
+ ciphertextLen := cipherGetCipherTextSize(uintptr(tpc.encryptType), tmp_para, uintptr(len(plaintext)))
+
+ ciphertext := make([]byte, ciphertextLen)
+ ret := cipherEncrypt(uintptr(tpc.encryptType), tmp_para, uintptr(unsafe.Pointer(&plaintext[0])), uintptr(len(plaintext)),
+ uintptr(unsafe.Pointer(&ciphertext[0])), uintptr(len(ciphertext)))
+ ciphertext = ciphertext[:ret]
+
+ cipherClean(uintptr(tpc.encryptType), tmp_para)
+ // md5摘要
+ if genDigest {
+ digest := md5.Sum(plaintext)
+ encrypt := ciphertext
+ ciphertext = make([]byte, len(encrypt)+len(digest))
+ copy(ciphertext[:len(encrypt)], encrypt)
+ copy(ciphertext[len(encrypt):], digest[:])
+ }
+ return ciphertext
+}
+
+func (tpc ThirdPartCipher) Decrypt(ciphertext []byte, checkDigest bool) ([]byte, error) {
+ var ret []byte
+ if checkDigest {
+ var digest = ciphertext[len(ciphertext)-MD5_DIGEST_SIZE:]
+ ret = ciphertext[:len(ciphertext)-MD5_DIGEST_SIZE]
+ ret = tpc.decrypt(ret)
+ var msgDigest = md5.Sum(ret)
+ if !reflect.DeepEqual(msgDigest[:], digest) {
+ return nil, errors.New("Decrypt failed/Digest not match\n")
+ }
+ } else {
+ ret = tpc.decrypt(ciphertext)
+ }
+ return ret, nil
+}
+
+func (tpc ThirdPartCipher) decrypt(ciphertext []byte) []byte {
+ var tmp_para uintptr
+
+ cipherDecryptInit(uintptr(tpc.encryptType), uintptr(unsafe.Pointer(&tpc.key[0])), uintptr(len(tpc.key)), tmp_para)
+
+ plaintext := make([]byte, len(ciphertext))
+ ret := cipherDecrypt(uintptr(tpc.encryptType), tmp_para, uintptr(unsafe.Pointer(&ciphertext[0])), uintptr(len(ciphertext)),
+ uintptr(unsafe.Pointer(&plaintext[0])), uintptr(len(plaintext)))
+ plaintext = plaintext[:ret]
+
+ cipherClean(uintptr(tpc.encryptType), tmp_para)
+ return plaintext
+}
+
+func addBufSize(buf []byte, newCap int) []byte {
+ newBuf := make([]byte, newCap)
+ copy(newBuf, buf)
+ return newBuf
+}
+
+func uintptr2bytes(p uintptr) []byte {
+ buf := make([]byte, 64)
+ i := 0
+ for b := (*byte)(unsafe.Pointer(p)); *b != 0; i++ {
+ if i > cap(buf) {
+ buf = addBufSize(buf, i * 2)
+ }
+ buf[i] = *b
+ // byte占1字节
+ p ++
+ b = (*byte)(unsafe.Pointer(p))
+ }
+ return buf[:i]
+}
diff --git a/dmr/security/zzg_darwin.go b/dmr/security/zzg_darwin.go
new file mode 100644
index 0000000..835002e
--- /dev/null
+++ b/dmr/security/zzg_darwin.go
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package security
+
+import "plugin"
+
+var (
+ dmCipherEncryptSo *plugin.Plugin
+ cipherGetCountProc plugin.Symbol
+ cipherGetInfoProc plugin.Symbol
+ cipherEncryptInitProc plugin.Symbol
+ cipherGetCipherTextSizeProc plugin.Symbol
+ cipherEncryptProc plugin.Symbol
+ cipherCleanupProc plugin.Symbol
+ cipherDecryptInitProc plugin.Symbol
+ cipherDecryptProc plugin.Symbol
+)
+
+func initThirdPartCipher(cipherPath string) (err error) {
+ if dmCipherEncryptSo, err = plugin.Open(cipherPath); err != nil {
+ return err
+ }
+ if cipherGetCountProc, err = dmCipherEncryptSo.Lookup("cipher_get_count"); err != nil {
+ return err
+ }
+ if cipherGetInfoProc, err = dmCipherEncryptSo.Lookup("cipher_get_info"); err != nil {
+ return err
+ }
+ if cipherEncryptInitProc, err = dmCipherEncryptSo.Lookup("cipher_encrypt_init"); err != nil {
+ return err
+ }
+ if cipherGetCipherTextSizeProc, err = dmCipherEncryptSo.Lookup("cipher_get_cipher_text_size"); err != nil {
+ return err
+ }
+ if cipherEncryptProc, err = dmCipherEncryptSo.Lookup("cipher_encrypt"); err != nil {
+ return err
+ }
+ if cipherCleanupProc, err = dmCipherEncryptSo.Lookup("cipher_cleanup"); err != nil {
+ return err
+ }
+ if cipherDecryptInitProc, err = dmCipherEncryptSo.Lookup("cipher_decrypt_init"); err != nil {
+ return err
+ }
+ if cipherDecryptProc, err = dmCipherEncryptSo.Lookup("cipher_decrypt"); err != nil {
+ return err
+ }
+ return nil
+}
+
+func cipherGetCount() int {
+ ret := cipherGetCountProc.(func() interface{})()
+ return ret.(int)
+}
+
+func cipherGetInfo(seqno, cipherId, cipherName, _type, blkSize, khSIze uintptr) {
+ ret := cipherGetInfoProc.(func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) interface{})(seqno, cipherId, cipherName, _type, blkSize, khSIze)
+ if ret.(int) == 0 {
+ panic("ThirdPartyCipher: call cipher_get_info failed")
+ }
+}
+
+func cipherEncryptInit(cipherId, key, keySize, cipherPara uintptr) {
+ ret := cipherEncryptInitProc.(func(uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, key, keySize, cipherPara)
+ if ret.(int) == 0 {
+ panic("ThirdPartyCipher: call cipher_encrypt_init failed")
+ }
+}
+
+func cipherGetCipherTextSize(cipherId, cipherPara, plainTextSize uintptr) uintptr {
+ ciphertextLen := cipherGetCipherTextSizeProc.(func(uintptr, uintptr, uintptr) interface{})(cipherId, cipherPara, plainTextSize)
+ return ciphertextLen.(uintptr)
+}
+
+func cipherEncrypt(cipherId, cipherPara, plainText, plainTextSize, cipherText, cipherTextBufSize uintptr) uintptr {
+ ret := cipherEncryptProc.(func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, cipherPara, plainText, plainTextSize, cipherText, cipherTextBufSize)
+ return ret.(uintptr)
+}
+
+func cipherClean(cipherId, cipherPara uintptr) {
+ cipherEncryptProc.(func(uintptr, uintptr))(cipherId, cipherPara)
+}
+
+func cipherDecryptInit(cipherId, key, keySize, cipherPara uintptr) {
+ ret := cipherDecryptInitProc.(func(uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, key, keySize, cipherPara)
+ if ret.(int) == 0 {
+ panic("ThirdPartyCipher: call cipher_decrypt_init failed")
+ }
+}
+
+func cipherDecrypt(cipherId, cipherPara, cipherText, cipherTextSize, plainText, plainTextBufSize uintptr) uintptr {
+ ret := cipherDecryptProc.(func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, cipherPara, cipherText, cipherTextSize, plainText, plainTextBufSize)
+ return ret.(uintptr)
+}
diff --git a/dmr/security/zzg_linux.go b/dmr/security/zzg_linux.go
new file mode 100644
index 0000000..835002e
--- /dev/null
+++ b/dmr/security/zzg_linux.go
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package security
+
+import "plugin"
+
+var (
+ dmCipherEncryptSo *plugin.Plugin
+ cipherGetCountProc plugin.Symbol
+ cipherGetInfoProc plugin.Symbol
+ cipherEncryptInitProc plugin.Symbol
+ cipherGetCipherTextSizeProc plugin.Symbol
+ cipherEncryptProc plugin.Symbol
+ cipherCleanupProc plugin.Symbol
+ cipherDecryptInitProc plugin.Symbol
+ cipherDecryptProc plugin.Symbol
+)
+
+func initThirdPartCipher(cipherPath string) (err error) {
+ if dmCipherEncryptSo, err = plugin.Open(cipherPath); err != nil {
+ return err
+ }
+ if cipherGetCountProc, err = dmCipherEncryptSo.Lookup("cipher_get_count"); err != nil {
+ return err
+ }
+ if cipherGetInfoProc, err = dmCipherEncryptSo.Lookup("cipher_get_info"); err != nil {
+ return err
+ }
+ if cipherEncryptInitProc, err = dmCipherEncryptSo.Lookup("cipher_encrypt_init"); err != nil {
+ return err
+ }
+ if cipherGetCipherTextSizeProc, err = dmCipherEncryptSo.Lookup("cipher_get_cipher_text_size"); err != nil {
+ return err
+ }
+ if cipherEncryptProc, err = dmCipherEncryptSo.Lookup("cipher_encrypt"); err != nil {
+ return err
+ }
+ if cipherCleanupProc, err = dmCipherEncryptSo.Lookup("cipher_cleanup"); err != nil {
+ return err
+ }
+ if cipherDecryptInitProc, err = dmCipherEncryptSo.Lookup("cipher_decrypt_init"); err != nil {
+ return err
+ }
+ if cipherDecryptProc, err = dmCipherEncryptSo.Lookup("cipher_decrypt"); err != nil {
+ return err
+ }
+ return nil
+}
+
+func cipherGetCount() int {
+ ret := cipherGetCountProc.(func() interface{})()
+ return ret.(int)
+}
+
+func cipherGetInfo(seqno, cipherId, cipherName, _type, blkSize, khSIze uintptr) {
+ ret := cipherGetInfoProc.(func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) interface{})(seqno, cipherId, cipherName, _type, blkSize, khSIze)
+ if ret.(int) == 0 {
+ panic("ThirdPartyCipher: call cipher_get_info failed")
+ }
+}
+
+func cipherEncryptInit(cipherId, key, keySize, cipherPara uintptr) {
+ ret := cipherEncryptInitProc.(func(uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, key, keySize, cipherPara)
+ if ret.(int) == 0 {
+ panic("ThirdPartyCipher: call cipher_encrypt_init failed")
+ }
+}
+
+func cipherGetCipherTextSize(cipherId, cipherPara, plainTextSize uintptr) uintptr {
+ ciphertextLen := cipherGetCipherTextSizeProc.(func(uintptr, uintptr, uintptr) interface{})(cipherId, cipherPara, plainTextSize)
+ return ciphertextLen.(uintptr)
+}
+
+func cipherEncrypt(cipherId, cipherPara, plainText, plainTextSize, cipherText, cipherTextBufSize uintptr) uintptr {
+ ret := cipherEncryptProc.(func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, cipherPara, plainText, plainTextSize, cipherText, cipherTextBufSize)
+ return ret.(uintptr)
+}
+
+func cipherClean(cipherId, cipherPara uintptr) {
+ cipherEncryptProc.(func(uintptr, uintptr))(cipherId, cipherPara)
+}
+
+func cipherDecryptInit(cipherId, key, keySize, cipherPara uintptr) {
+ ret := cipherDecryptInitProc.(func(uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, key, keySize, cipherPara)
+ if ret.(int) == 0 {
+ panic("ThirdPartyCipher: call cipher_decrypt_init failed")
+ }
+}
+
+func cipherDecrypt(cipherId, cipherPara, cipherText, cipherTextSize, plainText, plainTextBufSize uintptr) uintptr {
+ ret := cipherDecryptProc.(func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) interface{})(cipherId, cipherPara, cipherText, cipherTextSize, plainText, plainTextBufSize)
+ return ret.(uintptr)
+}
diff --git a/dmr/security/zzh_windows.go b/dmr/security/zzh_windows.go
new file mode 100644
index 0000000..2fa6861
--- /dev/null
+++ b/dmr/security/zzh_windows.go
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package security
+
+import (
+ "syscall"
+)
+
+var (
+ dmCipherEncryptDLL *syscall.LazyDLL
+ cipherGetCountProc *syscall.LazyProc
+ cipherGetInfoProc *syscall.LazyProc
+ cipherEncryptInitProc *syscall.LazyProc
+ cipherGetCipherTextSizeProc *syscall.LazyProc
+ cipherEncryptProc *syscall.LazyProc
+ cipherCleanupProc *syscall.LazyProc
+ cipherDecryptInitProc *syscall.LazyProc
+ cipherDecryptProc *syscall.LazyProc
+)
+
+func initThirdPartCipher(cipherPath string) error {
+ dmCipherEncryptDLL = syscall.NewLazyDLL(cipherPath)
+ if err := dmCipherEncryptDLL.Load(); err != nil {
+ return err
+ }
+ cipherGetCountProc = dmCipherEncryptDLL.NewProc("cipher_get_count")
+ cipherGetInfoProc = dmCipherEncryptDLL.NewProc("cipher_get_info")
+ cipherEncryptInitProc = dmCipherEncryptDLL.NewProc("cipher_encrypt_init")
+ cipherGetCipherTextSizeProc = dmCipherEncryptDLL.NewProc("cipher_get_cipher_text_size")
+ cipherEncryptProc = dmCipherEncryptDLL.NewProc("cipher_encrypt")
+ cipherCleanupProc = dmCipherEncryptDLL.NewProc("cipher_cleanup")
+ cipherDecryptInitProc = dmCipherEncryptDLL.NewProc("cipher_decrypt_init")
+ cipherDecryptProc = dmCipherEncryptDLL.NewProc("cipher_decrypt")
+ return nil
+}
+
+func cipherGetCount() int {
+ ret, _, _ := cipherGetCountProc.Call()
+ return int(ret)
+}
+
+func cipherGetInfo(seqno, cipherId, cipherName, _type, blkSize, khSIze uintptr) {
+ ret, _, _ := cipherGetInfoProc.Call(seqno, cipherId, cipherName, _type, blkSize, khSIze)
+ if ret == 0 {
+ panic("ThirdPartyCipher: call cipher_get_info failed")
+ }
+}
+
+func cipherEncryptInit(cipherId, key, keySize, cipherPara uintptr) {
+ ret, _, _ := cipherEncryptInitProc.Call(cipherId, key, keySize, cipherPara)
+ if ret == 0 {
+ panic("ThirdPartyCipher: call cipher_encrypt_init failed")
+ }
+}
+
+func cipherGetCipherTextSize(cipherId, cipherPara, plainTextSize uintptr) uintptr {
+ ciphertextLen, _, _ := cipherGetCipherTextSizeProc.Call(cipherId, cipherPara, plainTextSize)
+ return ciphertextLen
+}
+
+func cipherEncrypt(cipherId, cipherPara, plainText, plainTextSize, cipherText, cipherTextBufSize uintptr) uintptr {
+ ret, _, _ := cipherEncryptProc.Call(cipherId, cipherPara, plainText, plainTextSize, cipherText, cipherTextBufSize)
+ return ret
+}
+
+func cipherClean(cipherId, cipherPara uintptr) {
+ _, _, _ = cipherCleanupProc.Call(cipherId, cipherPara)
+}
+
+func cipherDecryptInit(cipherId, key, keySize, cipherPara uintptr) {
+ ret, _, _ := cipherDecryptInitProc.Call(cipherId, key, keySize, cipherPara)
+ if ret == 0 {
+ panic("ThirdPartyCipher: call cipher_decrypt_init failed")
+ }
+}
+
+func cipherDecrypt(cipherId, cipherPara, cipherText, cipherTextSize, plainText, plainTextBufSize uintptr) uintptr {
+ ret, _, _ := cipherDecryptProc.Call(cipherId, cipherPara, cipherText, cipherTextSize, plainText, plainTextBufSize)
+ return ret
+}
diff --git a/dmr/security/zzi.go b/dmr/security/zzi.go
new file mode 100644
index 0000000..5b8b6f9
--- /dev/null
+++ b/dmr/security/zzi.go
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package security
+
+import (
+ "crypto/tls"
+ "errors"
+ "flag"
+ "net"
+ "os"
+)
+
+var dmHome = flag.String("DM_HOME", "", "Where DMDB installed")
+
+func NewTLSFromTCP(conn *net.TCPConn, sslCertPath string, sslKeyPath string, user string) (*tls.Conn, error) {
+ if sslCertPath == "" && sslKeyPath == "" {
+ flag.Parse()
+ separator := string(os.PathSeparator)
+ if *dmHome != "" {
+ sslCertPath = *dmHome + separator + "bin" + separator + "client_ssl" + separator +
+ user + separator + "client-cert.pem"
+ sslKeyPath = *dmHome + separator + "bin" + separator + "client_ssl" + separator +
+ user + separator + "client-key.pem"
+ } else {
+ return nil, errors.New("sslCertPath and sslKeyPath can not be empty!")
+ }
+ }
+ cer, err := tls.LoadX509KeyPair(sslCertPath, sslKeyPath)
+ if err != nil {
+ return nil, err
+ }
+ conf := &tls.Config{
+ InsecureSkipVerify: true,
+ Certificates: []tls.Certificate{cer},
+ }
+ tlsConn := tls.Client(conn, conf)
+ if err := tlsConn.Handshake(); err != nil {
+ return nil, err
+ }
+ return tlsConn, nil
+}
\ No newline at end of file
diff --git a/dmr/t.go b/dmr/t.go
new file mode 100644
index 0000000..f602d86
--- /dev/null
+++ b/dmr/t.go
@@ -0,0 +1,505 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "database/sql/driver"
+ "io"
+ "reflect"
+ "strings"
+)
+
+type DmRows struct {
+ filterable
+ CurrentRows *innerRows
+ finish func()
+}
+
+func (r *DmRows) Columns() []string {
+ if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
+ return nil
+ }
+ if len(r.filterChain.filters) == 0 {
+ return r.columns()
+ }
+ return r.filterChain.reset().DmRowsColumns(r)
+}
+
+func (r *DmRows) Close() error {
+ if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
+ return err
+ }
+ if len(r.filterChain.filters) == 0 {
+ return r.close()
+ }
+ return r.filterChain.reset().DmRowsClose(r)
+}
+
+func (r *DmRows) Next(dest []driver.Value) error {
+ if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
+ return err
+ }
+ if len(r.filterChain.filters) == 0 {
+ return r.next(dest)
+ }
+ return r.filterChain.reset().DmRowsNext(r, dest)
+}
+
+func (r *DmRows) HasNextResultSet() bool {
+ if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
+ return false
+ }
+ if len(r.filterChain.filters) == 0 {
+ return r.hasNextResultSet()
+ }
+ return r.filterChain.reset().DmRowsHasNextResultSet(r)
+}
+
+func (r *DmRows) NextResultSet() error {
+ if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
+ return err
+ }
+ if len(r.filterChain.filters) == 0 {
+ return r.nextResultSet()
+ }
+ return r.filterChain.reset().DmRowsNextResultSet(r)
+}
+
+func (r *DmRows) ColumnTypeScanType(index int) reflect.Type {
+ if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
+ return nil
+ }
+ if len(r.filterChain.filters) == 0 {
+ return r.columnTypeScanType(index)
+ }
+ return r.filterChain.reset().DmRowsColumnTypeScanType(r, index)
+}
+
+func (r *DmRows) ColumnTypeDatabaseTypeName(index int) string {
+ if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
+ return ""
+ }
+ if len(r.filterChain.filters) == 0 {
+ return r.columnTypeDatabaseTypeName(index)
+ }
+ return r.filterChain.reset().DmRowsColumnTypeDatabaseTypeName(r, index)
+}
+
+func (r *DmRows) ColumnTypeLength(index int) (length int64, ok bool) {
+ if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
+ return -1, false
+ }
+ if len(r.filterChain.filters) == 0 {
+ return r.columnTypeLength(index)
+ }
+ return r.filterChain.reset().DmRowsColumnTypeLength(r, index)
+}
+
+func (r *DmRows) ColumnTypeNullable(index int) (nullable, ok bool) {
+ if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
+ return false, false
+ }
+ if len(r.filterChain.filters) == 0 {
+ return r.columnTypeNullable(index)
+ }
+ return r.filterChain.reset().DmRowsColumnTypeNullable(r, index)
+}
+
+func (r *DmRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
+ if err := r.CurrentRows.dmStmt.checkClosed(); err != nil {
+ return -1, -1, false
+ }
+ if len(r.filterChain.filters) == 0 {
+ return r.columnTypePrecisionScale(index)
+ }
+ return r.filterChain.reset().DmRowsColumnTypePrecisionScale(r, index)
+}
+
+func (rows *DmRows) columns() []string {
+ return rows.CurrentRows.Columns()
+}
+
+func (rows *DmRows) close() error {
+ if f := rows.finish; f != nil {
+ f()
+ rows.finish = nil
+ }
+ return rows.CurrentRows.Close()
+}
+
+func (rows *DmRows) next(dest []driver.Value) error {
+ return rows.CurrentRows.Next(dest)
+}
+
+func (rows *DmRows) hasNextResultSet() bool {
+ return rows.CurrentRows.HasNextResultSet()
+}
+
+func (rows *DmRows) nextResultSet() error {
+ return rows.CurrentRows.NextResultSet()
+}
+
+func (rows *DmRows) columnTypeScanType(index int) reflect.Type {
+ return rows.CurrentRows.ColumnTypeScanType(index)
+}
+
+func (rows *DmRows) columnTypeDatabaseTypeName(index int) string {
+ return rows.CurrentRows.ColumnTypeDatabaseTypeName(index)
+}
+
+func (rows *DmRows) columnTypeLength(index int) (length int64, ok bool) {
+ return rows.CurrentRows.ColumnTypeLength(index)
+}
+
+func (rows *DmRows) columnTypeNullable(index int) (nullable, ok bool) {
+ return rows.CurrentRows.ColumnTypeNullable(index)
+}
+
+func (rows *DmRows) columnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
+ return rows.CurrentRows.ColumnTypePrecisionScale(index)
+}
+
+type innerRows struct {
+ dmStmt *DmStatement
+
+ id int16
+
+ columns []column
+
+ datas [][][]byte
+
+ datasOffset int
+
+ datasStartPos int64
+
+ currentPos int64
+
+ totalRowCount int64
+
+ fetchSize int
+
+ sizeOfRow int
+
+ isBdta bool
+
+ nextExecInfo *execRetInfo
+
+ next *innerRows
+
+ dmRows *DmRows
+
+ closed bool
+}
+
+func (innerRows *innerRows) checkClosed() error {
+ if innerRows.closed {
+ return ECGO_RESULTSET_CLOSED.throw()
+ }
+ return nil
+}
+
+func (innerRows *innerRows) Columns() []string {
+ err := innerRows.checkClosed()
+ if err != nil {
+ panic(err)
+ }
+
+ columnNames := make([]string, len(innerRows.columns))
+ nameCase := innerRows.dmStmt.dmConn.dmConnector.columnNameCase
+
+ for i, column := range innerRows.columns {
+ if nameCase == COLUMN_NAME_NATURAL_CASE {
+ columnNames[i] = column.name
+ } else if nameCase == COLUMN_NAME_UPPER_CASE {
+ columnNames[i] = strings.ToUpper(column.name)
+ } else if nameCase == COLUMN_NAME_LOWER_CASE {
+ columnNames[i] = strings.ToLower(column.name)
+ } else {
+ columnNames[i] = column.name
+ }
+ }
+
+ return columnNames
+}
+
+func (innerRows *innerRows) Close() error {
+ if innerRows.closed {
+ return nil
+ }
+
+ innerRows.closed = true
+
+ if innerRows.dmStmt.innerUsed {
+ innerRows.dmStmt.close()
+ } else {
+ delete(innerRows.dmStmt.rsMap, innerRows.id)
+ }
+
+ innerRows.dmStmt = nil
+
+ return nil
+}
+
+func (innerRows *innerRows) Next(dest []driver.Value) error {
+ err := innerRows.checkClosed()
+ if err != nil {
+ return err
+ }
+
+ if innerRows.totalRowCount == 0 || innerRows.currentPos >= innerRows.totalRowCount {
+ return io.EOF
+ }
+
+ if innerRows.currentPos+1 == innerRows.totalRowCount {
+ innerRows.currentPos++
+ innerRows.datasOffset++
+ return io.EOF
+ }
+
+ if innerRows.currentPos+1 < innerRows.datasStartPos || innerRows.currentPos+1 >= innerRows.datasStartPos+int64(len(innerRows.datas)) {
+ if innerRows.fetchData(innerRows.currentPos + 1) {
+ innerRows.currentPos++
+ err := innerRows.getRowData(dest)
+ if err != nil {
+ return err
+ }
+ } else {
+ innerRows.currentPos++
+ innerRows.datasOffset++
+ return io.EOF
+ }
+ } else {
+ innerRows.currentPos++
+ innerRows.datasOffset++
+ err := innerRows.getRowData(dest)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (innerRows *innerRows) HasNextResultSet() bool {
+ err := innerRows.checkClosed()
+ if err != nil {
+ panic(err)
+ }
+
+ if innerRows.nextExecInfo != nil {
+ return innerRows.nextExecInfo.hasResultSet
+ }
+
+ innerRows.nextExecInfo, err = innerRows.dmStmt.dmConn.Access.Dm_build_449(innerRows.dmStmt, 0)
+ if err != nil {
+ panic(err)
+ }
+
+ if innerRows.nextExecInfo.hasResultSet {
+ innerRows.next = newInnerRows(innerRows.id+1, innerRows.dmStmt, innerRows.nextExecInfo)
+ return true
+ }
+
+ return false
+}
+
+func (innerRows *innerRows) NextResultSet() error {
+ err := innerRows.checkClosed()
+ if err != nil {
+ return err
+ }
+
+ if innerRows.nextExecInfo == nil {
+ innerRows.HasNextResultSet()
+ }
+
+ if innerRows.next == nil {
+ return io.EOF
+ }
+
+ innerRows.next.dmRows = innerRows.dmRows
+ innerRows.dmRows.CurrentRows = innerRows.next
+ return nil
+}
+
+func (innerRows *innerRows) ColumnTypeScanType(index int) reflect.Type {
+ err := innerRows.checkClosed()
+ if err != nil {
+ panic(err)
+ }
+ column := innerRows.checkIndex(index)
+ return column.ScanType()
+}
+
+func (innerRows *innerRows) ColumnTypeDatabaseTypeName(index int) string {
+ err := innerRows.checkClosed()
+ if err != nil {
+ panic(err)
+ }
+ column := innerRows.checkIndex(index)
+ return column.typeName
+}
+
+func (innerRows *innerRows) ColumnTypeLength(index int) (length int64, ok bool) {
+ err := innerRows.checkClosed()
+ if err != nil {
+ panic(err)
+ }
+ column := innerRows.checkIndex(index)
+ return column.Length()
+}
+
+func (innerRows *innerRows) ColumnTypeNullable(index int) (nullable, ok bool) {
+ err := innerRows.checkClosed()
+ if err != nil {
+ panic(err)
+ }
+ column := innerRows.checkIndex(index)
+ return column.nullable, true
+}
+
+func (innerRows *innerRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
+ err := innerRows.checkClosed()
+ if err != nil {
+ panic(err)
+ }
+ column := innerRows.checkIndex(index)
+ return column.PrecisionScale()
+}
+
+func newDmRows(currentRows *innerRows) *DmRows {
+ dr := new(DmRows)
+ dr.resetFilterable(¤tRows.dmStmt.filterable)
+ dr.CurrentRows = currentRows
+ dr.idGenerator = dmRowsIDGenerator
+ currentRows.dmRows = dr
+ return dr
+}
+
+func newInnerRows(id int16, stmt *DmStatement, execInfo *execRetInfo) *innerRows {
+ rows := new(innerRows)
+ rows.id = id
+ rows.dmStmt = stmt
+ rows.columns = stmt.columns
+ rows.datas = execInfo.rsDatas
+ rows.totalRowCount = execInfo.updateCount
+ rows.isBdta = execInfo.rsBdta
+ rows.fetchSize = stmt.fetchSize
+
+ if len(execInfo.rsDatas) == 0 {
+ rows.sizeOfRow = 0
+ } else {
+ rows.sizeOfRow = execInfo.rsSizeof / len(execInfo.rsDatas)
+ }
+
+ rows.currentPos = -1
+ rows.datasOffset = -1
+ rows.datasStartPos = 0
+
+ rows.nextExecInfo = nil
+ rows.next = nil
+
+ if rows.dmStmt.rsMap != nil {
+ rows.dmStmt.rsMap[rows.id] = rows
+ }
+
+ if stmt.dmConn.dmConnector.enRsCache && execInfo.rsCacheOffset > 0 &&
+ int64(len(execInfo.rsDatas)) == execInfo.updateCount {
+ rp.put(stmt, stmt.nativeSql, execInfo)
+ }
+
+ return rows
+}
+
+func newLocalInnerRows(stmt *DmStatement, columns []column, rsDatas [][][]byte) *innerRows {
+ rows := new(innerRows)
+ rows.id = 0
+ rows.dmStmt = stmt
+ rows.fetchSize = stmt.fetchSize
+
+ if columns == nil {
+ rows.columns = make([]column, 0)
+ } else {
+ rows.columns = columns
+ }
+
+ if rsDatas == nil {
+ rows.datas = make([][][]byte, 0)
+ rows.totalRowCount = 0
+ } else {
+ rows.datas = rsDatas
+ rows.totalRowCount = int64(len(rsDatas))
+ }
+
+ rows.isBdta = false
+ return rows
+}
+
+func (innerRows *innerRows) checkIndex(index int) *column {
+ if index < 0 || index > len(innerRows.columns)-1 {
+ panic(ECGO_INVALID_SEQUENCE_NUMBER)
+ }
+
+ return &innerRows.columns[index]
+}
+
+func (innerRows *innerRows) fetchData(startPos int64) bool {
+ execInfo, err := innerRows.dmStmt.dmConn.Access.Dm_build_456(innerRows, startPos)
+ if err != nil {
+ panic(err)
+ }
+
+ innerRows.totalRowCount = execInfo.updateCount
+ if execInfo.rsDatas != nil {
+ innerRows.datas = execInfo.rsDatas
+ innerRows.datasStartPos = startPos
+ innerRows.datasOffset = 0
+ return true
+ }
+
+ return false
+}
+
+func (innerRows *innerRows) getRowData(dest []driver.Value) (err error) {
+ for i, column := range innerRows.columns {
+
+ if i <= len(dest)-1 {
+ if column.colType == CURSOR {
+ var tmpExecInfo *execRetInfo
+ tmpExecInfo, err = innerRows.dmStmt.dmConn.Access.Dm_build_449(innerRows.dmStmt, 1)
+ if err != nil {
+ return err
+ }
+
+ if tmpExecInfo.hasResultSet {
+ dest[i] = newDmRows(newInnerRows(innerRows.id+1, innerRows.dmStmt, tmpExecInfo))
+ } else {
+ dest[i] = nil
+ }
+ continue
+ }
+
+ dest[i], err = column.getColumnData(innerRows.datas[innerRows.datasOffset][i+1], innerRows.dmStmt.dmConn)
+ innerRows.columns[i].isBdta = innerRows.isBdta
+ if err != nil {
+ return err
+ }
+ } else {
+ return nil
+ }
+ }
+
+ return nil
+}
+
+func (innerRows *innerRows) getRowCount() int64 {
+ innerRows.checkClosed()
+
+ if innerRows.totalRowCount == INT64_MAX {
+ return -1
+ }
+
+ return innerRows.totalRowCount
+}
diff --git a/dmr/u.go b/dmr/u.go
new file mode 100644
index 0000000..df0599a
--- /dev/null
+++ b/dmr/u.go
@@ -0,0 +1,1078 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "container/list"
+ "context"
+ "database/sql"
+ "database/sql/driver"
+ "fmt"
+ "io"
+ "math/big"
+ "reflect"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+const (
+ BIND_IN byte = 0x01
+
+ BIND_OUT byte = 0x10
+)
+
+var rp = newRsPool()
+
+type DmStatement struct {
+ filterable
+
+ dmConn *DmConnection
+ rsMap map[int16]*innerRows
+ inUse bool
+ innerUsed bool
+
+ innerExec bool
+
+ id int32
+
+ cursorName string
+
+ readBaseColName bool
+
+ execInfo *execRetInfo
+
+ resultSetType int
+
+ resultSetConcurrency int
+
+ resultSetHoldability int
+
+ nativeSql string
+
+ maxFieldSize int
+
+ maxRows int64
+
+ escapeProcessing bool
+
+ queryTimeout int32
+
+ fetchDirection int
+
+ fetchSize int
+
+ cursorUpdateRow int64
+
+ closeOnCompletion bool
+
+ isBatch bool
+
+ closed bool
+
+ columns []column
+
+ params []parameter
+
+ paramCount int32
+
+ curRowBindIndicator []byte
+
+ preExec bool
+}
+
+type stmtPoolInfo struct {
+ id int32
+
+ cursorName string
+
+ readBaseColName bool
+}
+
+type rsPoolKey struct {
+ dbGuid string
+ currentSchema string
+ sql string
+ paramCount int
+}
+
+func newRsPoolKey(stmt *DmStatement, sql string) rsPoolKey {
+ rpk := new(rsPoolKey)
+ rpk.dbGuid = stmt.dmConn.Guid
+ rpk.currentSchema = stmt.dmConn.Schema
+ rpk.paramCount = int(stmt.paramCount)
+
+ rpk.sql = sql
+ return *rpk
+}
+
+func (key rsPoolKey) equals(destKey rsPoolKey) bool {
+ return key.dbGuid == destKey.dbGuid &&
+ key.currentSchema == destKey.currentSchema &&
+ key.sql == destKey.sql &&
+ key.paramCount == destKey.paramCount
+
+}
+
+type rsPoolValue struct {
+ m_lastChkTime int
+ m_TbIds []int32
+ m_TbTss []int64
+ execInfo *execRetInfo
+}
+
+func newRsPoolValue(execInfo *execRetInfo) rsPoolValue {
+ rpv := new(rsPoolValue)
+ rpv.execInfo = execInfo
+ rpv.m_lastChkTime = time.Now().Nanosecond()
+ copy(rpv.m_TbIds, execInfo.tbIds)
+ copy(rpv.m_TbTss, execInfo.tbTss)
+ return *rpv
+}
+
+func (rpv rsPoolValue) refreshed(conn *DmConnection) (bool, error) {
+
+ if conn.dmConnector.rsRefreshFreq == 0 {
+ return false, nil
+ }
+
+ if rpv.m_lastChkTime+conn.dmConnector.rsRefreshFreq*int(time.Second) > time.Now().Nanosecond() {
+ return false, nil
+ }
+
+ tss, err := conn.Access.Dm_build_482(interface{}(rpv.m_TbIds).([]uint32))
+ if err != nil {
+ return false, err
+ }
+ rpv.m_lastChkTime = time.Now().Nanosecond()
+
+ var tbCount int
+ if tss != nil {
+ tbCount = len(tss)
+ }
+
+ if tbCount != len(rpv.m_TbTss) {
+ return true, nil
+ }
+
+ for i := 0; i < tbCount; i++ {
+ if rpv.m_TbTss[i] != tss[i] {
+ return true, nil
+ }
+
+ }
+ return false, nil
+}
+
+func (rpv rsPoolValue) getResultSet(stmt *DmStatement) *innerRows {
+ destDatas := rpv.execInfo.rsDatas
+ var totalRows int
+ if rpv.execInfo.rsDatas != nil {
+ totalRows = len(rpv.execInfo.rsDatas)
+ }
+
+ if stmt.maxRows > 0 && stmt.maxRows < int64(totalRows) {
+ destDatas = make([][][]byte, stmt.maxRows)
+ copy(destDatas[:len(destDatas)], rpv.execInfo.rsDatas[:len(destDatas)])
+ }
+
+ rs := newLocalInnerRows(stmt, stmt.columns, destDatas)
+ rs.id = 1
+ return rs
+}
+
+func (rpv rsPoolValue) getDataLen() int {
+ return rpv.execInfo.rsSizeof
+}
+
+type rsPool struct {
+ rsMap map[rsPoolKey]rsPoolValue
+ rsList *list.List
+ totalDataLen int
+}
+
+func newRsPool() *rsPool {
+ rp := new(rsPool)
+ rp.rsMap = make(map[rsPoolKey]rsPoolValue, 100)
+ rp.rsList = list.New()
+ return rp
+}
+
+func (rp *rsPool) removeInList(key rsPoolKey) {
+ for e := rp.rsList.Front(); e != nil && e.Value.(rsPoolKey).equals(key); e = e.Next() {
+ rp.rsList.Remove(e)
+ }
+}
+
+func (rp *rsPool) put(stmt *DmStatement, sql string, execInfo *execRetInfo) {
+ var dataLen int
+ if execInfo != nil {
+ dataLen = execInfo.rsSizeof
+ }
+
+ cacheSize := stmt.dmConn.dmConnector.rsCacheSize * 1024 * 1024
+
+ for rp.totalDataLen+dataLen > cacheSize {
+ if rp.totalDataLen == 0 {
+ return
+ }
+
+ lk := rp.rsList.Back().Value.(rsPoolKey)
+ rp.totalDataLen -= rp.rsMap[lk].getDataLen()
+ rp.rsList.Remove(rp.rsList.Back())
+ delete(rp.rsMap, rp.rsList.Back().Value.(rsPoolKey))
+ }
+
+ key := newRsPoolKey(stmt, sql)
+ value := newRsPoolValue(execInfo)
+
+ if _, ok := rp.rsMap[key]; !ok {
+ rp.rsList.PushFront(key)
+ } else {
+ rp.removeInList(key)
+ rp.rsList.PushFront(key)
+ }
+
+ rp.rsMap[key] = value
+ rp.totalDataLen += dataLen
+}
+
+func (rp *rsPool) get(stmt *DmStatement, sql string) (*rsPoolValue, error) {
+ key := newRsPoolKey(stmt, sql)
+
+ v, ok := rp.rsMap[key]
+ if ok {
+ b, err := v.refreshed(stmt.dmConn)
+ if err != nil {
+ return nil, err
+ }
+
+ if b {
+ rp.removeInList(key)
+ delete(rp.rsMap, key)
+ return nil, nil
+ }
+
+ rp.removeInList(key)
+ rp.rsList.PushFront(key)
+ return &v, nil
+ } else {
+ return nil, nil
+ }
+}
+
+func (s *DmStatement) Close() error {
+ if s.closed {
+ return nil
+ }
+ if len(s.filterChain.filters) == 0 {
+ return s.close()
+ }
+ return s.filterChain.reset().DmStatementClose(s)
+}
+
+func (s *DmStatement) NumInput() int {
+ if err := s.checkClosed(); err != nil {
+ return 0
+ }
+ if len(s.filterChain.filters) == 0 {
+ return s.numInput()
+ }
+ return s.filterChain.reset().DmStatementNumInput(s)
+}
+
+func (s *DmStatement) Exec(args []driver.Value) (driver.Result, error) {
+ if err := s.checkClosed(); err != nil {
+ return nil, err
+ }
+ if len(s.filterChain.filters) == 0 {
+ return s.exec(args)
+ }
+ return s.filterChain.reset().DmStatementExec(s, args)
+}
+
+func (s *DmStatement) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
+ if err := s.checkClosed(); err != nil {
+ return nil, err
+ }
+ if len(s.filterChain.filters) == 0 {
+ return s.execContext(ctx, args)
+ }
+ return s.filterChain.reset().DmStatementExecContext(s, ctx, args)
+}
+
+func (s *DmStatement) Query(args []driver.Value) (driver.Rows, error) {
+ if err := s.checkClosed(); err != nil {
+ return nil, err
+ }
+ if len(s.filterChain.filters) == 0 {
+ return s.query(args)
+ }
+ return s.filterChain.reset().DmStatementQuery(s, args)
+}
+
+func (s *DmStatement) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
+ if err := s.checkClosed(); err != nil {
+ return nil, err
+ }
+ if len(s.filterChain.filters) == 0 {
+ return s.queryContext(ctx, args)
+ }
+ return s.filterChain.reset().DmStatementQueryContext(s, ctx, args)
+}
+
+func (s *DmStatement) CheckNamedValue(nv *driver.NamedValue) error {
+ if len(s.filterChain.filters) == 0 {
+ return s.checkNamedValue(nv)
+ }
+ return s.filterChain.reset().DmStatementCheckNamedValue(s, nv)
+}
+
+func (st *DmStatement) prepare() error {
+ var err error
+ if st.dmConn.dmConnector.escapeProcess {
+ st.nativeSql, err = st.dmConn.escape(st.nativeSql, st.dmConn.dmConnector.keyWords)
+ if err != nil {
+ return err
+ }
+ }
+
+ st.execInfo, err = st.dmConn.Access.Dm_build_407(st, Dm_build_685)
+ if err != nil {
+ return err
+ }
+ st.curRowBindIndicator = make([]byte, st.paramCount)
+ return nil
+}
+
+func (stmt *DmStatement) close() error {
+ stmt.inUse = true
+ if stmt.dmConn.stmtPool != nil && len(stmt.dmConn.stmtPool) < stmt.dmConn.dmConnector.stmtPoolMaxSize {
+ stmt.pool()
+ return nil
+ } else {
+ return stmt.free()
+ }
+}
+
+func (stmt *DmStatement) numInput() int {
+ return int(stmt.paramCount)
+}
+
+func (stmt *DmStatement) checkNamedValue(nv *driver.NamedValue) error {
+ var err error
+ var cvt = converter{stmt.dmConn, false}
+ nv.Value, err = cvt.ConvertValue(nv.Value)
+ stmt.isBatch = cvt.isBatch
+ return err
+}
+
+func (stmt *DmStatement) exec(args []driver.Value) (*DmResult, error) {
+ var err error
+
+ stmt.inUse = true
+ if stmt.isBatch && len(args) > 0 {
+ var tmpArg []driver.Value
+ var arg driver.Value
+ for i := len(args) - 1; i >= 0; i-- {
+ if args[i] != nil {
+ arg = args[i]
+ break
+ }
+ }
+ for _, row := range arg.([][]interface{}) {
+ tmpArg = append(tmpArg, row)
+ }
+ err = stmt.executeBatch(tmpArg)
+ } else {
+ err = stmt.executeInner(args, Dm_build_687)
+ }
+ if err != nil {
+ return nil, err
+ }
+ return newDmResult(stmt, stmt.execInfo), nil
+}
+
+func (stmt *DmStatement) execContext(ctx context.Context, args []driver.NamedValue) (*DmResult, error) {
+ stmt.inUse = true
+ dargs, err := namedValueToValue(stmt, args)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := stmt.dmConn.watchCancel(ctx); err != nil {
+ return nil, err
+ }
+ defer stmt.dmConn.finish()
+
+ return stmt.exec(dargs)
+}
+
+func (stmt *DmStatement) query(args []driver.Value) (*DmRows, error) {
+ var err error
+ stmt.inUse = true
+ err = stmt.executeInner(args, Dm_build_686)
+ if err != nil {
+ return nil, err
+ }
+
+ return newDmRows(newInnerRows(0, stmt, stmt.execInfo)), nil
+}
+
+func (stmt *DmStatement) queryContext(ctx context.Context, args []driver.NamedValue) (*DmRows, error) {
+ stmt.inUse = true
+ dargs, err := namedValueToValue(stmt, args)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := stmt.dmConn.watchCancel(ctx); err != nil {
+ return nil, err
+ }
+
+ rows, err := stmt.query(dargs)
+ if err != nil {
+ stmt.dmConn.finish()
+ return nil, err
+ }
+ rows.finish = stmt.dmConn.finish
+ return rows, err
+}
+
+func NewDmStmt(conn *DmConnection, sql string) (*DmStatement, error) {
+ var s *DmStatement
+
+ if conn.stmtMap != nil && len(conn.stmtMap) > 0 {
+ for _, sv := range conn.stmtMap {
+ if !sv.inUse {
+ sv.inUse = true
+ sv.nativeSql = sql
+ s = sv
+ break
+ }
+ }
+ }
+
+ if s == nil {
+ s = new(DmStatement)
+ s.resetFilterable(&conn.filterable)
+ s.objId = -1
+ s.idGenerator = dmStmtIDGenerator
+ s.dmConn = conn
+ s.maxRows = int64(conn.dmConnector.maxRows)
+ s.nativeSql = sql
+ s.rsMap = make(map[int16]*innerRows)
+ s.inUse = true
+ s.isBatch = conn.isBatch
+
+ if conn.stmtPool != nil && len(conn.stmtPool) > 0 {
+ len := len(conn.stmtPool)
+ spi := conn.stmtPool[0]
+ copy(conn.stmtPool, conn.stmtPool[1:])
+ conn.stmtPool = conn.stmtPool[:len-1]
+ s.id = spi.id
+ s.cursorName = spi.cursorName
+ s.readBaseColName = spi.readBaseColName
+ } else {
+ err := conn.Access.Dm_build_389(s)
+ if err != nil {
+ return nil, err
+ }
+ }
+ conn.stmtMap[s.id] = s
+ }
+
+ return s, nil
+
+}
+
+func (stmt *DmStatement) checkClosed() error {
+ if stmt.dmConn.closed.IsSet() {
+ return driver.ErrBadConn
+ } else if stmt.closed {
+ return ECGO_STATEMENT_HANDLE_CLOSED.throw()
+ }
+
+ return nil
+}
+
+func (stmt *DmStatement) pool() {
+ for _, rs := range stmt.rsMap {
+ rs.Close()
+ }
+
+ stmt.dmConn.stmtPool = append(stmt.dmConn.stmtPool, stmtPoolInfo{stmt.id, stmt.cursorName, stmt.readBaseColName})
+ delete(stmt.dmConn.stmtMap, stmt.id)
+ stmt.inUse = false
+ stmt.closed = true
+}
+
+func (stmt *DmStatement) free() error {
+ for _, rs := range stmt.rsMap {
+ rs.Close()
+ }
+
+ err := stmt.dmConn.Access.Dm_build_394(int32(stmt.id))
+ if err != nil {
+ return err
+ }
+ delete(stmt.dmConn.stmtMap, stmt.id)
+ stmt.inUse = false
+ stmt.closed = true
+ return nil
+}
+
+func encodeArgs(stmt *DmStatement, args []driver.Value) ([]interface{}, error) {
+ bytes := make([]interface{}, len(args), len(args))
+
+ var err error
+
+ for i, arg := range args {
+ nextSwitch:
+ if stmt.params[i].colType == CURSOR {
+ if stmt.params[i].cursorStmt == nil {
+ stmt.params[i].cursorStmt = &DmStatement{dmConn: stmt.dmConn}
+ stmt.params[i].cursorStmt.resetFilterable(&stmt.dmConn.filterable)
+ err = stmt.params[i].cursorStmt.dmConn.Access.Dm_build_389(stmt.params[i].cursorStmt)
+ }
+ stmt.curRowBindIndicator[i] |= BIND_OUT
+ continue
+ }
+ if arg == nil {
+ if resetColType(stmt, i, NULL) {
+ bytes[i] = ParamDataEnum_Null
+ }
+ continue
+ }
+
+ switch v := arg.(type) {
+ case bool:
+ if resetColType(stmt, i, BIT) {
+ bytes[i], err = G2DB.fromBool(v, stmt.params[i], stmt.dmConn)
+ }
+ case int8:
+ if resetColType(stmt, i, TINYINT) {
+ bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn)
+ }
+ case int16:
+ if resetColType(stmt, i, SMALLINT) {
+ bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn)
+ }
+ case int32:
+ if resetColType(stmt, i, INT) {
+ bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn)
+ }
+ case int64:
+ if resetColType(stmt, i, BIGINT) {
+ bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn)
+ }
+ case int:
+ if resetColType(stmt, i, BIGINT) {
+ bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn)
+ }
+ case uint8:
+ if resetColType(stmt, i, SMALLINT) {
+ bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn)
+ }
+ case uint16:
+ if resetColType(stmt, i, INT) {
+ bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn)
+ }
+ case uint32:
+ if resetColType(stmt, i, BIGINT) {
+ bytes[i], err = G2DB.fromInt64(int64(v), stmt.params[i], stmt.dmConn)
+ }
+
+ case float32:
+ if resetColType(stmt, i, REAL) {
+ bytes[i], err = G2DB.fromFloat32(v, stmt.params[i], stmt.dmConn)
+ }
+ case float64:
+ if resetColType(stmt, i, DOUBLE) {
+ bytes[i], err = G2DB.fromFloat64(float64(v), stmt.params[i], stmt.dmConn)
+ }
+ case []byte:
+ if resetColType(stmt, i, VARBINARY) {
+ bytes[i], err = G2DB.fromBytes(v, stmt.params[i], stmt.dmConn)
+ }
+ case string:
+
+ if v == "" && emptyStringToNil(stmt.params[i].colType) {
+ arg = nil
+ goto nextSwitch
+ }
+ if resetColType(stmt, i, VARCHAR) {
+ bytes[i], err = G2DB.fromString(v, stmt.params[i], stmt.dmConn)
+ }
+ case time.Time:
+ if resetColType(stmt, i, DATETIME_TZ) {
+ bytes[i], err = G2DB.fromTime(v, stmt.params[i], stmt.dmConn)
+ }
+ case DmTimestamp:
+ if resetColType(stmt, i, DATETIME_TZ) {
+ bytes[i], err = G2DB.fromTime(v.ToTime(), stmt.params[i], stmt.dmConn)
+ }
+ case DmIntervalDT:
+ if resetColType(stmt, i, INTERVAL_DT) {
+ bytes[i], err = G2DB.fromDmIntervalDT(v, stmt.params[i], stmt.dmConn)
+ }
+ case DmIntervalYM:
+ if resetColType(stmt, i, INTERVAL_YM) {
+ bytes[i], err = G2DB.fromDmdbIntervalYM(v, stmt.params[i], stmt.dmConn)
+ }
+ case DmDecimal:
+ if resetColType(stmt, i, DECIMAL) {
+ bytes[i], err = G2DB.fromDecimal(v, stmt.params[i], stmt.dmConn)
+ }
+
+ case DmBlob:
+ if resetColType(stmt, i, BLOB) {
+ bytes[i], err = G2DB.fromBlob(DmBlob(v), stmt.params[i], stmt.dmConn)
+ if err != nil {
+ return nil, err
+ }
+ }
+ case DmClob:
+ if resetColType(stmt, i, CLOB) {
+ bytes[i], err = G2DB.fromClob(DmClob(v), stmt.params[i], stmt.dmConn)
+ if err != nil {
+ return nil, err
+ }
+ }
+ case DmArray:
+ if resetColType(stmt, i, ARRAY) {
+ da := &v
+ da, err = da.create(stmt.dmConn)
+ if err != nil {
+ return nil, err
+ }
+
+ bytes[i], err = G2DB.fromArray(da, stmt.params[i], stmt.dmConn)
+ }
+ case DmStruct:
+ if resetColType(stmt, i, RECORD) {
+ ds := &v
+ ds, err = ds.create(stmt.dmConn)
+ if err != nil {
+ return nil, err
+ }
+
+ bytes[i], err = G2DB.fromStruct(ds, stmt.params[i], stmt.dmConn)
+ }
+ case sql.Out:
+ arg = v.Dest
+ goto nextSwitch
+
+ case *DmTimestamp:
+ if resetColType(stmt, i, DATETIME_TZ) {
+ bytes[i], err = G2DB.fromTime(v.ToTime(), stmt.params[i], stmt.dmConn)
+ }
+ case *DmIntervalDT:
+ if resetColType(stmt, i, INTERVAL_DT) {
+ bytes[i], err = G2DB.fromDmIntervalDT(*v, stmt.params[i], stmt.dmConn)
+ }
+ case *DmIntervalYM:
+ if resetColType(stmt, i, INTERVAL_YM) {
+ bytes[i], err = G2DB.fromDmdbIntervalYM(*v, stmt.params[i], stmt.dmConn)
+ }
+ case *DmDecimal:
+ if resetColType(stmt, i, DECIMAL) {
+ bytes[i], err = G2DB.fromDecimal(*v, stmt.params[i], stmt.dmConn)
+ }
+ case *DmBlob:
+ if resetColType(stmt, i, BLOB) {
+ bytes[i], err = G2DB.fromBlob(DmBlob(*v), stmt.params[i], stmt.dmConn)
+ }
+ case *DmClob:
+ if resetColType(stmt, i, CLOB) {
+ bytes[i], err = G2DB.fromClob(DmClob(*v), stmt.params[i], stmt.dmConn)
+ }
+ case *DmArray:
+ if resetColType(stmt, i, ARRAY) {
+ v, err = v.create(stmt.dmConn)
+ if err != nil {
+ return nil, err
+ }
+
+ bytes[i], err = G2DB.fromArray(v, stmt.params[i], stmt.dmConn)
+ }
+ case *DmStruct:
+ if resetColType(stmt, i, RECORD) {
+ v, err = v.create(stmt.dmConn)
+ if err != nil {
+ return nil, err
+ }
+
+ bytes[i], err = G2DB.fromStruct(v, stmt.params[i], stmt.dmConn)
+ }
+ case *driver.Rows:
+ if stmt.params[i].colType == CURSOR && !resetColType(stmt, i, CURSOR) && stmt.params[i].cursorStmt == nil {
+ stmt.params[i].cursorStmt = &DmStatement{dmConn: stmt.dmConn}
+ stmt.params[i].cursorStmt.resetFilterable(&stmt.dmConn.filterable)
+ err = stmt.params[i].cursorStmt.dmConn.Access.Dm_build_389(stmt.params[i].cursorStmt)
+ }
+ case io.Reader:
+ bytes[i], err = G2DB.fromReader(io.Reader(v), stmt.params[i], stmt.dmConn)
+ if err != nil {
+ return nil, err
+ }
+ default:
+ err = ECGO_UNSUPPORTED_INPARAM_TYPE.throw()
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ }
+
+ return bytes, nil
+}
+
+type converter struct {
+ conn *DmConnection
+ isBatch bool
+}
+type decimalDecompose interface {
+ Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32)
+}
+
+func (c *converter) ConvertValue(v interface{}) (driver.Value, error) {
+ if driver.IsValue(v) {
+ return v, nil
+ }
+
+ switch vr := v.(type) {
+ case driver.Valuer:
+ sv, err := callValuerValue(vr)
+ if err != nil {
+ return nil, err
+ }
+
+ return sv, nil
+
+ case decimalDecompose, DmDecimal, *DmDecimal, DmTimestamp, *DmTimestamp, DmIntervalDT, *DmIntervalDT,
+ DmIntervalYM, *DmIntervalYM, driver.Rows, *driver.Rows, DmArray, *DmArray, DmStruct, *DmStruct, sql.Out:
+ return vr, nil
+ case big.Int:
+ return NewDecimalFromBigInt(&vr)
+ case big.Float:
+ return NewDecimalFromBigFloat(&vr)
+ case DmClob:
+
+ if vr.connection == nil {
+ vr.connection = c.conn
+ }
+ return vr, nil
+ case DmBlob:
+
+ if vr.connection == nil {
+ vr.connection = c.conn
+ }
+ return vr, nil
+ case *DmBlob:
+
+ if vr.connection == nil {
+ vr.connection = c.conn
+ }
+ return vr, nil
+ case io.Reader:
+ return vr, nil
+ }
+
+ rv := reflect.ValueOf(v)
+ switch rv.Kind() {
+ case reflect.Ptr:
+ if rv.IsNil() {
+ return nil, nil
+ } else {
+ return c.ConvertValue(rv.Elem().Interface())
+ }
+ case reflect.Int:
+ return rv.Int(), nil
+ case reflect.Int8:
+ return int8(rv.Int()), nil
+ case reflect.Int16:
+ return int16(rv.Int()), nil
+ case reflect.Int32:
+ return int32(rv.Int()), nil
+ case reflect.Int64:
+ return int64(rv.Int()), nil
+ case reflect.Uint8:
+ return uint8(rv.Uint()), nil
+ case reflect.Uint16:
+ return uint16(rv.Uint()), nil
+ case reflect.Uint32:
+ return uint32(rv.Uint()), nil
+ case reflect.Uint64, reflect.Uint:
+ u64 := rv.Uint()
+ if u64 >= 1<<63 {
+ bigInt := &big.Int{}
+ bigInt.SetString(strconv.FormatUint(u64, 10), 10)
+ return NewDecimalFromBigInt(bigInt)
+ }
+ return int64(u64), nil
+ case reflect.Float32:
+ return float32(rv.Float()), nil
+ case reflect.Float64:
+ return float64(rv.Float()), nil
+ case reflect.Bool:
+ return rv.Bool(), nil
+ case reflect.Slice:
+ ek := rv.Type().Elem().Kind()
+ if ek == reflect.Uint8 {
+ return rv.Bytes(), nil
+ } else if ek == reflect.Slice {
+ c.isBatch = true
+ return v, nil
+ }
+ return nil, fmt.Errorf("unsupported type %T, a slice of %s", v, ek)
+ case reflect.String:
+ return rv.String(), nil
+ }
+ return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind())
+}
+
+var valuerReflectType = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
+
+func callValuerValue(vr driver.Valuer) (v driver.Value, err error) {
+ if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Ptr &&
+ rv.IsNil() &&
+ rv.Type().Elem().Implements(valuerReflectType) {
+ return nil, nil
+ }
+ return vr.Value()
+}
+
+func namedValueToValue(stmt *DmStatement, named []driver.NamedValue) ([]driver.Value, error) {
+
+ dargs := make([]driver.Value, stmt.paramCount)
+ for i, _ := range dargs {
+ found := false
+ for _, nv := range named {
+ if nv.Name != "" && strings.ToUpper(nv.Name) == strings.ToUpper(stmt.params[i].name) {
+ dargs[i] = nv.Value
+ found = true
+ break
+ }
+ }
+
+ if !found && i < len(named) {
+ dargs[i] = named[i].Value
+ }
+
+ }
+ return dargs, nil
+}
+
+func (stmt *DmStatement) executeInner(args []driver.Value, executeType int16) (err error) {
+
+ var bytes []interface{}
+
+ if stmt.paramCount > 0 {
+ bytes, err = encodeArgs(stmt, args)
+ if err != nil {
+ return err
+ }
+ }
+ stmt.execInfo, err = stmt.dmConn.Access.Dm_build_439(stmt, bytes, false)
+ if err != nil {
+ return err
+ }
+ if stmt.execInfo.outParamDatas != nil {
+ for i, outParamData := range stmt.execInfo.outParamDatas {
+ if stmt.curRowBindIndicator[i]&BIND_OUT == BIND_OUT {
+ if outParamData == nil {
+ if arg, ok := args[i].(*driver.Rows); ok && stmt.params[i].colType == CURSOR {
+ var tmpExecInfo *execRetInfo
+ if tmpExecInfo, err = stmt.dmConn.Access.Dm_build_449(stmt.params[i].cursorStmt, 1); err != nil {
+ return err
+ }
+ if tmpExecInfo.hasResultSet {
+ *arg = newDmRows(newInnerRows(0, stmt.params[i].cursorStmt, tmpExecInfo))
+ } else {
+ *arg = nil
+ }
+ } else {
+ args[i] = nil
+ }
+ continue
+ }
+ if args[i] == nil {
+ switch stmt.params[i].colType {
+ case BOOLEAN:
+ args[i], err = DB2G.toBool(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case BIT:
+ if strings.ToLower(stmt.params[i].typeName) == "boolean" {
+ args[i], err = DB2G.toBool(outParamData, &stmt.params[i].column, stmt.dmConn)
+ }
+
+ args[i], err = DB2G.toInt8(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case TINYINT:
+ args[i], err = DB2G.toInt8(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case SMALLINT:
+ args[i], err = DB2G.toInt16(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case INT:
+ args[i], err = DB2G.toInt32(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case BIGINT:
+ args[i], err = DB2G.toInt64(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case REAL:
+ args[i], err = DB2G.toFloat32(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case DOUBLE:
+ args[i], err = DB2G.toFloat64(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case DATE, TIME, DATETIME, TIME_TZ, DATETIME_TZ:
+ args[i], err = DB2G.toTime(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case INTERVAL_DT:
+ args[i] = newDmIntervalDTByBytes(outParamData)
+ case INTERVAL_YM:
+ args[i] = newDmIntervalYMByBytes(outParamData)
+ case DECIMAL:
+ args[i], err = DB2G.toDmDecimal(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case BINARY, VARBINARY:
+ args[i] = util.StringUtil.BytesToHexString(outParamData, false)
+ case BLOB:
+ args[i] = DB2G.toDmBlob(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case CHAR, VARCHAR2, VARCHAR:
+ args[i] = DB2G.toString(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case CLOB:
+ args[i] = DB2G.toDmClob(outParamData, stmt.dmConn, &stmt.params[i].column)
+ default:
+ err = ECGO_UNSUPPORTED_OUTPARAM_TYPE.throw()
+ }
+ } else {
+ nextSwitch:
+ switch v := args[i].(type) {
+ case sql.Out:
+ args[i] = v.Dest
+ goto nextSwitch
+ case string, *string:
+ args[i] = DB2G.toString(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case []byte, *[]byte:
+ args[i], err = DB2G.toBytes(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case bool, *bool:
+ args[i], err = DB2G.toBool(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case int8, *int8:
+ args[i], err = DB2G.toInt8(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case int16, *int16:
+ args[i], err = DB2G.toInt16(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case int32, *int32:
+ args[i], err = DB2G.toInt32(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case int64, *int64:
+ args[i], err = DB2G.toInt64(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case uint8, *uint8:
+ args[i], err = DB2G.toByte(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case uint16, *uint16:
+ args[i], err = DB2G.toUInt16(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case uint32, *uint32:
+ args[i], err = DB2G.toUInt32(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case uint64, *uint64:
+ args[i], err = DB2G.toUInt64(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case int, *int:
+ args[i], err = DB2G.toInt(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case uint, *uint:
+ args[i], err = DB2G.toUInt(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case float32, *float32:
+ args[i], err = DB2G.toFloat32(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case float64, *float64:
+ args[i], err = DB2G.toFloat64(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case time.Time, *time.Time:
+ args[i], err = DB2G.toTime(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case DmTimestamp, *DmTimestamp:
+ args[i] = newDmTimestampFromBytes(outParamData, stmt.params[i].column, stmt.dmConn)
+ case DmIntervalDT, *DmIntervalDT:
+ args[i] = newDmIntervalDTByBytes(outParamData)
+ case DmIntervalYM, *DmIntervalYM:
+ args[i] = newDmIntervalYMByBytes(outParamData)
+ case DmDecimal, *DmDecimal:
+ args[i], err = DB2G.toDmDecimal(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case DmBlob, *DmBlob:
+ args[i] = DB2G.toDmBlob(outParamData, &stmt.params[i].column, stmt.dmConn)
+ case DmClob, *DmClob:
+ args[i] = DB2G.toDmClob(outParamData, stmt.dmConn, &stmt.params[i].column)
+ case *driver.Rows:
+ if stmt.params[i].colType == CURSOR {
+ var tmpExecInfo *execRetInfo
+ tmpExecInfo, err = stmt.dmConn.Access.Dm_build_449(stmt.params[i].cursorStmt, 1)
+ if err != nil {
+ return err
+ }
+
+ if tmpExecInfo.hasResultSet {
+ *v = newDmRows(newInnerRows(0, stmt.params[i].cursorStmt, tmpExecInfo))
+ } else {
+ *v = nil
+ }
+ }
+ case DmArray, *DmArray:
+ args[i], err = TypeDataSV.bytesToArray(outParamData, nil, stmt.params[i].typeDescriptor)
+ case DmStruct, *DmStruct:
+ args[i], err = TypeDataSV.bytesToRecord(outParamData, nil, stmt.params[i].typeDescriptor)
+ default:
+ err = ECGO_UNSUPPORTED_OUTPARAM_TYPE.throw()
+ }
+ }
+ }
+ }
+ }
+
+ return err
+}
+
+func (stmt *DmStatement) executeBatch(args []driver.Value) (err error) {
+
+ var bytes [][]interface{}
+
+ if stmt.execInfo.retSqlType == Dm_build_700 || stmt.execInfo.retSqlType == Dm_build_705 {
+ return ECGO_INVALID_SQL_TYPE.throw()
+ }
+
+ if stmt.paramCount > 0 && args != nil && len(args) > 0 {
+
+ if len(args) == 1 || stmt.dmConn.dmConnector.batchType == 2 ||
+ (stmt.dmConn.dmConnector.batchNotOnCall && stmt.execInfo.retSqlType == Dm_build_701) {
+ return stmt.executeBatchByRow(args)
+ } else {
+ for _, arg := range args {
+ var newArg []driver.Value
+ for _, a := range arg.([]interface{}) {
+ newArg = append(newArg, a)
+ }
+ tmpBytes, err := encodeArgs(stmt, newArg)
+ if err != nil {
+ return err
+ }
+ bytes = append(bytes, tmpBytes)
+ }
+ stmt.execInfo, err = stmt.dmConn.Access.Dm_build_428(stmt, bytes, stmt.preExec)
+ }
+ }
+ return err
+}
+
+func (stmt *DmStatement) executeBatchByRow(args []driver.Value) (err error) {
+ count := len(args)
+ stmt.execInfo = NewExceInfo()
+ stmt.execInfo.updateCounts = make([]int64, count)
+ var sqlErrBuilder strings.Builder
+ for i := 0; i < count; i++ {
+ tmpExecInfo, err := stmt.dmConn.Access.Dm_build_439(stmt, args[i].([]interface{}), stmt.preExec || i != 0)
+ if err == nil {
+ stmt.execInfo.union(tmpExecInfo, i, 1)
+ } else {
+ stmt.execInfo.updateCounts[i] = -1
+ if stmt.dmConn.dmConnector.continueBatchOnError {
+ sqlErrBuilder.WriteString("row[" + strconv.Itoa(i) + "]:" + err.Error() + util.LINE_SEPARATOR)
+ } else {
+ return ECGO_BATCH_ERROR.addDetailln(err.Error()).throw()
+ }
+ }
+ }
+ if sqlErrBuilder.Len() > 0 {
+ return EC_BP_WITH_ERROR.addDetail(sqlErrBuilder.String()).throw()
+ }
+ return nil
+}
diff --git a/dmr/util/zzq.go b/dmr/util/zzq.go
new file mode 100644
index 0000000..00660f2
--- /dev/null
+++ b/dmr/util/zzq.go
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package util
+
+func Split(s string, sep string) []string {
+ var foot = make([]int, len(s)) // 足够的元素个数
+ var count, sLen, sepLen = 0, len(s), len(sep)
+ for i := 0; i < sLen; i++ {
+ // 处理 s == “-9999-1" && seperators == "-"情况
+ if i == 0 && sLen >= sepLen {
+ if s[0:sepLen] == sep {
+ i += sepLen - 1
+ continue
+ }
+ }
+ for j := 0; j < sepLen; j++ {
+ if s[i] == sep[j] {
+ foot[count] = i
+ count++
+ break
+ }
+ }
+ }
+ var ret = make([]string, count+1)
+ if count == 0 {
+ ret[0] = s
+ return ret
+ }
+ ret[0] = s[0:foot[0]]
+ for i := 1; i < count; i++ {
+ ret[i] = s[foot[i-1]+1 : foot[i]]
+ }
+ ret[count] = s[foot[count-1]+1:]
+ return ret
+}
diff --git a/dmr/util/zzr.go b/dmr/util/zzr.go
new file mode 100644
index 0000000..78147cb
--- /dev/null
+++ b/dmr/util/zzr.go
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package util
+
+import (
+ "go/build"
+ "os"
+ "runtime"
+ "strings"
+)
+
+const (
+ PathSeparator = string(os.PathSeparator)
+ PathListSeparator = string(os.PathListSeparator)
+)
+
+var (
+ goRoot = build.Default.GOROOT
+ goPath = build.Default.GOPATH //获取实际编译时的GOPATH值
+)
+
+type fileUtil struct {
+}
+
+var FileUtil = &fileUtil{}
+
+func (fileUtil *fileUtil) Exists(path string) bool {
+ if _, err := os.Stat(path); !os.IsNotExist(err) {
+ return true
+ }
+ return false
+}
+
+func (fileUtil *fileUtil) Search(relativePath string) (path string) {
+ if strings.Contains(runtime.GOOS, "windows") {
+ relativePath = strings.ReplaceAll(relativePath, "/", "\\")
+ }
+
+ if fileUtil.Exists(goPath) {
+ for _, s := range strings.Split(goPath, PathListSeparator) {
+ path = s + PathSeparator + "src" + PathSeparator + relativePath
+ if fileUtil.Exists(path) {
+ return path
+ }
+ }
+ }
+
+ if fileUtil.Exists(goPath) {
+ for _, s := range strings.Split(goPath, PathListSeparator) {
+ path = s + PathSeparator + "pkg" + PathSeparator + relativePath
+ if fileUtil.Exists(path) {
+ return path
+ }
+ }
+ }
+
+ //if workDir, _ := os.Getwd(); fileUtil.Exists(workDir) {
+ // path = workDir + PathSeparator + "src" + PathSeparator + relativePath
+ // if fileUtil.Exists(path) {
+ // return path
+ // }
+ //}
+
+ //if fileUtil.Exists(goRoot) {
+ // path = goRoot + PathSeparator + "src" + PathSeparator + relativePath
+ // if fileUtil.Exists(path) {
+ // return path
+ // }
+ //}
+
+ return ""
+}
diff --git a/dmr/util/zzs.go b/dmr/util/zzs.go
new file mode 100644
index 0000000..b01ae80
--- /dev/null
+++ b/dmr/util/zzs.go
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package util
+
+const (
+ LINE_SEPARATOR = "\n"
+)
+
+func SliceEquals(src []byte, dest []byte) bool {
+ if len(src) != len(dest) {
+ return false
+ }
+
+ for i, _ := range src {
+ if src[i] != dest[i] {
+ return false
+ }
+ }
+
+ return true
+}
+
+// 获取两个数的最大公约数,由调用者确保m、n>=0;如果m或n为0,返回1
+func GCD(m int32, n int32) int32 {
+ if m == 0 || n == 0 {
+ return 1
+ }
+ r := m % n
+ m = n
+ n = r
+ if r == 0 {
+ return m
+ } else {
+ return GCD(m, n)
+ }
+}
+
+// 返回切片中所有数的累加值
+func Sum(arr []int32) int32 {
+ var sum int32 = 0
+ for _, i := range arr {
+ sum += i
+ }
+ return sum
+}
diff --git a/dmr/util/zzt.go b/dmr/util/zzt.go
new file mode 100644
index 0000000..e652897
--- /dev/null
+++ b/dmr/util/zzt.go
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package util
+
+import (
+ "bytes"
+ "runtime"
+ "strings"
+ "time"
+ "unicode"
+)
+
+type stringutil struct{}
+
+var StringUtil = &stringutil{}
+
+/*----------------------------------------------------*/
+func (StringUtil *stringutil) LineSeparator() string {
+ var lineSeparator string
+ if strings.Contains(runtime.GOOS, "windos") {
+ lineSeparator = "\r\n"
+ } else if strings.Contains(runtime.GOOS, "mac") {
+ lineSeparator = "\r"
+ } else {
+ lineSeparator = "\n"
+ }
+
+ return lineSeparator
+}
+
+func (StringUtil *stringutil) Equals(str1 string, str2 string) bool {
+ return str1 == str2
+}
+
+func (StringUtil *stringutil) EqualsIgnoreCase(str1 string, str2 string) bool {
+ return strings.ToUpper(str1) == strings.ToUpper(str2)
+}
+
+func (StringUtil *stringutil) StartsWith(s string, subStr string) bool {
+ return strings.Index(s, subStr) == 0
+}
+
+func (StringUtil *stringutil) StartWithIgnoreCase(s string, subStr string) bool {
+ return strings.HasPrefix(strings.ToLower(s), strings.ToLower(subStr))
+}
+
+func (StringUtil *stringutil) EndsWith(s string, subStr string) bool {
+ return strings.LastIndex(s, subStr) == len(s)-1
+}
+
+func (StringUtil *stringutil) IsDigit(str string) bool {
+ if str == "" {
+ return false
+ }
+ sz := len(str)
+ for i := 0; i < sz; i++ {
+ if unicode.IsDigit(rune(str[i])) {
+ continue
+ } else {
+ return false
+ }
+ }
+ return true
+}
+
+func (StringUtil *stringutil) FormatDir(dir string) string {
+ dir = strings.TrimSpace(dir)
+ if dir != "" {
+ if !StringUtil.EndsWith(dir, PathSeparator) {
+ dir += PathSeparator
+ }
+ }
+ return dir
+}
+
+func (StringUtil *stringutil) HexStringToBytes(s string) []byte {
+ str := s
+
+ bs := make([]byte, 0)
+ flag := false
+
+ str = strings.TrimSpace(str)
+ if strings.Index(str, "0x") == 0 || strings.Index(str, "0X") == 0 {
+ str = str[2:]
+ }
+
+ if len(str) == 0 {
+ return bs
+ }
+
+ var bsChr []byte
+ l := len(str)
+
+ if l%2 == 0 {
+ bsChr = []byte(str)
+ } else {
+ l += 1
+ bsChr = make([]byte, l)
+ bsChr[0] = '0'
+ for i := 0; i < l-1; i++ {
+ bsChr[i+1] = str[i]
+ }
+ }
+
+ bs = make([]byte, l/2)
+
+ pos := 0
+ for i := 0; i < len(bsChr); i += 2 {
+ bt := convertHex(bsChr[i])
+ bt2 := convertHex(bsChr[i+1])
+ if int(bt) == 0xff || int(bt2) == 0xff {
+ flag = true
+ break
+ }
+
+ bs[pos] = byte(bt*16 + bt2)
+ pos++
+ }
+
+ if flag {
+ bs = ([]byte)(str)
+ }
+
+ return bs
+}
+
+func convertHex(chr byte) byte {
+ if chr >= '0' && chr <= '9' {
+ return chr - '0'
+ } else if chr >= 'a' && chr <= 'f' {
+ return chr - 'a' + 10
+ } else if chr >= 'A' && chr <= 'F' {
+ return chr - 'A' + 10
+ } else {
+ return 0xff
+ }
+}
+
+func (StringUtil *stringutil) BytesToHexString(bs []byte, pre bool) string {
+ if bs == nil {
+ return ""
+ }
+ if len(bs) == 0 {
+ return ""
+ }
+
+ hexDigits := "0123456789ABCDEF"
+ ret := new(strings.Builder)
+ for _, b := range bs {
+ ret.WriteByte(hexDigits[0x0F&(b>>4)])
+ ret.WriteByte(hexDigits[0x0F&b])
+ }
+ if pre {
+ return "0x" + ret.String()
+ }
+ return ret.String()
+}
+
+func (StringUtil *stringutil) ProcessSingleQuoteOfName(name string) string {
+ return StringUtil.processQuoteOfName(name, "'")
+}
+
+func (StringUtil *stringutil) ProcessDoubleQuoteOfName(name string) string {
+ return StringUtil.processQuoteOfName(name, "\"")
+}
+
+func (StringUtil *stringutil) processQuoteOfName(name string, quote string) string {
+ if quote == "" || name == "" {
+ return name
+ }
+
+ temp := name
+ result := bytes.NewBufferString("")
+ index := -1
+ quetoLength := len(quote)
+ index = strings.Index(temp, quote)
+ for index != -1 {
+ result.WriteString(temp[:index+quetoLength])
+ result.WriteString(quote)
+ temp = temp[index+quetoLength:]
+ index = strings.Index(temp, quote)
+ }
+ result.WriteString(temp)
+ return result.String()
+}
+
+func (StringUtil *stringutil) FormatTime() string {
+ return time.Now().Format("2006-01-02 15:04:05")
+}
+
+func (StringUtil *stringutil) SubstringBetween(str string, open string, close string) string {
+ if str == "" {
+ return ""
+ }
+
+ iopen := -1
+ if open != "" {
+ iopen = strings.Index(str, open)
+ }
+
+ iclose := -1
+ if close != "" {
+ iclose = strings.LastIndex(str, close)
+ }
+
+ if iopen == -1 && iclose == -1 {
+ return ""
+ } else if iopen == -1 {
+ return str[0:iclose]
+ } else if iclose == -1 {
+ return str[iopen:]
+ } else {
+ return str[iopen:iclose]
+ }
+}
diff --git a/dmr/v.go b/dmr/v.go
new file mode 100644
index 0000000..35bc373
--- /dev/null
+++ b/dmr/v.go
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import "database/sql/driver"
+
+type DmStruct struct {
+ TypeData
+ m_strctDesc *StructDescriptor // 结构体的描述信息
+
+ m_attribs []TypeData // 各属性值
+
+ m_objCount int // 一个数组项中存在对象类型的个数(class、动态数组)
+
+ m_strCount int // 一个数组项中存在字符串类型的个数
+
+ typeName string
+
+ elements []interface{}
+
+ // Valid为false代表DmArray数据在数据库中为NULL
+ Valid bool
+}
+
+func newDmStruct(typeName string, elements []interface{}) *DmStruct {
+ ds := new(DmStruct)
+ ds.typeName = typeName
+ ds.elements = elements
+ ds.Valid = true
+ return ds
+}
+
+func (ds *DmStruct) create(dc *DmConnection) (*DmStruct, error) {
+ desc, err := newStructDescriptor(ds.typeName, dc)
+ if err != nil {
+ return nil, err
+ }
+ return ds.createByStructDescriptor(desc, dc)
+}
+
+func newDmStructByTypeData(atData []TypeData, desc *TypeDescriptor) *DmStruct {
+ ds := new(DmStruct)
+ ds.Valid = true
+ ds.initTypeData()
+ ds.m_strctDesc = newStructDescriptorByTypeDescriptor(desc)
+ ds.m_attribs = atData
+ return ds
+}
+
+func (dest *DmStruct) Scan(src interface{}) error {
+ switch src := src.(type) {
+ case nil:
+ *dest = *new(DmStruct)
+ // 将Valid标志置false表示数据库中该列为NULL
+ (*dest).Valid = false
+ return nil
+ case *DmStruct:
+ *dest = *src
+ return nil
+ default:
+ return UNSUPPORTED_SCAN
+ }
+}
+
+func (dt DmStruct) Value() (driver.Value, error) {
+ if !dt.Valid {
+ return nil, nil
+ }
+ return dt, nil
+}
+
+func (ds *DmStruct) getAttribsTypeData() []TypeData {
+ return ds.m_attribs
+}
+
+func (ds *DmStruct) createByStructDescriptor(desc *StructDescriptor, conn *DmConnection) (*DmStruct, error) {
+ ds.initTypeData()
+
+ if nil == desc {
+ return nil, ECGO_INVALID_PARAMETER_VALUE.throw()
+ }
+
+ ds.m_strctDesc = desc
+ if nil == ds.elements {
+ ds.m_attribs = make([]TypeData, desc.getSize())
+ } else {
+ if desc.getSize() != len(ds.elements) && desc.getObjId() != 4 {
+ return nil, ECGO_STRUCT_MEM_NOT_MATCH.throw()
+ }
+ var err error
+ ds.m_attribs, err = TypeDataSV.toStruct(ds.elements, ds.m_strctDesc.m_typeDesc)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return ds, nil
+}
+
+func (ds *DmStruct) getSQLTypeName() (string, error) {
+ return ds.m_strctDesc.m_typeDesc.getFulName()
+}
+
+func (ds *DmStruct) getAttributes() ([]interface{}, error) {
+ return TypeDataSV.toJavaArrayByDmStruct(ds)
+}
+
+func (ds *DmStruct) checkCol(col int) error {
+ if col < 1 || col > len(ds.m_attribs) {
+ return ECGO_INVALID_SEQUENCE_NUMBER.throw()
+ }
+ return nil
+}
+
+// 获取指定索引的成员变量值,以TypeData的形式给出,col 1 based
+func (ds *DmStruct) getAttrValue(col int) (*TypeData, error) {
+ err := ds.checkCol(col)
+ if err != nil {
+ return nil, err
+ }
+ return &ds.m_attribs[col-1], nil
+}
+
+func (ds *DmStruct) checkValid() error {
+ if !ds.Valid {
+ return ECGO_IS_NULL.throw()
+ }
+ return nil
+}
diff --git a/dmr/w.go b/dmr/w.go
new file mode 100644
index 0000000..e730c1d
--- /dev/null
+++ b/dmr/w.go
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import (
+ "database/sql/driver"
+ "strings"
+ "time"
+)
+
+const (
+ Seconds_1900_1970 = 2209017600
+
+ OFFSET_YEAR = 0
+
+ OFFSET_MONTH = 1
+
+ OFFSET_DAY = 2
+
+ OFFSET_HOUR = 3
+
+ OFFSET_MINUTE = 4
+
+ OFFSET_SECOND = 5
+
+ OFFSET_MILLISECOND = 6
+
+ OFFSET_TIMEZONE = 7
+
+ DT_LEN = 8
+
+ INVALID_VALUE = int(INT32_MIN)
+)
+
+type DmTimestamp struct {
+ dt []int
+ dtype int
+ scale int
+ oracleFormatPattern string
+ oracleDateLanguage int
+
+ // Valid为false代表DmArray数据在数据库中为NULL
+ Valid bool
+}
+
+func newDmTimestampFromDt(dt []int, dtype int, scale int) *DmTimestamp {
+ dmts := new(DmTimestamp)
+ dmts.Valid = true
+ dmts.dt = dt
+ dmts.dtype = dtype
+ dmts.scale = scale
+ return dmts
+}
+
+func newDmTimestampFromBytes(bytes []byte, column column, conn *DmConnection) *DmTimestamp {
+ dmts := new(DmTimestamp)
+ dmts.Valid = true
+ dmts.dt = decode(bytes, column.isBdta, int(column.colType), int(column.scale), int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
+
+ if isLocalTimeZone(int(column.colType), int(column.scale)) {
+ dmts.scale = getLocalTimeZoneScale(int(column.colType), int(column.scale))
+ } else {
+ dmts.scale = int(column.scale)
+ }
+
+ dmts.dtype = int(column.colType)
+ dmts.scale = int(column.scale)
+ dmts.oracleDateLanguage = int(conn.OracleDateLanguage)
+ switch column.colType {
+ case DATE:
+ dmts.oracleFormatPattern = conn.FormatDate
+ case TIME:
+ dmts.oracleFormatPattern = conn.FormatTime
+ case TIME_TZ:
+ dmts.oracleFormatPattern = conn.FormatTimeTZ
+ case DATETIME:
+ dmts.oracleFormatPattern = conn.FormatTimestamp
+ case DATETIME_TZ:
+ dmts.oracleFormatPattern = conn.FormatTimestampTZ
+ }
+ return dmts
+}
+
+func NewDmTimestampFromString(str string) (*DmTimestamp, error) {
+ dt := make([]int, DT_LEN)
+ dtype, err := toDTFromString(strings.TrimSpace(str), dt)
+ if err != nil {
+ return nil, err
+ }
+
+ if dtype == DATE {
+ return newDmTimestampFromDt(dt, dtype, 0), nil
+ }
+ return newDmTimestampFromDt(dt, dtype, 6), nil
+}
+
+func NewDmTimestampFromTime(time time.Time) *DmTimestamp {
+ dt := toDTFromTime(time)
+ return newDmTimestampFromDt(dt, DATETIME, 6)
+}
+
+func (dmTimestamp *DmTimestamp) ToTime() time.Time {
+ return toTimeFromDT(dmTimestamp.dt, 0)
+}
+
+// 获取年月日时分秒毫秒时区
+func (dmTimestamp *DmTimestamp) GetDt() []int {
+ return dmTimestamp.dt
+}
+
+func (dmTimestamp *DmTimestamp) CompareTo(ts DmTimestamp) int {
+ if dmTimestamp.ToTime().Equal(ts.ToTime()) {
+ return 0
+ } else if dmTimestamp.ToTime().Before(ts.ToTime()) {
+ return -1
+ } else {
+ return 1
+ }
+}
+
+func (dmTimestamp *DmTimestamp) String() string {
+ if dmTimestamp.oracleFormatPattern != "" {
+ return dtToStringByOracleFormat(dmTimestamp.dt, dmTimestamp.oracleFormatPattern, dmTimestamp.oracleDateLanguage)
+ }
+ return dtToString(dmTimestamp.dt, dmTimestamp.dtype, dmTimestamp.scale)
+}
+
+func (dest *DmTimestamp) Scan(src interface{}) error {
+ if dest == nil {
+ return ECGO_STORE_IN_NIL_POINTER.throw()
+ }
+ switch src := src.(type) {
+ case nil:
+ *dest = *new(DmTimestamp)
+ // 将Valid标志置false表示数据库中该列为NULL
+ (*dest).Valid = false
+ return nil
+ case *DmTimestamp:
+ *dest = *src
+ return nil
+ case time.Time:
+ ret := NewDmTimestampFromTime(src)
+ *dest = *ret
+ return nil
+ default:
+ return UNSUPPORTED_SCAN
+ }
+}
+
+func (dmTimestamp DmTimestamp) Value() (driver.Value, error) {
+ if !dmTimestamp.Valid {
+ return nil, nil
+ }
+ return dmTimestamp, nil
+}
+
+func (dmTimestamp *DmTimestamp) toBytes() ([]byte, error) {
+ return encode(dmTimestamp.dt, dmTimestamp.dtype, dmTimestamp.scale, dmTimestamp.dt[OFFSET_TIMEZONE])
+}
+
+/**
+ * 获取当前对象的年月日时分秒,如果原来没有decode会先decode;
+ */
+func (dmTimestamp *DmTimestamp) getDt() []int {
+ return dmTimestamp.dt
+}
+
+func (dmTimestamp *DmTimestamp) getTime() int64 {
+ sec := toTimeFromDT(dmTimestamp.dt, 0).Unix()
+ return sec + int64(dmTimestamp.dt[OFFSET_MILLISECOND])
+}
+
+func (dmTimestamp *DmTimestamp) setTime(time int64) {
+ timeInMillis := (time / 1000) * 1000
+ nanos := (int64)((time % 1000) * 1000000)
+ if nanos < 0 {
+ nanos = 1000000000 + nanos
+ timeInMillis = (((time / 1000) - 1) * 1000)
+ }
+ dmTimestamp.dt = toDTFromUnix(timeInMillis, nanos)
+}
+
+func (dmTimestamp *DmTimestamp) setTimezone(tz int) error {
+ // DM中合法的时区取值范围为-12:59至+14:00
+ if tz <= -13*60 || tz > 14*60 {
+ return ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ dmTimestamp.dt[OFFSET_TIMEZONE] = tz
+ return nil
+}
+
+func (dmTimestamp *DmTimestamp) getNano() int64 {
+ return int64(dmTimestamp.dt[OFFSET_MILLISECOND] * 1000)
+}
+
+func (dmTimestamp *DmTimestamp) setNano(nano int64) {
+ dmTimestamp.dt[OFFSET_MILLISECOND] = (int)(nano / 1000)
+}
+
+func (dmTimestamp *DmTimestamp) string() string {
+ if dmTimestamp.oracleFormatPattern != "" {
+ return dtToStringByOracleFormat(dmTimestamp.dt, dmTimestamp.oracleFormatPattern, dmTimestamp.oracleDateLanguage)
+ }
+ return dtToString(dmTimestamp.dt, dmTimestamp.dtype, dmTimestamp.scale)
+}
+
+func (dmTimestamp *DmTimestamp) checkValid() error {
+ if !dmTimestamp.Valid {
+ return ECGO_IS_NULL.throw()
+ }
+ return nil
+}
diff --git a/dmr/x.go b/dmr/x.go
new file mode 100644
index 0000000..17edf20
--- /dev/null
+++ b/dmr/x.go
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import (
+ "context"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+)
+
+const (
+ STATUS_VALID_TIME = 20 * time.Second // ms
+
+ // sort 值
+ SORT_SERVER_MODE_INVALID = -1 // 不允许连接的模式
+
+ SORT_SERVER_NOT_ALIVE = -2 // 站点无法连接
+
+ SORT_UNKNOWN = INT32_MAX // 站点还未连接过,模式未知
+
+ SORT_NORMAL = 30
+
+ SORT_PRIMARY = 20
+
+ SORT_STANDBY = 10
+
+ // OPEN>MOUNT>SUSPEND
+ SORT_OPEN = 3
+
+ SORT_MOUNT = 2
+
+ SORT_SUSPEND = 1
+)
+
+type ep struct {
+ host string
+ port int32
+ alive bool
+ statusRefreshTs int64 // 状态更新的时间点
+ serverMode int32
+ serverStatus int32
+ dscControl bool
+ sort int32
+ epSeqno int32
+ epStatus int32
+ lock sync.Mutex
+}
+
+func newEP(host string, port int32) *ep {
+ ep := new(ep)
+ ep.host = host
+ ep.port = port
+ ep.serverMode = -1
+ ep.serverStatus = -1
+ ep.sort = SORT_UNKNOWN
+ return ep
+}
+
+func (ep *ep) getSort(checkTime bool) int32 {
+ if checkTime {
+ if time.Now().UnixNano()-ep.statusRefreshTs < int64(STATUS_VALID_TIME) {
+ return ep.sort
+ } else {
+ return SORT_UNKNOWN
+ }
+ }
+ return ep.sort
+}
+
+func (ep *ep) calcSort(loginMode int32) int32 {
+ var sort int32 = 0
+ switch loginMode {
+ case LOGIN_MODE_PRIMARY_FIRST:
+ {
+ // 主机优先:PRIMARY>NORMAL>STANDBY
+ switch ep.serverMode {
+ case SERVER_MODE_NORMAL:
+ sort += SORT_NORMAL * 10
+ case SERVER_MODE_PRIMARY:
+ sort += SORT_PRIMARY * 100
+ case SERVER_MODE_STANDBY:
+ sort += SORT_STANDBY
+ }
+ }
+ case LOGIN_MODE_STANDBY_FIRST:
+ {
+ // STANDBY优先: STANDBY>PRIMARY>NORMAL
+ switch ep.serverMode {
+ case SERVER_MODE_NORMAL:
+ sort += SORT_NORMAL
+ case SERVER_MODE_PRIMARY:
+ sort += SORT_PRIMARY * 10
+ case SERVER_MODE_STANDBY:
+ sort += SORT_STANDBY * 100
+ }
+ }
+ case LOGIN_MODE_PRIMARY_ONLY:
+ if ep.serverMode != SERVER_MODE_PRIMARY {
+ return SORT_SERVER_MODE_INVALID
+ }
+ sort += SORT_PRIMARY
+ case LOGIN_MODE_STANDBY_ONLY:
+ if ep.serverMode != SERVER_MODE_STANDBY {
+ return SORT_SERVER_MODE_INVALID
+ }
+ sort += SORT_STANDBY
+ }
+
+ switch ep.serverStatus {
+ case SERVER_STATUS_MOUNT:
+ sort += SORT_MOUNT
+ case SERVER_STATUS_OPEN:
+ sort += SORT_OPEN
+ case SERVER_STATUS_SUSPEND:
+ sort += SORT_SUSPEND
+ }
+ return sort
+}
+
+func (ep *ep) refreshStatus(alive bool, conn *DmConnection) {
+ ep.lock.Lock()
+ defer ep.lock.Unlock()
+ ep.alive = alive
+ ep.statusRefreshTs = time.Now().UnixNano()
+ if alive {
+ ep.serverMode = conn.SvrMode
+ ep.serverStatus = conn.SvrStat
+ ep.dscControl = conn.dscControl
+ ep.sort = ep.calcSort(int32(conn.dmConnector.loginMode))
+ } else {
+ ep.serverMode = -1
+ ep.serverStatus = -1
+ ep.dscControl = false
+ ep.sort = SORT_SERVER_NOT_ALIVE
+ }
+}
+
+func (ep *ep) connect(connector *DmConnector) (*DmConnection, error) {
+ connector.host = ep.host
+ connector.port = ep.port
+ conn, err := connector.connectSingle(context.Background())
+ if err != nil {
+ ep.refreshStatus(false, conn)
+ return nil, err
+ }
+ ep.refreshStatus(true, conn)
+ return conn, nil
+}
+
+func (ep *ep) getServerStatusDesc(serverStatus int32) string {
+ ret := ""
+ switch ep.serverStatus {
+ case SERVER_STATUS_OPEN:
+ ret = "OPEN"
+ case SERVER_STATUS_MOUNT:
+ ret = "MOUNT"
+ case SERVER_STATUS_SUSPEND:
+ ret = "SUSPEND"
+ default:
+ ret = "UNKNOWN"
+ }
+ return ret
+}
+
+func (ep *ep) getServerModeDesc(serverMode int32) string {
+ ret := ""
+ switch ep.serverMode {
+ case SERVER_MODE_NORMAL:
+ ret = "NORMAL"
+ case SERVER_MODE_PRIMARY:
+ ret = "PRIMARY"
+ case SERVER_MODE_STANDBY:
+ ret = "STANDBY"
+ default:
+ ret = "UNKNOWN"
+ }
+ return ret
+}
+
+func (ep *ep) String() string {
+ dscControl := ")"
+ if ep.dscControl {
+ dscControl = ", DSC CONTROL)"
+ }
+ return strings.TrimSpace(ep.host) + ":" + strconv.Itoa(int(ep.port)) +
+ " (" + ep.getServerModeDesc(ep.serverMode) + ", " + ep.getServerStatusDesc(ep.serverStatus) + dscControl
+}
diff --git a/dmr/y.go b/dmr/y.go
new file mode 100644
index 0000000..73e7155
--- /dev/null
+++ b/dmr/y.go
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import (
+ "bytes"
+ "math/rand"
+ "sync"
+ "time"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+/**
+ * dm_svc.conf中配置的服务名对应的一组实例, 以及相关属性和状态信息
+ *
+ * 需求:
+ * 1. 连接均匀分布在各个节点上
+ * 2. loginMode,loginStatus匹配
+ * 3. 连接异常节点比较耗时,在DB列表中包含异常节点时异常连接尽量靠后,减少对建连接速度的影响
+ *
+ *
+ * DB 连接顺序:
+ * 1. well distribution,每次连接都从列表的下一个节点开始
+ * 2. 用DB sort值按从大到小排序,sort为一个四位数XXXX,个位--serverStatus,十位--serverMode,共 有三种模式,最优先的 *100, 次优先的*10
+ */
+type epGroup struct {
+ name string
+ epList []*ep
+ props *Properties
+ epStartPos int32 // wellDistribute 起始位置
+ lock sync.Mutex
+}
+
+func newEPGroup(name string, serverList []*ep) *epGroup {
+ g := new(epGroup)
+ g.name = name
+ g.epList = serverList
+ if serverList == nil || len(serverList) == 0 {
+ g.epStartPos = -1
+ } else {
+ // 保证进程间均衡,起始位置采用随机值
+ g.epStartPos = rand.Int31n(int32(len(serverList))) - 1
+ }
+ return g
+}
+
+func (g *epGroup) connect(connector *DmConnector) (*DmConnection, error) {
+ var dbSelector = g.getEPSelector(connector)
+ var ex error = nil
+ // 如果配置了loginMode的主、备等优先策略,而未找到最高优先级的节点时持续循环switchtimes次,如果最终还是没有找到最高优先级则选择次优先级的
+ // 如果只有一个节点,一轮即可决定是否连接;多个节点时保证switchTimes轮尝试,最后一轮决定用哪个节点(由于节点已经按照模式优先级排序,最后一轮理论上就是连第一个节点)
+ var cycleCount int32
+ if len(g.epList) == 1 {
+ cycleCount = 1
+ } else {
+ cycleCount = connector.switchTimes + 1
+ }
+ for i := int32(0); i < cycleCount; i++ {
+ // 循环了一遍,如果没有符合要求的, 重新排序, 再尝试连接
+ conn, err := g.traverseServerList(connector, dbSelector, i == 0, i == cycleCount-1)
+ if err != nil {
+ ex = err
+ time.Sleep(time.Duration(connector.switchInterval) * time.Millisecond)
+ continue
+ }
+ return conn, nil
+ }
+ return nil, ex
+}
+
+func (g *epGroup) getEPSelector(connector *DmConnector) *epSelector {
+ if connector.epSelector == TYPE_HEAD_FIRST {
+ return newEPSelector(g.epList)
+ } else {
+ serverCount := int32(len(g.epList))
+ sortEPs := make([]*ep, serverCount)
+ g.lock.Lock()
+ defer g.lock.Unlock()
+ g.epStartPos = (g.epStartPos + 1) % serverCount
+ for i := int32(0); i < serverCount; i++ {
+ sortEPs[i] = g.epList[(i+g.epStartPos)%serverCount]
+ }
+ return newEPSelector(sortEPs)
+ }
+}
+
+/**
+* 从指定编号开始,遍历一遍服务名中的ip列表,只连接指定类型(主机或备机)的ip
+* @param servers
+* @param checkTime
+*
+* @exception
+* DBError.ECJDBC_INVALID_SERVER_MODE 有站点的模式不匹配
+* DBError.ECJDBC_COMMUNITION_ERROR 所有站点都连不上
+ */
+func (g *epGroup) traverseServerList(connector *DmConnector, epSelector *epSelector, first bool, last bool) (*DmConnection, error) {
+ epList := epSelector.sortDBList(first)
+ errorMsg := bytes.NewBufferString("")
+ var ex error = nil // 第一个错误
+ for _, server := range epList {
+ conn, err := server.connect(connector)
+ if err != nil {
+ if ex == nil {
+ ex = err
+ }
+ errorMsg.WriteString("[")
+ errorMsg.WriteString(server.String())
+ errorMsg.WriteString("]")
+ errorMsg.WriteString(err.Error())
+ errorMsg.WriteString(util.StringUtil.LineSeparator())
+ continue
+ }
+ valid, err := epSelector.checkServerMode(conn, last)
+ if err != nil {
+ if ex == nil {
+ ex = err
+ }
+ errorMsg.WriteString("[")
+ errorMsg.WriteString(server.String())
+ errorMsg.WriteString("]")
+ errorMsg.WriteString(err.Error())
+ errorMsg.WriteString(util.StringUtil.LineSeparator())
+ continue
+ }
+ if !valid {
+ conn.close()
+ err = ECGO_INVALID_SERVER_MODE.throw()
+ if ex == nil {
+ ex = err
+ }
+ errorMsg.WriteString("[")
+ errorMsg.WriteString(server.String())
+ errorMsg.WriteString("]")
+ errorMsg.WriteString(err.Error())
+ errorMsg.WriteString(util.StringUtil.LineSeparator())
+ continue
+ }
+ return conn, nil
+ }
+ if ex != nil {
+ return nil, ex
+ }
+ return nil, ECGO_COMMUNITION_ERROR.addDetail(errorMsg.String()).throw()
+}
diff --git a/dmr/z.go b/dmr/z.go
new file mode 100644
index 0000000..377fba1
--- /dev/null
+++ b/dmr/z.go
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import "sort"
+
+const (
+ TYPE_WELL_DISTRIBUTE = 0
+ TYPE_HEAD_FIRST = 1
+)
+
+type epSelector struct {
+ dbs []*ep
+}
+
+func newEPSelector(dbs []*ep) *epSelector {
+ return &epSelector{dbs}
+}
+
+func (s *epSelector) sortDBList(first bool) []*ep {
+ if !first {
+ // 按sort从大到小排序,相同sort值顺序不变
+ sort.Slice(s.dbs, func(i, j int) bool {
+ return s.dbs[i].getSort(first) > s.dbs[j].getSort(first)
+ })
+ }
+ return s.dbs
+}
+
+func (s *epSelector) checkServerMode(conn *DmConnection, last bool) (bool, error) {
+ // 只连dsc control节点
+ if conn.dmConnector.loginDscCtrl && !conn.dscControl {
+ conn.close()
+ return false, ECGO_INVALID_SERVER_MODE.throw()
+ }
+ // 模式不匹配, 这里使用的是连接之前的sort,连接之后server的状态可能发生改变sort也可能改变
+ if conn.dmConnector.loginStatus > 0 && int(conn.SvrStat) != conn.dmConnector.loginStatus {
+ conn.close()
+ return false, ECGO_INVALID_SERVER_MODE.throw()
+ }
+ if last {
+ switch conn.dmConnector.loginMode {
+ case LOGIN_MODE_PRIMARY_ONLY:
+ return conn.SvrMode == SERVER_MODE_PRIMARY, nil
+ case LOGIN_MODE_STANDBY_ONLY:
+ return conn.SvrMode == SERVER_MODE_STANDBY, nil
+ default:
+ return true, nil
+ }
+ }
+ switch conn.dmConnector.loginMode {
+ case LOGIN_MODE_NORMAL_FIRST:
+ return conn.SvrMode == SERVER_MODE_NORMAL, nil
+ case LOGIN_MODE_PRIMARY_FIRST, LOGIN_MODE_PRIMARY_ONLY:
+ return conn.SvrMode == SERVER_MODE_PRIMARY, nil
+ case LOGIN_MODE_STANDBY_FIRST, LOGIN_MODE_STANDBY_ONLY:
+ return conn.SvrMode == SERVER_MODE_STANDBY, nil
+ default:
+ break
+ }
+ return false, nil
+}
diff --git a/dmr/za.go b/dmr/za.go
new file mode 100644
index 0000000..040612c
--- /dev/null
+++ b/dmr/za.go
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import (
+ "bytes"
+ "fmt"
+ "runtime"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/i18n"
+)
+
+// 驱动级错误
+var (
+ DSN_INVALID_SCHEMA = newDmError(9001, "error.dsn.invalidSchema")
+ UNSUPPORTED_SCAN = newDmError(9002, "error.unsupported.scan")
+ INVALID_PARAMETER_NUMBER = newDmError(9003, "error.invalidParameterNumber")
+ THIRD_PART_CIPHER_INIT_FAILED = newDmError(9004, "error.initThirdPartCipherFailed")
+ ECGO_NOT_QUERY_SQL = newDmError(9005, "error.notQuerySQL")
+ ECGO_NOT_EXEC_SQL = newDmError(9006, "error.notExecSQL")
+ ECGO_UNKOWN_NETWORK = newDmError(9007, "error.unkownNetWork")
+ ECGO_INVALID_CONN = newDmError(9008, "error.invalidConn")
+ ECGO_UNSUPPORTED_INPARAM_TYPE = newDmError(9009, "error.unsupportedInparamType")
+ ECGO_UNSUPPORTED_OUTPARAM_TYPE = newDmError(9010, "error.unsupportedOutparamType")
+ ECGO_STORE_IN_NIL_POINTER = newDmError(9011, "error.storeInNilPointer")
+ ECGO_IS_NULL = newDmError(9012, "error.isNull")
+)
+
+var (
+ ECGO_CONNECTION_SWITCH_FAILED = newDmError(20001, "error.connectionSwitchFailed")
+ ECGO_CONNECTION_SWITCHED = newDmError(20000, "error.connectionSwitched")
+ ECGO_COMMUNITION_ERROR = newDmError(6001, "error.communicationError")
+ ECGO_MSG_CHECK_ERROR = newDmError(6002, "error.msgCheckError")
+ ECGO_INVALID_TIME_INTERVAL = newDmError(6005, "error.invalidTimeInterval")
+ ECGO_UNSUPPORTED_TYPE = newDmError(6006, "error.unsupportedType")
+ ECGO_DATA_CONVERTION_ERROR = newDmError(6007, "error.dataConvertionError")
+ ECGO_INVALID_SQL_TYPE = newDmError(6009, "error.invalidSqlType")
+ ECGO_INVALID_DATETIME_FORMAT = newDmError(6015, "error.invalidDateTimeFormat")
+ ECGO_INVALID_COLUMN_TYPE = newDmError(6016, "error.invalidColumnType")
+ ECGO_RESULTSET_IS_READ_ONLY = newDmError(6029, "error.resultsetInReadOnlyStatus")
+ ECGO_INVALID_SEQUENCE_NUMBER = newDmError(6032, "error.invalidSequenceNumber")
+ ECGO_RESULTSET_CLOSED = newDmError(6034, "errorResultSetColsed")
+ ECGO_STATEMENT_HANDLE_CLOSED = newDmError(6035, "errorStatementHandleClosed")
+ ECGO_INVALID_PARAMETER_VALUE = newDmError(6036, "error.invalidParamterValue")
+ ECGO_INVALID_TRAN_ISOLATION = newDmError(6038, "error.invalidTranIsolation")
+ ECGO_COMMIT_IN_AUTOCOMMIT_MODE = newDmError(6039, "errorCommitInAutoCommitMode")
+ ECGO_ROLLBACK_IN_AUTOCOMMIT_MODE = newDmError(6040, "errorRollbackInAutoCommitMode")
+ ECGO_INVALID_LENGTH_OR_OFFSET = newDmError(6057, "error.invalidLenOrOffset")
+ ECGO_INTERVAL_OVERFLOW = newDmError(6066, "error.intervalValueOverflow")
+ ECGO_INVALID_BFILE_STR = newDmError(6067, "error.invalidBFile")
+ ECGO_INVALID_HEX = newDmError(6068, "error.invalidHex")
+ ECGO_INVALID_CIPHER = newDmError(6069, "error.invalidCipher")
+ ECGO_OSAUTH_ERROR = newDmError(6073, "error.osauthError")
+ ECGO_ERROR_SERVER_VERSION = newDmError(6074, "error.serverVersion")
+ ECGO_USERNAME_TOO_LONG = newDmError(6075, "error.usernameTooLong")
+ ECGO_PASSWORD_TOO_LONG = newDmError(6076, "error.passwordTooLong")
+ ECGO_INVALID_COMPLEX_TYPE_NAME = newDmError(6079, "error.invalidComplexTypeName")
+ ECGO_STRUCT_MEM_NOT_MATCH = newDmError(6080, "error.structMemNotMatch")
+ ECGO_INVALID_OBJ_BLOB = newDmError(6081, "error.invalidObjBlob")
+ ECGO_INVALID_ARRAY_LEN = newDmError(6082, "error.invalidArrayLen")
+ ECGO_INVALID_SERVER_MODE = newDmError(6091, "error.invalidServerMode")
+ ECGO_DATA_TOO_LONG = newDmError(6092, "error.dataTooLong")
+ ECGO_BATCH_ERROR = newDmError(6093, "error.batchError")
+ ECGO_MSG_TOO_LONG = newDmError(6101, "error.msgTooLong")
+ ECGO_INVALID_DATETIME_VALUE = newDmError(6103, "error.invalidDateTimeValue")
+
+ ECGO_INIT_SSL_FAILED = newDmError(20002, "error.SSLInitFailed")
+ ECGO_LOB_FREED = newDmError(20003, "error.LobDataHasFreed")
+ ECGO_FATAL_ERROR = newDmError(20004, "error.fatalError")
+)
+
+//Svr Msg Err
+var (
+ ECGO_DATA_OVERFLOW = newDmError(-6102, "error.dataOverflow")
+ ECGO_DATETIME_OVERFLOW = newDmError(-6112, "error.datetimeOverflow")
+ EC_RN_EXCEED_ROWSET_SIZE = newDmError(-7036, "")
+ EC_BP_WITH_ERROR = newDmError(121, "warning.bpWithErr")
+)
+
+type DmError struct {
+ ErrCode int32
+ ErrText string
+ stack []uintptr
+ detail string
+}
+
+func newDmError(errCode int32, errText string) *DmError {
+ de := new(DmError)
+ de.ErrCode = errCode
+ de.ErrText = errText
+ de.stack = nil
+ de.detail = ""
+ return de
+}
+
+func (dmError *DmError) throw() *DmError {
+ var pcs [32]uintptr
+ n := runtime.Callers(2, pcs[:])
+ dmError.stack = pcs[0:n]
+ return dmError
+}
+
+func (dmError *DmError) FormatStack() string {
+ if dmError == nil || dmError.stack == nil {
+ return ""
+ }
+ buffer := bytes.NewBuffer(nil)
+ index := 1
+ space := " "
+ for _, p := range dmError.stack {
+ if fn := runtime.FuncForPC(p - 1); fn != nil {
+ file, line := fn.FileLine(p - 1)
+ buffer.WriteString(fmt.Sprintf(" %d).%s%s\n \t%s:%d\n", index, space, fn.Name(), file, line))
+ index++
+ }
+ }
+ return buffer.String()
+}
+
+func (dmError *DmError) Error() string {
+ return fmt.Sprintf("Error %d: %s", dmError.ErrCode, i18n.Get(dmError.ErrText, Locale)) + dmError.detail + "\n" + "stack info:\n" + dmError.FormatStack()
+}
+
+// 扩充ErrText
+func (dmError *DmError) addDetail(detail string) *DmError {
+ dmError.detail = detail
+ return dmError
+}
+func (dmError *DmError) addDetailln(detail string) *DmError {
+ return dmError.addDetail("\n" + detail)
+}
diff --git a/dmr/zb.go b/dmr/zb.go
new file mode 100644
index 0000000..35ce362
--- /dev/null
+++ b/dmr/zb.go
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+const (
+ IGNORE_TARGET_LENGTH int32 = -1
+
+ IGNORE_TARGET_SCALE int32 = -1
+
+ IGNORE_TARGET_TYPE = INT32_MIN
+
+ TYPE_FLAG_UNKNOWN byte = 0 // 未知类型
+
+ TYPE_FLAG_EXACT byte = 1 // 精确类型
+
+ TYPE_FLAG_RECOMMEND byte = 2 // 推荐类型
+
+ IO_TYPE_IN byte = 0
+
+ IO_TYPE_OUT byte = 1
+
+ IO_TYPE_INOUT byte = 2
+)
+
+type execRetInfo struct {
+ // param
+ outParamDatas [][]byte
+
+ // rs
+ hasResultSet bool
+
+ rsDatas [][][]byte
+
+ rsSizeof int // 结果集数据占用多少空间,(消息中结果集起始位置到 rsCacheOffset
+ // 的空间大小,这和实际的rsDatas占用空间大小有一定出入,这里粗略估算,用于结果集缓存时的空间管理)
+
+ rsCacheOffset int32 // 缓存信息,在响应消息体中的偏移,0表示不存在,仅结果集缓存中可以用
+
+ rsBdta bool
+
+ rsUpdatable bool
+
+ rsRowIds []int64
+
+ // rs cache
+ tbIds []int32
+
+ tbTss []int64
+
+ // print
+ printLen int32
+
+ printMsg string
+
+ // explain
+ explain string
+
+ // 影响行数
+ updateCount int64 // Insert/Update/Delet影响行数, select结果集的总行数
+
+ updateCounts []int64 // 批量影响行数
+
+ // 键
+ rowid int64
+
+ lastInsertId int64
+
+ // other
+ retSqlType int16 // 执行返回的语句类型
+
+ execId int32
+}
+
+type column struct {
+ typeName string
+
+ colType int32
+
+ prec int32
+
+ scale int32
+
+ name string
+
+ tableName string
+
+ schemaName string
+
+ nullable bool
+
+ identity bool
+
+ readonly bool // 是否只读
+
+ baseName string
+
+ // lob info
+ lob bool
+
+ lobTabId int32
+
+ lobColId int16
+
+ // 用于描述ARRAY、STRUCT类型的特有描述信息
+ typeDescriptor *TypeDescriptor
+
+ isBdta bool
+}
+
+type parameter struct {
+ column
+
+ typeFlag byte
+
+ ioType byte
+
+ outJType int32
+
+ outScale int32
+
+ outObjectName string
+
+ cursorStmt *DmStatement
+}
+
+func (column *column) InitColumn() *column {
+ column.typeName = ""
+
+ column.colType = 0
+
+ column.prec = 0
+
+ column.scale = 0
+
+ column.name = ""
+
+ column.tableName = ""
+
+ column.schemaName = ""
+
+ column.nullable = false
+
+ column.identity = false
+
+ column.readonly = false
+
+ column.baseName = ""
+
+ // lob info
+ column.lob = false
+
+ column.lobTabId = 0
+
+ column.lobColId = 0
+
+ // 用于描述ARRAY、STRUCT类型的特有描述信息
+ column.typeDescriptor = nil
+
+ column.isBdta = false
+
+ return column
+}
+
+func (parameter *parameter) InitParameter() *parameter {
+ parameter.InitColumn()
+
+ parameter.typeFlag = TYPE_FLAG_UNKNOWN
+
+ parameter.ioType = IO_TYPE_IN
+
+ parameter.outJType = IGNORE_TARGET_TYPE
+
+ parameter.outScale = IGNORE_TARGET_SCALE
+
+ parameter.outObjectName = ""
+
+ parameter.cursorStmt = nil
+
+ return parameter
+}
+
+func (execInfo *execRetInfo) union(other *execRetInfo, startRow int, count int) {
+ if count == 1 {
+ execInfo.updateCounts[startRow] = other.updateCount
+ } else if execInfo.updateCounts != nil {
+ copy(execInfo.updateCounts[startRow:startRow+count], other.updateCounts[0:count])
+ }
+ if execInfo.outParamDatas != nil {
+ execInfo.outParamDatas = append(execInfo.outParamDatas, other.outParamDatas...)
+ }
+}
+
+func NewExceInfo() *execRetInfo {
+
+ execInfo := execRetInfo{}
+
+ execInfo.outParamDatas = nil
+
+ execInfo.hasResultSet = false
+
+ execInfo.rsDatas = nil
+
+ execInfo.rsSizeof = 0
+
+ execInfo.rsCacheOffset = 0
+
+ execInfo.rsBdta = false
+
+ execInfo.rsUpdatable = false
+
+ execInfo.rsRowIds = nil
+
+ execInfo.tbIds = nil
+
+ execInfo.tbTss = nil
+
+ execInfo.printLen = 0
+
+ execInfo.printMsg = ""
+
+ execInfo.explain = ""
+
+ execInfo.updateCount = 0
+
+ execInfo.updateCounts = nil
+
+ execInfo.rowid = -1
+
+ execInfo.lastInsertId = 0
+ // other
+ execInfo.retSqlType = -1 // 执行返回的语句类型
+
+ execInfo.execId = 0
+
+ return &execInfo
+}
diff --git a/dmr/zc.go b/dmr/zc.go
new file mode 100644
index 0000000..ec3a6ed
--- /dev/null
+++ b/dmr/zc.go
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "context"
+ "database/sql/driver"
+ "reflect"
+ "sync"
+ "sync/atomic"
+ "time"
+)
+
+type filter interface {
+ DmDriverOpen(filterChain *filterChain, d *DmDriver, dsn string) (*DmConnection, error)
+ DmDriverOpenConnector(filterChain *filterChain, d *DmDriver, dsn string) (*DmConnector, error)
+
+ DmConnectorConnect(filterChain *filterChain, c *DmConnector, ctx context.Context) (*DmConnection, error)
+ DmConnectorDriver(filterChain *filterChain, c *DmConnector) *DmDriver
+
+ DmConnectionBegin(filterChain *filterChain, c *DmConnection) (*DmConnection, error)
+ DmConnectionBeginTx(filterChain *filterChain, c *DmConnection, ctx context.Context, opts driver.TxOptions) (*DmConnection, error)
+ DmConnectionCommit(filterChain *filterChain, c *DmConnection) error
+ DmConnectionRollback(filterChain *filterChain, c *DmConnection) error
+ DmConnectionClose(filterChain *filterChain, c *DmConnection) error
+ DmConnectionPing(filterChain *filterChain, c *DmConnection, ctx context.Context) error
+ DmConnectionExec(filterChain *filterChain, c *DmConnection, query string, args []driver.Value) (*DmResult, error)
+ DmConnectionExecContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (*DmResult, error)
+ DmConnectionQuery(filterChain *filterChain, c *DmConnection, query string, args []driver.Value) (*DmRows, error)
+ DmConnectionQueryContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (*DmRows, error)
+ DmConnectionPrepare(filterChain *filterChain, c *DmConnection, query string) (*DmStatement, error)
+ DmConnectionPrepareContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string) (*DmStatement, error)
+ DmConnectionResetSession(filterChain *filterChain, c *DmConnection, ctx context.Context) error
+ DmConnectionCheckNamedValue(filterChain *filterChain, c *DmConnection, nv *driver.NamedValue) error
+
+ DmStatementClose(filterChain *filterChain, s *DmStatement) error
+ DmStatementNumInput(filterChain *filterChain, s *DmStatement) int
+ DmStatementExec(filterChain *filterChain, s *DmStatement, args []driver.Value) (*DmResult, error)
+ DmStatementExecContext(filterChain *filterChain, s *DmStatement, ctx context.Context, args []driver.NamedValue) (*DmResult, error)
+ DmStatementQuery(filterChain *filterChain, s *DmStatement, args []driver.Value) (*DmRows, error)
+ DmStatementQueryContext(filterChain *filterChain, s *DmStatement, ctx context.Context, args []driver.NamedValue) (*DmRows, error)
+ DmStatementCheckNamedValue(filterChain *filterChain, s *DmStatement, nv *driver.NamedValue) error
+
+ DmResultLastInsertId(filterChain *filterChain, r *DmResult) (int64, error)
+ DmResultRowsAffected(filterChain *filterChain, r *DmResult) (int64, error)
+
+ DmRowsColumns(filterChain *filterChain, r *DmRows) []string
+ DmRowsClose(filterChain *filterChain, r *DmRows) error
+ DmRowsNext(filterChain *filterChain, r *DmRows, dest []driver.Value) error
+ DmRowsHasNextResultSet(filterChain *filterChain, r *DmRows) bool
+ DmRowsNextResultSet(filterChain *filterChain, r *DmRows) error
+ DmRowsColumnTypeScanType(filterChain *filterChain, r *DmRows, index int) reflect.Type
+ DmRowsColumnTypeDatabaseTypeName(filterChain *filterChain, r *DmRows, index int) string
+ DmRowsColumnTypeLength(filterChain *filterChain, r *DmRows, index int) (length int64, ok bool)
+ DmRowsColumnTypeNullable(filterChain *filterChain, r *DmRows, index int) (nullable, ok bool)
+ DmRowsColumnTypePrecisionScale(filterChain *filterChain, r *DmRows, index int) (precision, scale int64, ok bool)
+}
+
+type IDGenerator int64
+
+var dmDriverIDGenerator = new(IDGenerator)
+var dmConntorIDGenerator = new(IDGenerator)
+var dmConnIDGenerator = new(IDGenerator)
+var dmStmtIDGenerator = new(IDGenerator)
+var dmResultIDGenerator = new(IDGenerator)
+var dmRowsIDGenerator = new(IDGenerator)
+
+func (g *IDGenerator) incrementAndGet() int64 {
+ return atomic.AddInt64((*int64)(g), 1)
+}
+
+type RWSiteEnum int
+
+const (
+ PRIMARY RWSiteEnum = iota
+ STANDBY
+ ANYSITE
+)
+
+var (
+ goMapMu sync.RWMutex
+ goMap = make(map[string]goRun, 2)
+)
+
+type filterable struct {
+ filterChain *filterChain
+ rwInfo *rwInfo
+ logInfo *logInfo
+ recoverInfo *recoverInfo
+ statInfo *statInfo
+ objId int64
+ idGenerator *IDGenerator
+}
+
+func runLog() {
+ goMapMu.Lock()
+ _, ok := goMap["log"]
+ if !ok {
+ goMap["log"] = &logWriter{
+ flushQueue: make(chan []byte, LogFlushQueueSize),
+ date: time.Now().Format("2006-01-02"),
+ logFile: nil,
+ flushFreq: LogFlushFreq,
+ filePath: LogDir,
+ filePrefix: "dm_go",
+ buffer: Dm_build_1503(),
+ }
+ go goMap["log"].doRun()
+ }
+ goMapMu.Unlock()
+}
+
+func runStat() {
+ goMapMu.Lock()
+ _, ok := goMap["stat"]
+ if !ok {
+ goMap["stat"] = newStatFlusher()
+ go goMap["stat"].doRun()
+ }
+ goMapMu.Unlock()
+}
+
+func (f *filterable) createFilterChain(bc *DmConnector, props *Properties) {
+ var filters = make([]filter, 0, 5)
+
+ if bc != nil {
+ if LogLevel != LOG_OFF {
+ filters = append(filters, &logFilter{})
+ f.logInfo = &logInfo{logRecord: new(LogRecord)}
+ runLog()
+ }
+
+ if StatEnable {
+ filters = append(filters, &statFilter{})
+ f.statInfo = newStatInfo()
+ goStatMu.Lock()
+ if goStat == nil {
+ goStat = newGoStat(1000)
+ }
+ goStatMu.Unlock()
+ runStat()
+ }
+
+ if bc.doSwitch != DO_SWITCH_OFF {
+ filters = append(filters, &reconnectFilter{})
+ }
+
+ if bc.rwSeparate {
+ filters = append(filters, &rwFilter{})
+ f.rwInfo = newRwInfo()
+ }
+ } else if props != nil {
+ if ParseLogLevel(props) != LOG_OFF {
+ filters = append(filters, &logFilter{})
+ f.logInfo = &logInfo{logRecord: new(LogRecord)}
+ runLog()
+ }
+
+ if props.GetBool("statEnable", StatEnable) {
+ filters = append(filters, &statFilter{})
+ f.statInfo = newStatInfo()
+ goStatMu.Lock()
+ if goStat == nil {
+ goStat = newGoStat(1000)
+ }
+ goStatMu.Unlock()
+ runStat()
+ }
+
+ if props.GetInt(DoSwitchKey, int(DO_SWITCH_OFF), 0, 2) != int(DO_SWITCH_OFF) {
+ filters = append(filters, &reconnectFilter{})
+ f.recoverInfo = newRecoverInfo()
+ }
+
+ if props.GetBool("rwSeparate", false) {
+ filters = append(filters, &rwFilter{})
+ f.rwInfo = newRwInfo()
+ }
+ }
+
+ f.filterChain = newFilterChain(filters)
+}
+
+func (f *filterable) resetFilterable(src *filterable) {
+ f.filterChain = src.filterChain
+ f.logInfo = src.logInfo
+ f.rwInfo = src.rwInfo
+ f.statInfo = src.statInfo
+}
+
+func (f filterable) getID() int64 {
+ if f.objId < 0 {
+ f.objId = f.idGenerator.incrementAndGet()
+ }
+ return f.objId
+}
+
+type logInfo struct {
+ logRecord *LogRecord
+ lastExecuteStartNano time.Time
+}
+
+type rwInfo struct {
+ distribute RWSiteEnum
+
+ rwCounter *rwCounter
+
+ connStandby *DmConnection
+
+ connCurrent *DmConnection
+
+ tryRecoverTs int64
+
+ stmtStandby *DmStatement
+
+ stmtCurrent *DmStatement
+
+ readOnly bool
+}
+
+func newRwInfo() *rwInfo {
+ rwInfo := new(rwInfo)
+ rwInfo.distribute = PRIMARY
+ rwInfo.readOnly = true
+ return rwInfo
+}
+
+func (rwi *rwInfo) cleanup() {
+ rwi.distribute = PRIMARY
+ rwi.rwCounter = nil
+ rwi.connStandby = nil
+ rwi.connCurrent = nil
+ rwi.stmtStandby = nil
+ rwi.stmtCurrent = nil
+}
+
+func (rwi *rwInfo) toPrimary() RWSiteEnum {
+ if rwi.distribute != PRIMARY {
+
+ rwi.rwCounter.countPrimary()
+ }
+ rwi.distribute = PRIMARY
+ return rwi.distribute
+}
+
+func (rwi *rwInfo) toAny() RWSiteEnum {
+
+ rwi.distribute = rwi.rwCounter.count(ANYSITE, rwi.connStandby)
+ return rwi.distribute
+}
+
+type recoverInfo struct {
+ checkEpRecoverTs int64
+}
+
+func newRecoverInfo() *recoverInfo {
+ recoverInfo := new(recoverInfo)
+ recoverInfo.checkEpRecoverTs = 0
+ return recoverInfo
+}
+
+type statInfo struct {
+ constructNano int64
+
+ connStat *connectionStat
+
+ lastExecuteStartNano int64
+
+ lastExecuteTimeNano int64
+
+ lastExecuteType ExecuteTypeEnum
+
+ firstResultSet bool
+
+ lastExecuteSql string
+
+ sqlStat *sqlStat
+
+ sql string
+
+ cursorIndex int
+
+ closeCount int
+
+ readStringLength int64
+
+ readBytesLength int64
+
+ openInputStreamCount int
+
+ openReaderCount int
+}
+
+var (
+ goStatMu sync.RWMutex
+ goStat *GoStat
+)
+
+func newStatInfo() *statInfo {
+ si := new(statInfo)
+ return si
+}
+func (si *statInfo) init(conn *DmConnection) {
+ si.connStat = goStat.createConnStat(conn)
+}
+
+func (si *statInfo) setConstructNano() {
+ si.constructNano = time.Now().UnixNano()
+}
+
+func (si *statInfo) getConstructNano() int64 {
+ return si.constructNano
+}
+
+func (si *statInfo) getConnStat() *connectionStat {
+ return si.connStat
+}
+
+func (si *statInfo) getLastExecuteStartNano() int64 {
+ return si.lastExecuteStartNano
+}
+
+func (si *statInfo) setLastExecuteStartNano(lastExecuteStartNano int64) {
+ si.lastExecuteStartNano = lastExecuteStartNano
+}
+
+func (si *statInfo) getLastExecuteTimeNano() int64 {
+ return si.lastExecuteTimeNano
+}
+
+func (si *statInfo) setLastExecuteTimeNano(lastExecuteTimeNano int64) {
+ si.lastExecuteTimeNano = lastExecuteTimeNano
+}
+
+func (si *statInfo) getLastExecuteType() ExecuteTypeEnum {
+ return si.lastExecuteType
+}
+
+func (si *statInfo) setLastExecuteType(lastExecuteType ExecuteTypeEnum) {
+ si.lastExecuteType = lastExecuteType
+}
+
+func (si *statInfo) isFirstResultSet() bool {
+ return si.firstResultSet
+}
+
+func (si *statInfo) setFirstResultSet(firstResultSet bool) {
+ si.firstResultSet = firstResultSet
+}
+
+func (si *statInfo) getLastExecuteSql() string {
+ return si.lastExecuteSql
+}
+
+func (si *statInfo) setLastExecuteSql(lastExecuteSql string) {
+ si.lastExecuteSql = lastExecuteSql
+}
+
+func (si *statInfo) getSqlStat() *sqlStat {
+ return si.sqlStat
+}
+
+func (si *statInfo) setSqlStat(sqlStat *sqlStat) {
+ si.sqlStat = sqlStat
+}
+
+func (si *statInfo) setConnStat(connStat *connectionStat) {
+ si.connStat = connStat
+}
+
+func (si *statInfo) setConstructNanoWithConstructNano(constructNano int64) {
+ si.constructNano = constructNano
+}
+
+func (si *statInfo) afterExecute(nanoSpan int64) {
+ si.lastExecuteTimeNano = nanoSpan
+}
+
+func (si *statInfo) beforeExecute() {
+ si.lastExecuteStartNano = time.Now().UnixNano()
+}
+
+func (si *statInfo) getSql() string {
+ return si.sql
+}
+
+func (si *statInfo) setSql(sql string) {
+ si.sql = sql
+}
+
+func (si *statInfo) getCursorIndex() int {
+ return si.cursorIndex
+}
+
+func (si *statInfo) setCursorIndex(cursorIndex int) {
+ si.cursorIndex = cursorIndex
+}
+
+func (si *statInfo) getCloseCount() int {
+ return si.closeCount
+}
+
+func (si *statInfo) setCloseCount(closeCount int) {
+ si.closeCount = closeCount
+}
+
+func (si *statInfo) getReadStringLength() int64 {
+ return si.readStringLength
+}
+
+func (si *statInfo) setReadStringLength(readStringLength int64) {
+ si.readStringLength = readStringLength
+}
+
+func (si *statInfo) getReadBytesLength() int64 {
+ return si.readBytesLength
+}
+
+func (si *statInfo) setReadBytesLength(readBytesLength int64) {
+ si.readBytesLength = readBytesLength
+}
+
+func (si *statInfo) getOpenInputStreamCount() int {
+ return si.openInputStreamCount
+}
+
+func (si *statInfo) setOpenInputStreamCount(openInputStreamCount int) {
+ si.openInputStreamCount = openInputStreamCount
+}
+
+func (si *statInfo) getOpenReaderCount() int {
+ return si.openReaderCount
+}
+
+func (si *statInfo) setOpenReaderCount(openReaderCount int) {
+ si.openReaderCount = openReaderCount
+}
+
+func (si *statInfo) incrementCloseCount() {
+ si.closeCount++
+}
diff --git a/dmr/zd.go b/dmr/zd.go
new file mode 100644
index 0000000..4201579
--- /dev/null
+++ b/dmr/zd.go
@@ -0,0 +1,403 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import (
+ "context"
+ "database/sql/driver"
+ "reflect"
+)
+
+type filterChain struct {
+ filters []filter
+ fpos int
+}
+
+func newFilterChain(filters []filter) *filterChain {
+ fc := new(filterChain)
+ fc.filters = filters
+ fc.fpos = 0
+ return fc
+}
+
+func (filterChain *filterChain) reset() *filterChain {
+ filterChain.fpos = 0
+ return filterChain
+}
+
+func (filterChain *filterChain) DmDriverOpen(d *DmDriver, dsn string) (*DmConnection, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmDriverOpen(filterChain, d, dsn)
+ }
+
+ return d.open(dsn)
+}
+
+func (filterChain *filterChain) DmDriverOpenConnector(d *DmDriver, dsn string) (*DmConnector, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmDriverOpenConnector(filterChain, d, dsn)
+ }
+
+ return d.openConnector(dsn)
+}
+
+//DmConnector
+func (filterChain *filterChain) DmConnectorConnect(c *DmConnector, ctx context.Context) (*DmConnection, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectorConnect(filterChain, c, ctx)
+ }
+
+ return c.connect(ctx)
+}
+
+func (filterChain *filterChain) DmConnectorDriver(c *DmConnector) *DmDriver {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectorDriver(filterChain, c)
+ }
+
+ return c.driver()
+}
+
+//DmConnection
+func (filterChain *filterChain) DmConnectionBegin(c *DmConnection) (*DmConnection, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectionBegin(filterChain, c)
+ }
+
+ return c.begin()
+}
+func (filterChain *filterChain) DmConnectionBeginTx(c *DmConnection, ctx context.Context, opts driver.TxOptions) (*DmConnection, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectionBeginTx(filterChain, c, ctx, opts)
+ }
+
+ return c.beginTx(ctx, opts)
+}
+
+func (filterChain *filterChain) DmConnectionCommit(c *DmConnection) error {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectionCommit(filterChain, c)
+ }
+
+ return c.commit()
+}
+
+func (filterChain *filterChain) DmConnectionRollback(c *DmConnection) error {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectionRollback(filterChain, c)
+ }
+
+ return c.rollback()
+}
+
+func (filterChain *filterChain) DmConnectionClose(c *DmConnection) error {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectionClose(filterChain, c)
+ }
+
+ return c.close()
+}
+
+func (filterChain *filterChain) DmConnectionPing(c *DmConnection, ctx context.Context) error {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectionPing(filterChain, c, ctx)
+ }
+
+ return c.ping(ctx)
+}
+
+func (filterChain *filterChain) DmConnectionExec(c *DmConnection, query string, args []driver.Value) (*DmResult, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectionExec(filterChain, c, query, args)
+ }
+
+ return c.exec(query, args)
+}
+
+func (filterChain *filterChain) DmConnectionExecContext(c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (*DmResult, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectionExecContext(filterChain, c, ctx, query, args)
+ }
+
+ return c.execContext(ctx, query, args)
+}
+
+func (filterChain *filterChain) DmConnectionQuery(c *DmConnection, query string, args []driver.Value) (*DmRows, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectionQuery(filterChain, c, query, args)
+ }
+
+ return c.query(query, args)
+}
+
+func (filterChain *filterChain) DmConnectionQueryContext(c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (*DmRows, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectionQueryContext(filterChain, c, ctx, query, args)
+ }
+
+ return c.queryContext(ctx, query, args)
+}
+
+func (filterChain *filterChain) DmConnectionPrepare(c *DmConnection, query string) (*DmStatement, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectionPrepare(filterChain, c, query)
+ }
+
+ return c.prepare(query)
+}
+
+func (filterChain *filterChain) DmConnectionPrepareContext(c *DmConnection, ctx context.Context, query string) (*DmStatement, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectionPrepareContext(filterChain, c, ctx, query)
+ }
+
+ return c.prepareContext(ctx, query)
+}
+
+func (filterChain *filterChain) DmConnectionResetSession(c *DmConnection, ctx context.Context) error {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectionResetSession(filterChain, c, ctx)
+ }
+
+ return c.resetSession(ctx)
+}
+
+func (filterChain *filterChain) DmConnectionCheckNamedValue(c *DmConnection, nv *driver.NamedValue) error {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmConnectionCheckNamedValue(filterChain, c, nv)
+ }
+
+ return c.checkNamedValue(nv)
+}
+
+//DmStatement
+func (filterChain *filterChain) DmStatementClose(s *DmStatement) error {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmStatementClose(filterChain, s)
+ }
+
+ return s.close()
+}
+
+func (filterChain *filterChain) DmStatementNumInput(s *DmStatement) int {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmStatementNumInput(filterChain, s)
+ }
+
+ return s.numInput()
+}
+
+func (filterChain *filterChain) DmStatementExec(s *DmStatement, args []driver.Value) (*DmResult, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmStatementExec(filterChain, s, args)
+ }
+
+ return s.exec(args)
+}
+
+func (filterChain *filterChain) DmStatementExecContext(s *DmStatement, ctx context.Context, args []driver.NamedValue) (*DmResult, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmStatementExecContext(filterChain, s, ctx, args)
+ }
+
+ return s.execContext(ctx, args)
+}
+
+func (filterChain *filterChain) DmStatementQuery(s *DmStatement, args []driver.Value) (*DmRows, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmStatementQuery(filterChain, s, args)
+ }
+
+ return s.query(args)
+}
+
+func (filterChain *filterChain) DmStatementQueryContext(s *DmStatement, ctx context.Context, args []driver.NamedValue) (*DmRows, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmStatementQueryContext(filterChain, s, ctx, args)
+ }
+
+ return s.queryContext(ctx, args)
+}
+
+func (filterChain *filterChain) DmStatementCheckNamedValue(s *DmStatement, nv *driver.NamedValue) error {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmStatementCheckNamedValue(filterChain, s, nv)
+ }
+
+ return s.checkNamedValue(nv)
+}
+
+//DmResult
+func (filterChain *filterChain) DmResultLastInsertId(r *DmResult) (int64, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmResultLastInsertId(filterChain, r)
+ }
+
+ return r.lastInsertId()
+}
+
+func (filterChain *filterChain) DmResultRowsAffected(r *DmResult) (int64, error) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmResultRowsAffected(filterChain, r)
+ }
+
+ return r.rowsAffected()
+}
+
+//DmRows
+func (filterChain *filterChain) DmRowsColumns(r *DmRows) []string {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmRowsColumns(filterChain, r)
+ }
+
+ return r.columns()
+}
+
+func (filterChain *filterChain) DmRowsClose(r *DmRows) error {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmRowsClose(filterChain, r)
+ }
+
+ return r.close()
+}
+
+func (filterChain *filterChain) DmRowsNext(r *DmRows, dest []driver.Value) error {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmRowsNext(filterChain, r, dest)
+ }
+
+ return r.next(dest)
+}
+
+func (filterChain *filterChain) DmRowsHasNextResultSet(r *DmRows) bool {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmRowsHasNextResultSet(filterChain, r)
+ }
+
+ return r.hasNextResultSet()
+}
+
+func (filterChain *filterChain) DmRowsNextResultSet(r *DmRows) error {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmRowsNextResultSet(filterChain, r)
+ }
+
+ return r.nextResultSet()
+}
+
+func (filterChain *filterChain) DmRowsColumnTypeScanType(r *DmRows, index int) reflect.Type {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmRowsColumnTypeScanType(filterChain, r, index)
+ }
+
+ return r.columnTypeScanType(index)
+}
+
+func (filterChain *filterChain) DmRowsColumnTypeDatabaseTypeName(r *DmRows, index int) string {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmRowsColumnTypeDatabaseTypeName(filterChain, r, index)
+ }
+
+ return r.columnTypeDatabaseTypeName(index)
+}
+
+func (filterChain *filterChain) DmRowsColumnTypeLength(r *DmRows, index int) (length int64, ok bool) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmRowsColumnTypeLength(filterChain, r, index)
+ }
+
+ return r.columnTypeLength(index)
+}
+
+func (filterChain *filterChain) DmRowsColumnTypeNullable(r *DmRows, index int) (nullable, ok bool) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmRowsColumnTypeNullable(filterChain, r, index)
+ }
+
+ return r.columnTypeNullable(index)
+}
+
+func (filterChain *filterChain) DmRowsColumnTypePrecisionScale(r *DmRows, index int) (precision, scale int64, ok bool) {
+ if filterChain.fpos < len(filterChain.filters) {
+ f := filterChain.filters[filterChain.fpos]
+ filterChain.fpos++
+ return f.DmRowsColumnTypePrecisionScale(filterChain, r, index)
+ }
+
+ return r.columnTypePrecisionScale(index)
+}
diff --git a/dmr/ze.go b/dmr/ze.go
new file mode 100644
index 0000000..7bb1bb1
--- /dev/null
+++ b/dmr/ze.go
@@ -0,0 +1,871 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import (
+ "context"
+ "database/sql/driver"
+ "reflect"
+ "strconv"
+ "time"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+type logFilter struct{}
+
+func (filter *logFilter) DmDriverOpen(filterChain *filterChain, d *DmDriver, dsn string) (ret *DmConnection, err error) {
+ var logRecord = d.logInfo.logRecord
+ logRecord.Set(d, "open", dsn)
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ ret, err = filterChain.DmDriverOpen(d, dsn)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmDriverOpenConnector(filterChain *filterChain, d *DmDriver, dsn string) (ret *DmConnector, err error) {
+ var logRecord = d.logInfo.logRecord
+ logRecord.Set(d, "openConnector", dsn)
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ ret, err = filterChain.DmDriverOpenConnector(d, dsn)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmConnectorConnect(filterChain *filterChain, c *DmConnector, ctx context.Context) (ret *DmConnection, err error) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "connect")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ ret, err = filterChain.DmConnectorConnect(c, ctx)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmConnectorDriver(filterChain *filterChain, c *DmConnector) (ret *DmDriver) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "dmr")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ ret = filterChain.DmConnectorDriver(c)
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmConnectionBegin(filterChain *filterChain, c *DmConnection) (ret *DmConnection, err error) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "begin")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ ret, err = filterChain.DmConnectionBegin(c)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmConnectionBeginTx(filterChain *filterChain, c *DmConnection, ctx context.Context, opts driver.TxOptions) (ret *DmConnection, err error) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "beginTx", opts)
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ ret, err = filterChain.DmConnectionBeginTx(c, ctx, opts)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmConnectionCommit(filterChain *filterChain, c *DmConnection) (err error) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "commit")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ err = filterChain.DmConnectionCommit(c)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ return
+}
+
+func (filter *logFilter) DmConnectionRollback(filterChain *filterChain, c *DmConnection) (err error) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "rollback")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ err = filterChain.DmConnectionRollback(c)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ return
+}
+
+func (filter *logFilter) DmConnectionClose(filterChain *filterChain, c *DmConnection) (err error) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "close")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ err = filterChain.DmConnectionClose(c)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ return
+}
+
+func (filter *logFilter) DmConnectionPing(filterChain *filterChain, c *DmConnection, ctx context.Context) (err error) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "ping")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ err = filterChain.DmConnectionPing(c, ctx)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ return
+}
+
+func (filter *logFilter) DmConnectionExec(filterChain *filterChain, c *DmConnection, query string, args []driver.Value) (ret *DmResult, err error) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "executeByStmt", query, args)
+ defer func() {
+ filter.executeAfter(c.logInfo, logRecord)
+ filter.doLog(logRecord)
+ }()
+ logRecord.SetSql(query)
+ filter.executeBefore(c.logInfo)
+ ret, err = filterChain.DmConnectionExec(c, query, args)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmConnectionExecContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (ret *DmResult, err error) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "executeCtx", query, args)
+ defer func() {
+ filter.executeAfter(c.logInfo, logRecord)
+ filter.doLog(logRecord)
+ }()
+ logRecord.SetSql(query)
+ filter.executeBefore(c.logInfo)
+ ret, err = filterChain.DmConnectionExecContext(c, ctx, query, args)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmConnectionQuery(filterChain *filterChain, c *DmConnection, query string, args []driver.Value) (ret *DmRows, err error) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "query", query, args)
+ defer func() {
+ filter.executeAfter(c.logInfo, logRecord)
+ filter.doLog(logRecord)
+ }()
+ logRecord.SetSql(query)
+ filter.executeBefore(c.logInfo)
+ ret, err = filterChain.DmConnectionQuery(c, query, args)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmConnectionQueryContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (ret *DmRows, err error) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "queryCtx", query, args)
+ defer func() {
+ filter.executeAfter(c.logInfo, logRecord)
+ filter.doLog(logRecord)
+ }()
+ logRecord.SetSql(query)
+ filter.executeBefore(c.logInfo)
+ ret, err = filterChain.DmConnectionQueryContext(c, ctx, query, args)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmConnectionPrepare(filterChain *filterChain, c *DmConnection, query string) (ret *DmStatement, err error) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "prepareStatement", query)
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ logRecord.SetSql(query)
+ ret, err = filterChain.DmConnectionPrepare(c, query)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmConnectionPrepareContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string) (ret *DmStatement, err error) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "prepareStatementCtx", query)
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ logRecord.SetSql(query)
+ ret, err = filterChain.DmConnectionPrepareContext(c, ctx, query)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmConnectionResetSession(filterChain *filterChain, c *DmConnection, ctx context.Context) (err error) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "resetSession")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ err = filterChain.DmConnectionResetSession(c, ctx)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ return
+}
+
+func (filter *logFilter) DmConnectionCheckNamedValue(filterChain *filterChain, c *DmConnection, nv *driver.NamedValue) (err error) {
+ var logRecord = c.logInfo.logRecord
+ logRecord.Set(c, "checkNamedValue", nv)
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ err = filterChain.DmConnectionCheckNamedValue(c, nv)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ return
+}
+
+func (filter *logFilter) DmStatementClose(filterChain *filterChain, s *DmStatement) (err error) {
+ var logRecord = s.logInfo.logRecord
+ logRecord.Set(s, "close")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ err = filterChain.DmStatementClose(s)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ return
+}
+
+func (filter *logFilter) DmStatementNumInput(filterChain *filterChain, s *DmStatement) (ret int) {
+ var logRecord = s.logInfo.logRecord
+ logRecord.Set(s, "numInput")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ ret = filterChain.DmStatementNumInput(s)
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmStatementExec(filterChain *filterChain, s *DmStatement, args []driver.Value) (ret *DmResult, err error) {
+ var logRecord = s.logInfo.logRecord
+ logRecord.Set(s, "executeByStmt", args)
+ defer func() {
+ filter.executeAfter(s.logInfo, logRecord)
+ filter.doLog(logRecord)
+ }()
+ logRecord.SetSql(s.nativeSql)
+ filter.executeBefore(s.logInfo)
+ ret, err = filterChain.DmStatementExec(s, args)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmStatementExecContext(filterChain *filterChain, s *DmStatement, ctx context.Context, args []driver.NamedValue) (ret *DmResult, err error) {
+ var logRecord = s.logInfo.logRecord
+ logRecord.Set(s, "executeCtx", args)
+ defer func() {
+ filter.executeAfter(s.logInfo, logRecord)
+ filter.doLog(logRecord)
+ }()
+ logRecord.SetSql(s.nativeSql)
+ filter.executeBefore(s.logInfo)
+ ret, err = filterChain.DmStatementExecContext(s, ctx, args)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmStatementQuery(filterChain *filterChain, s *DmStatement, args []driver.Value) (ret *DmRows, err error) {
+ var logRecord = s.logInfo.logRecord
+ logRecord.Set(s, "query", args)
+ defer func() {
+ filter.executeAfter(s.logInfo, logRecord)
+ filter.doLog(logRecord)
+ }()
+ logRecord.SetSql(s.nativeSql)
+ filter.executeBefore(s.logInfo)
+ ret, err = filterChain.DmStatementQuery(s, args)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmStatementQueryContext(filterChain *filterChain, s *DmStatement, ctx context.Context, args []driver.NamedValue) (ret *DmRows, err error) {
+ var logRecord = s.logInfo.logRecord
+ logRecord.Set(s, "queryCtx", args)
+ defer func() {
+ filter.executeAfter(s.logInfo, logRecord)
+ filter.doLog(logRecord)
+ }()
+ logRecord.SetSql(s.nativeSql)
+ filter.executeBefore(s.logInfo)
+ ret, err = filterChain.DmStatementQueryContext(s, ctx, args)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmStatementCheckNamedValue(filterChain *filterChain, s *DmStatement, nv *driver.NamedValue) (err error) {
+ var logRecord = s.logInfo.logRecord
+ logRecord.Set(s, "checkNamedValue", nv)
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ err = filterChain.DmStatementCheckNamedValue(s, nv)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ return
+}
+
+func (filter *logFilter) DmResultLastInsertId(filterChain *filterChain, r *DmResult) (ret int64, err error) {
+ var logRecord = r.logInfo.logRecord
+ logRecord.Set(r, "lastInsertId")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ ret, err = filterChain.DmResultLastInsertId(r)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmResultRowsAffected(filterChain *filterChain, r *DmResult) (ret int64, err error) {
+ var logRecord = r.logInfo.logRecord
+ logRecord.Set(r, "rowsAffected")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ ret, err = filterChain.DmResultRowsAffected(r)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmRowsColumns(filterChain *filterChain, r *DmRows) (ret []string) {
+ var logRecord = r.logInfo.logRecord
+ logRecord.Set(r, "columns")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ ret = filterChain.DmRowsColumns(r)
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmRowsClose(filterChain *filterChain, r *DmRows) (err error) {
+ var logRecord = r.logInfo.logRecord
+ logRecord.Set(r, "close")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ err = filterChain.DmRowsClose(r)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ return
+}
+
+func (filter *logFilter) DmRowsNext(filterChain *filterChain, r *DmRows, dest []driver.Value) (err error) {
+ var logRecord = r.logInfo.logRecord
+ logRecord.Set(r, "next", dest)
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ err = filterChain.DmRowsNext(r, dest)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ return
+}
+
+func (filter *logFilter) DmRowsHasNextResultSet(filterChain *filterChain, r *DmRows) (ret bool) {
+ var logRecord = r.logInfo.logRecord
+ logRecord.Set(r, "hasNextResultSet")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ ret = filterChain.DmRowsHasNextResultSet(r)
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmRowsNextResultSet(filterChain *filterChain, r *DmRows) (err error) {
+ var logRecord = r.logInfo.logRecord
+ logRecord.Set(r, "nextResultSet")
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ err = filterChain.DmRowsNextResultSet(r)
+ if err != nil {
+ logRecord.SetError(err)
+ return
+ }
+ return
+}
+
+func (filter *logFilter) DmRowsColumnTypeScanType(filterChain *filterChain, r *DmRows, index int) (ret reflect.Type) {
+ var logRecord = r.logInfo.logRecord
+ logRecord.Set(r, "columnTypeScanType", index)
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ ret = filterChain.DmRowsColumnTypeScanType(r, index)
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmRowsColumnTypeDatabaseTypeName(filterChain *filterChain, r *DmRows, index int) (ret string) {
+ var logRecord = r.logInfo.logRecord
+ logRecord.Set(r, "columnTypeDatabaseTypeName", index)
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ ret = filterChain.DmRowsColumnTypeDatabaseTypeName(r, index)
+ logRecord.SetReturnValue(ret)
+ return
+}
+
+func (filter *logFilter) DmRowsColumnTypeLength(filterChain *filterChain, r *DmRows, index int) (length int64, ok bool) {
+ var logRecord = r.logInfo.logRecord
+ logRecord.Set(r, "columnTypeLength", index)
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ length, ok = filterChain.DmRowsColumnTypeLength(r, index)
+ if ok {
+ logRecord.SetReturnValue(length)
+ } else {
+ logRecord.SetReturnValue(-1)
+ }
+ return
+}
+
+func (filter *logFilter) DmRowsColumnTypeNullable(filterChain *filterChain, r *DmRows, index int) (nullable, ok bool) {
+ var logRecord = r.logInfo.logRecord
+ logRecord.Set(r, "columnTypeNullable", index)
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ nullable, ok = filterChain.DmRowsColumnTypeNullable(r, index)
+ if ok {
+ logRecord.SetReturnValue(nullable)
+ } else {
+ logRecord.SetReturnValue(false)
+ }
+ return
+}
+
+func (filter *logFilter) DmRowsColumnTypePrecisionScale(filterChain *filterChain, r *DmRows, index int) (precision, scale int64, ok bool) {
+ var logRecord = r.logInfo.logRecord
+ logRecord.Set(r, "columnTypePrecisionScale", index)
+ defer func() {
+ filter.doLog(logRecord)
+ }()
+ precision, scale, ok = filterChain.DmRowsColumnTypePrecisionScale(r, index)
+ if ok {
+ logRecord.SetReturnValue(strconv.FormatInt(precision, 10) + "&" + strconv.FormatInt(scale, 10))
+ } else {
+ logRecord.SetReturnValue("-1&-1")
+ }
+ return
+}
+
+func (filter *logFilter) executeBefore(logInfo *logInfo) {
+ if LogFilterLogger.IsSqlEnabled() {
+ logInfo.lastExecuteStartNano = time.Now()
+ }
+}
+
+func (filter *logFilter) executeAfter(logInfo *logInfo, record *LogRecord) {
+ if LogFilterLogger.IsSqlEnabled() {
+ record.SetUsedTime(time.Since(logInfo.lastExecuteStartNano))
+ }
+}
+
+func (filter *logFilter) doLog(record *LogRecord) {
+
+ if record == nil {
+ return
+ }
+ if record.GetError() != nil {
+ LogFilterLogger.ErrorWithErr(record.ToString(), record.GetError())
+ } else if record.GetSql() != "" && LogFilterLogger.IsSqlEnabled() {
+ LogFilterLogger.Sql(record.ToString())
+ } else {
+ LogFilterLogger.Info(record.ToString())
+ }
+}
+
+/************************************************************************************************************/
+type Logger struct {
+}
+
+var LogFilterLogger = &Logger{}
+var ConnLogger = &Logger{}
+var AccessLogger = &Logger{}
+
+func (logger Logger) IsDebugEnabled() bool {
+ return LogLevel >= LOG_DEBUG
+}
+func (logger Logger) IsErrorEnabled() bool {
+ return LogLevel >= LOG_ERROR
+}
+func (logger Logger) IsInfoEnabled() bool {
+ return LogLevel >= LOG_INFO
+}
+func (logger Logger) IsWarnEnabled() bool {
+ return LogLevel >= LOG_WARN
+}
+func (logger Logger) IsSqlEnabled() bool {
+ return LogLevel >= LOG_SQL
+}
+func (logger Logger) Debug(msg string) {
+ if logger.IsDebugEnabled() {
+ logger.println(logger.formatHead("DEBUG") + msg)
+ }
+}
+func (logger Logger) DebugWithErr(msg string, err error) {
+ if logger.IsDebugEnabled() {
+ if e, ok := err.(*DmError); ok {
+ logger.println(logger.formatHead("DEBUG") + msg + util.LINE_SEPARATOR + e.FormatStack())
+ } else {
+ logger.println(logger.formatHead("DEBUG") + msg + util.LINE_SEPARATOR + err.Error())
+ }
+ }
+}
+func (logger Logger) Info(msg string) {
+ if logger.IsInfoEnabled() {
+ logger.println(logger.formatHead("INFO ") + msg)
+ }
+}
+func (logger Logger) Sql(msg string) {
+ if logger.IsSqlEnabled() {
+ logger.println(logger.formatHead("SQL ") + msg)
+ }
+}
+func (logger Logger) Warn(msg string) {
+ if logger.IsWarnEnabled() {
+ logger.println(logger.formatHead("WARN ") + msg)
+ }
+}
+func (logger Logger) ErrorWithErr(msg string, err error) {
+ if e, ok := err.(*DmError); ok {
+ logger.println(logger.formatHead("ERROR") + msg + util.LINE_SEPARATOR + e.FormatStack())
+ } else {
+ logger.println(logger.formatHead("ERROR") + msg + util.LINE_SEPARATOR + err.Error())
+ }
+}
+
+//TODO: 获取goroutine objId
+func (logger Logger) formatHead(head string) string {
+ // return "[" + head + " - " + StringUtil.formatTime() + "] tid:" + Thread.currentThread().getId();
+ return "[" + head + " - " + util.StringUtil.FormatTime() + "]"
+}
+func (logger Logger) println(msg string) {
+ goMap["log"].(*logWriter).WriteLine(msg)
+}
+
+/*************************************************************************************************/
+func formatSource(source interface{}) string {
+ if source == nil {
+ return ""
+ }
+ var str string
+ switch src := source.(type) {
+ case string:
+ str += src
+ case *DmDriver:
+ str += formatDriver(src)
+ case *DmConnector:
+ str += formatContor(src)
+ case *DmConnection:
+ str += formatConn(src)
+ case *DmStatement:
+ str += formatConn(src.dmConn) + ", "
+ str += formatStmt(src)
+ case *DmResult:
+ str += formatConn(src.dmStmt.dmConn) + ", "
+ str += formatStmt(src.dmStmt) + ", "
+ str += formatRs(src)
+ case *DmRows:
+ str += formatConn(src.CurrentRows.dmStmt.dmConn) + ", "
+ str += formatStmt(src.CurrentRows.dmStmt) + ", "
+ str += formatRows(src)
+ default:
+ str += reflect.TypeOf(src).String() + "@" + reflect.ValueOf(src).Addr().String()
+ }
+ return str
+}
+
+func formatDriver(driver *DmDriver) string {
+ if driver != nil && driver.logInfo != nil {
+ return "dmr-" + strconv.FormatInt(driver.getID(), 10)
+ }
+ return "dmr-nil"
+}
+
+func formatContor(contor *DmConnector) string {
+ if contor != nil && contor.logInfo != nil {
+ return "contor-" + strconv.FormatInt(contor.getID(), 10)
+ }
+ return "contor-nil"
+}
+
+func formatConn(conn *DmConnection) string {
+ if conn != nil && conn.logInfo != nil {
+ return "conn-" + strconv.FormatInt(conn.getID(), 10)
+ }
+ return "conn-nil"
+}
+
+func formatStmt(stmt *DmStatement) string {
+ if stmt != nil && stmt.logInfo != nil {
+ return "stmt-" + strconv.FormatInt(stmt.getID(), 10)
+ }
+ return "stmt-nil"
+}
+
+func formatRs(result *DmResult) string {
+ if result != nil && result.logInfo != nil {
+ return "rs-" + strconv.FormatInt(result.getID(), 10)
+ }
+ return "rs-nil"
+}
+
+func formatRows(rows *DmRows) string {
+ if rows != nil && rows.logInfo != nil {
+ return "rows-" + strconv.FormatInt(rows.getID(), 10)
+ }
+ return "rows-nil"
+}
+
+func formatTrace(source string, method string, returnValue interface{}, params ...interface{}) string {
+ var str string
+ if source != "" {
+ str += "{ " + source + " } "
+ }
+ str += method + "("
+ var paramStartIndex = 0
+ if params != nil && len(params) > paramStartIndex {
+ for i := paramStartIndex; i < len(params); i++ {
+ if i != paramStartIndex {
+ str += ", "
+ }
+ if params[i] != nil {
+ str += reflect.TypeOf(params[i]).String()
+ } else {
+ str += "nil"
+ }
+ }
+ }
+ str += ")"
+ if returnValue != nil {
+ str += ": " + formatReturn(returnValue)
+ }
+ str += "; "
+ if params != nil && len(params) > paramStartIndex {
+ str += "[PARAMS]: "
+ for i := paramStartIndex; i < len(params); i++ {
+ if i != 0 {
+ str += ", "
+ }
+ if s, ok := params[i].(string); ok {
+ str += "\"" + s + "\""
+ } else {
+ str += reflect.ValueOf(params[i]).String()
+ }
+ }
+ str += "; "
+ }
+ return str
+}
+
+func formatReturn(returnObj interface{}) string {
+ var str string
+ switch o := returnObj.(type) {
+ case *DmConnection:
+ str = formatConn(o)
+ sessID := o.SessionID
+ if sessID != -1 {
+ str += ", sessionID-0x" + strconv.FormatInt(sessID, 16)
+ }
+ case *DmStatement:
+ str = formatStmt(o)
+ str += ", handle-" + strconv.Itoa(int(o.id))
+ case *DmResult:
+ str = formatRs(o)
+ case *DmRows:
+ str = formatRows(o)
+ case string:
+ str = `"` + o + `"`
+ case nullData:
+ str = "nil"
+ default:
+ str = "unknown"
+ }
+ return str
+}
+
+func formatUsedTime(duration time.Duration) string {
+ return "[USED TIME]: " + duration.String()
+}
+
+/************************************************************************************************************/
+
+type nullData struct{}
+
+var null = nullData{}
+
+type LogRecord struct {
+ source string
+ method string
+ params []interface{}
+ returnValue interface{}
+ e error
+ usedTime time.Duration
+ sql string
+}
+
+func (record *LogRecord) Set(source interface{}, method string, params ...interface{}) {
+ record.source = formatSource(source)
+ record.method = method
+ record.params = params
+}
+
+func (record *LogRecord) SetReturnValue(retValue interface{}) {
+ if retValue == nil {
+ record.returnValue = null
+ } else {
+ record.returnValue = retValue
+ }
+}
+
+func (record *LogRecord) GetReturnValue() interface{} {
+ return record.returnValue
+}
+
+func (record *LogRecord) SetSql(sql string) {
+ record.sql = sql
+}
+
+func (record *LogRecord) GetSql() string {
+ return record.sql
+}
+
+func (record *LogRecord) SetUsedTime(usedTime time.Duration) {
+ record.usedTime = usedTime
+}
+
+func (record *LogRecord) GetUsedTime() time.Duration {
+ return record.usedTime
+}
+
+func (record *LogRecord) SetError(err error) {
+ record.e = err
+}
+
+func (record *LogRecord) GetError() error {
+ return record.e
+}
+
+func (record *LogRecord) ToString() string {
+ var str string
+ str += formatTrace(record.source, record.method, record.returnValue, record.params...)
+ if record.usedTime > 0 {
+ str += formatUsedTime(record.usedTime)
+ }
+ return str
+}
diff --git a/dmr/zf.go b/dmr/zf.go
new file mode 100644
index 0000000..bad6c81
--- /dev/null
+++ b/dmr/zf.go
@@ -0,0 +1,497 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import (
+ "context"
+ "database/sql/driver"
+ "io"
+ "reflect"
+ "time"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+const SQL_GET_DSC_EP_SITE = "SELECT " +
+ "dsc.ep_seqno, " +
+ "(CASE mal.MAL_INST_HOST WHEN '' THEN mal.MAL_HOST ELSE mal.MAL_INST_HOST END) as ep_host, " +
+ "dcr.EP_PORT, " +
+ "dsc.EP_STATUS " +
+ "FROM V$DSC_EP_INFO dsc " +
+ "LEFT join V$DM_MAL_INI mal " +
+ "on dsc.EP_NAME = mal.MAL_INST_NAME " +
+ "LEFT join (SELECT grp.GROUP_TYPE GROUP_TYPE, ep.* FROM SYS.\"V$DCR_GROUP\" grp, SYS.\"V$DCR_EP\" ep where grp.GROUP_NAME = ep.GROUP_NAME) dcr " +
+ "on dsc.EP_NAME = dcr.EP_NAME and GROUP_TYPE = 'DB' order by dsc.ep_seqno asc;"
+
+type reconnectFilter struct {
+}
+
+// 一定抛错
+func (rf *reconnectFilter) autoReconnect(connection *DmConnection, err error) error {
+ if dmErr, ok := err.(*DmError); ok {
+ if dmErr.ErrCode == ECGO_COMMUNITION_ERROR.ErrCode {
+ return rf.reconnect(connection, dmErr.Error())
+ }
+ }
+ return err
+}
+
+// 一定抛错
+func (rf *reconnectFilter) reconnect(connection *DmConnection, reason string) error {
+ // 读写分离,重连需要处理备机
+ var err error
+ if connection.dmConnector.rwSeparate {
+ err = RWUtil.reconnect(connection)
+ } else {
+ err = connection.reconnect()
+ }
+
+ if err != nil {
+ return ECGO_CONNECTION_SWITCH_FAILED.addDetailln(reason).throw()
+ }
+
+ // 重连成功
+ return ECGO_CONNECTION_SWITCHED.addDetailln(reason).throw()
+}
+
+func (rf *reconnectFilter) loadDscEpSites(conn *DmConnection) []*ep {
+ stmt, rs, err := conn.driverQuery(SQL_GET_DSC_EP_SITE)
+ if err != nil {
+ return nil
+ }
+ defer func() {
+ rs.close()
+ stmt.close()
+ }()
+ epList := make([]*ep, 0)
+ dest := make([]driver.Value, 4)
+ for err = rs.next(dest); err != io.EOF; err = rs.next(dest) {
+ ep := newEP(dest[1].(string), dest[2].(int32))
+ ep.epSeqno = dest[0].(int32)
+ if util.StringUtil.EqualsIgnoreCase(dest[3].(string), "OK") {
+ ep.epStatus = EP_STATUS_OK
+ } else {
+ ep.epStatus = EP_STATUS_ERROR
+ }
+ epList = append(epList, ep)
+ }
+ return epList
+}
+
+func (rf *reconnectFilter) checkAndRecover(conn *DmConnection) error {
+ if conn.dmConnector.doSwitch != DO_SWITCH_WHEN_EP_RECOVER {
+ return nil
+ }
+ // check trx finish
+ if !conn.trxFinish {
+ return nil
+ }
+ var curIndex = conn.getIndexOnEPGroup()
+ if curIndex == 0 || (time.Now().UnixNano()/1000000-conn.recoverInfo.checkEpRecoverTs) < int64(conn.dmConnector.switchInterval) {
+ return nil
+ }
+ // check db recover
+ var dscEps []*ep
+ if conn.dmConnector.cluster == CLUSTER_TYPE_DSC {
+ dscEps = rf.loadDscEpSites(conn)
+ }
+ if dscEps == nil || len(dscEps) == 0 {
+ return nil
+ }
+ var recover = false
+ for _, okEp := range dscEps {
+ if okEp.epStatus != EP_STATUS_OK {
+ continue
+ }
+ for i := int32(0); i < curIndex; i++ {
+ ep := conn.dmConnector.group.epList[i]
+ if okEp.host == ep.host && okEp.port == ep.port {
+ recover = true
+ break
+ }
+ }
+ if recover {
+ break
+ }
+ }
+
+ conn.recoverInfo.checkEpRecoverTs = time.Now().UnixNano() / 1000000
+ if !recover {
+ return nil
+ }
+ // do reconnect
+ return conn.reconnect()
+}
+
+//DmDriver
+func (rf *reconnectFilter) DmDriverOpen(filterChain *filterChain, d *DmDriver, dsn string) (*DmConnection, error) {
+ return filterChain.DmDriverOpen(d, dsn)
+}
+
+func (rf *reconnectFilter) DmDriverOpenConnector(filterChain *filterChain, d *DmDriver, dsn string) (*DmConnector, error) {
+ return filterChain.DmDriverOpenConnector(d, dsn)
+}
+
+//DmConnector
+func (rf *reconnectFilter) DmConnectorConnect(filterChain *filterChain, c *DmConnector, ctx context.Context) (*DmConnection, error) {
+ return filterChain.DmConnectorConnect(c, ctx)
+}
+
+func (rf *reconnectFilter) DmConnectorDriver(filterChain *filterChain, c *DmConnector) *DmDriver {
+ return filterChain.DmConnectorDriver(c)
+}
+
+//DmConnection
+func (rf *reconnectFilter) DmConnectionBegin(filterChain *filterChain, c *DmConnection) (*DmConnection, error) {
+ dc, err := filterChain.DmConnectionBegin(c)
+ if err != nil {
+ return nil, rf.autoReconnect(c, err)
+ }
+ return dc, err
+}
+
+func (rf *reconnectFilter) DmConnectionBeginTx(filterChain *filterChain, c *DmConnection, ctx context.Context, opts driver.TxOptions) (*DmConnection, error) {
+ dc, err := filterChain.DmConnectionBeginTx(c, ctx, opts)
+ if err != nil {
+ return nil, rf.autoReconnect(c, err)
+ }
+ return dc, err
+}
+
+func (rf *reconnectFilter) DmConnectionCommit(filterChain *filterChain, c *DmConnection) error {
+ if err := filterChain.DmConnectionCommit(c); err != nil {
+ return rf.autoReconnect(c, err)
+ }
+ if err := rf.checkAndRecover(c); err != nil {
+ return rf.autoReconnect(c, err)
+ }
+ return nil
+}
+
+func (rf *reconnectFilter) DmConnectionRollback(filterChain *filterChain, c *DmConnection) error {
+ err := filterChain.DmConnectionRollback(c)
+ if err != nil {
+ err = rf.autoReconnect(c, err)
+ }
+
+ return err
+}
+
+func (rf *reconnectFilter) DmConnectionClose(filterChain *filterChain, c *DmConnection) error {
+ err := filterChain.DmConnectionClose(c)
+ if err != nil {
+ err = rf.autoReconnect(c, err)
+ }
+
+ return err
+}
+
+func (rf *reconnectFilter) DmConnectionPing(filterChain *filterChain, c *DmConnection, ctx context.Context) error {
+ err := filterChain.DmConnectionPing(c, ctx)
+ if err != nil {
+ err = rf.autoReconnect(c, err)
+ }
+
+ return err
+}
+
+func (rf *reconnectFilter) DmConnectionExec(filterChain *filterChain, c *DmConnection, query string, args []driver.Value) (*DmResult, error) {
+ if err := rf.checkAndRecover(c); err != nil {
+ return nil, rf.autoReconnect(c, err)
+ }
+ dr, err := filterChain.DmConnectionExec(c, query, args)
+ if err != nil {
+ return nil, rf.autoReconnect(c, err)
+ }
+
+ return dr, err
+}
+
+func (rf *reconnectFilter) DmConnectionExecContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (*DmResult, error) {
+ if err := rf.checkAndRecover(c); err != nil {
+ return nil, rf.autoReconnect(c, err)
+ }
+ dr, err := filterChain.DmConnectionExecContext(c, ctx, query, args)
+ if err != nil {
+ return nil, rf.autoReconnect(c, err)
+ }
+
+ return dr, err
+}
+
+func (rf *reconnectFilter) DmConnectionQuery(filterChain *filterChain, c *DmConnection, query string, args []driver.Value) (*DmRows, error) {
+ if err := rf.checkAndRecover(c); err != nil {
+ return nil, rf.autoReconnect(c, err)
+ }
+ dr, err := filterChain.DmConnectionQuery(c, query, args)
+ if err != nil {
+ return nil, rf.autoReconnect(c, err)
+ }
+
+ return dr, err
+}
+
+func (rf *reconnectFilter) DmConnectionQueryContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (*DmRows, error) {
+ if err := rf.checkAndRecover(c); err != nil {
+ return nil, rf.autoReconnect(c, err)
+ }
+ dr, err := filterChain.DmConnectionQueryContext(c, ctx, query, args)
+ if err != nil {
+ return nil, rf.autoReconnect(c, err)
+ }
+
+ return dr, err
+}
+
+func (rf *reconnectFilter) DmConnectionPrepare(filterChain *filterChain, c *DmConnection, query string) (*DmStatement, error) {
+ ds, err := filterChain.DmConnectionPrepare(c, query)
+ if err != nil {
+ return nil, rf.autoReconnect(c, err)
+ }
+
+ return ds, err
+}
+
+func (rf *reconnectFilter) DmConnectionPrepareContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string) (*DmStatement, error) {
+ ds, err := filterChain.DmConnectionPrepareContext(c, ctx, query)
+ if err != nil {
+ return nil, rf.autoReconnect(c, err)
+ }
+
+ return ds, err
+}
+
+func (rf *reconnectFilter) DmConnectionResetSession(filterChain *filterChain, c *DmConnection, ctx context.Context) error {
+ err := filterChain.DmConnectionResetSession(c, ctx)
+ if err != nil {
+ err = rf.autoReconnect(c, err)
+ }
+
+ return err
+}
+
+func (rf *reconnectFilter) DmConnectionCheckNamedValue(filterChain *filterChain, c *DmConnection, nv *driver.NamedValue) error {
+ err := filterChain.DmConnectionCheckNamedValue(c, nv)
+ if err != nil {
+ err = rf.autoReconnect(c, err)
+ }
+
+ return err
+}
+
+//DmStatement
+func (rf *reconnectFilter) DmStatementClose(filterChain *filterChain, s *DmStatement) error {
+ err := filterChain.DmStatementClose(s)
+ if err != nil {
+ err = rf.autoReconnect(s.dmConn, err)
+ }
+
+ return err
+}
+
+func (rf *reconnectFilter) DmStatementNumInput(filterChain *filterChain, s *DmStatement) int {
+ var ret int
+ defer func() {
+ err := recover()
+ if err != nil {
+ rf.autoReconnect(s.dmConn, err.(error))
+ ret = 0
+ }
+ }()
+ ret = filterChain.DmStatementNumInput(s)
+ return ret
+}
+
+func (rf *reconnectFilter) DmStatementExec(filterChain *filterChain, s *DmStatement, args []driver.Value) (*DmResult, error) {
+ if err := rf.checkAndRecover(s.dmConn); err != nil {
+ return nil, rf.autoReconnect(s.dmConn, err)
+ }
+ dr, err := filterChain.DmStatementExec(s, args)
+ if err != nil {
+ return nil, rf.autoReconnect(s.dmConn, err)
+ }
+
+ return dr, err
+}
+
+func (rf *reconnectFilter) DmStatementExecContext(filterChain *filterChain, s *DmStatement, ctx context.Context, args []driver.NamedValue) (*DmResult, error) {
+ if err := rf.checkAndRecover(s.dmConn); err != nil {
+ return nil, rf.autoReconnect(s.dmConn, err)
+ }
+ dr, err := filterChain.DmStatementExecContext(s, ctx, args)
+ if err != nil {
+ return nil, rf.autoReconnect(s.dmConn, err)
+ }
+
+ return dr, err
+}
+
+func (rf *reconnectFilter) DmStatementQuery(filterChain *filterChain, s *DmStatement, args []driver.Value) (*DmRows, error) {
+ if err := rf.checkAndRecover(s.dmConn); err != nil {
+ return nil, rf.autoReconnect(s.dmConn, err)
+ }
+ dr, err := filterChain.DmStatementQuery(s, args)
+ if err != nil {
+ return nil, rf.autoReconnect(s.dmConn, err)
+ }
+
+ return dr, err
+}
+
+func (rf *reconnectFilter) DmStatementQueryContext(filterChain *filterChain, s *DmStatement, ctx context.Context, args []driver.NamedValue) (*DmRows, error) {
+ if err := rf.checkAndRecover(s.dmConn); err != nil {
+ return nil, rf.autoReconnect(s.dmConn, err)
+ }
+ dr, err := filterChain.DmStatementQueryContext(s, ctx, args)
+ if err != nil {
+ return nil, rf.autoReconnect(s.dmConn, err)
+ }
+
+ return dr, err
+}
+
+func (rf *reconnectFilter) DmStatementCheckNamedValue(filterChain *filterChain, s *DmStatement, nv *driver.NamedValue) error {
+ err := filterChain.DmStatementCheckNamedValue(s, nv)
+ if err != nil {
+ err = rf.autoReconnect(s.dmConn, err)
+ }
+
+ return err
+}
+
+//DmResult
+func (rf *reconnectFilter) DmResultLastInsertId(filterChain *filterChain, r *DmResult) (int64, error) {
+ i, err := filterChain.DmResultLastInsertId(r)
+ if err != nil {
+ err = rf.autoReconnect(r.dmStmt.dmConn, err)
+ return 0, err
+ }
+
+ return i, err
+}
+
+func (rf *reconnectFilter) DmResultRowsAffected(filterChain *filterChain, r *DmResult) (int64, error) {
+ i, err := filterChain.DmResultRowsAffected(r)
+ if err != nil {
+ err = rf.autoReconnect(r.dmStmt.dmConn, err)
+ return 0, err
+ }
+
+ return i, err
+}
+
+//DmRows
+func (rf *reconnectFilter) DmRowsColumns(filterChain *filterChain, r *DmRows) []string {
+ var ret []string
+ defer func() {
+ err := recover()
+ if err != nil {
+ rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err.(error))
+ ret = nil
+ }
+ }()
+ ret = filterChain.DmRowsColumns(r)
+ return ret
+}
+
+func (rf *reconnectFilter) DmRowsClose(filterChain *filterChain, r *DmRows) error {
+ err := filterChain.DmRowsClose(r)
+ if err != nil {
+ err = rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err)
+ }
+
+ return err
+}
+
+func (rf *reconnectFilter) DmRowsNext(filterChain *filterChain, r *DmRows, dest []driver.Value) error {
+ err := filterChain.DmRowsNext(r, dest)
+ if err != nil {
+ err = rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err)
+ }
+
+ return err
+}
+
+func (rf *reconnectFilter) DmRowsHasNextResultSet(filterChain *filterChain, r *DmRows) bool {
+ var ret bool
+ defer func() {
+ err := recover()
+ if err != nil {
+ rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err.(error))
+ ret = false
+ }
+ }()
+ ret = filterChain.DmRowsHasNextResultSet(r)
+ return ret
+}
+
+func (rf *reconnectFilter) DmRowsNextResultSet(filterChain *filterChain, r *DmRows) error {
+ err := filterChain.DmRowsNextResultSet(r)
+ if err != nil {
+ err = rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err)
+ }
+
+ return err
+}
+
+func (rf *reconnectFilter) DmRowsColumnTypeScanType(filterChain *filterChain, r *DmRows, index int) reflect.Type {
+ var ret reflect.Type
+ defer func() {
+ err := recover()
+ if err != nil {
+ rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err.(error))
+ ret = scanTypeUnknown
+ }
+ }()
+ ret = filterChain.DmRowsColumnTypeScanType(r, index)
+ return ret
+}
+
+func (rf *reconnectFilter) DmRowsColumnTypeDatabaseTypeName(filterChain *filterChain, r *DmRows, index int) string {
+ var ret string
+ defer func() {
+ err := recover()
+ if err != nil {
+ rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err.(error))
+ ret = ""
+ }
+ }()
+ ret = filterChain.DmRowsColumnTypeDatabaseTypeName(r, index)
+ return ret
+}
+
+func (rf *reconnectFilter) DmRowsColumnTypeLength(filterChain *filterChain, r *DmRows, index int) (length int64, ok bool) {
+ defer func() {
+ err := recover()
+ if err != nil {
+ rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err.(error))
+ length, ok = 0, false
+ }
+ }()
+ return filterChain.DmRowsColumnTypeLength(r, index)
+}
+
+func (rf *reconnectFilter) DmRowsColumnTypeNullable(filterChain *filterChain, r *DmRows, index int) (nullable, ok bool) {
+ defer func() {
+ err := recover()
+ if err != nil {
+ rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err.(error))
+ nullable, ok = false, false
+ }
+ }()
+ return filterChain.DmRowsColumnTypeNullable(r, index)
+}
+
+func (rf *reconnectFilter) DmRowsColumnTypePrecisionScale(filterChain *filterChain, r *DmRows, index int) (precision, scale int64, ok bool) {
+ defer func() {
+ err := recover()
+ if err != nil {
+ rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err.(error))
+ precision, scale, ok = 0, 0, false
+ }
+ }()
+ return filterChain.DmRowsColumnTypePrecisionScale(r, index)
+}
diff --git a/dmr/zg.go b/dmr/zg.go
new file mode 100644
index 0000000..a65db20
--- /dev/null
+++ b/dmr/zg.go
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import (
+ "context"
+ "database/sql/driver"
+ "reflect"
+)
+
+type rwFilter struct {
+}
+
+//DmDriver
+func (rwf *rwFilter) DmDriverOpen(filterChain *filterChain, d *DmDriver, dsn string) (*DmConnection, error) {
+ return filterChain.DmDriverOpen(d, dsn)
+}
+
+func (rwf *rwFilter) DmDriverOpenConnector(filterChain *filterChain, d *DmDriver, dsn string) (*DmConnector, error) {
+ return filterChain.DmDriverOpenConnector(d, dsn)
+}
+
+//DmConnector
+func (rwf *rwFilter) DmConnectorConnect(filterChain *filterChain, c *DmConnector, ctx context.Context) (*DmConnection, error) {
+ return RWUtil.connect(c, ctx)
+}
+
+func (rwf *rwFilter) DmConnectorDriver(filterChain *filterChain, c *DmConnector) *DmDriver {
+ return filterChain.DmConnectorDriver(c)
+}
+
+//DmConnection
+func (rwf *rwFilter) DmConnectionBegin(filterChain *filterChain, c *DmConnection) (*DmConnection, error) {
+ if RWUtil.isStandbyAlive(c) {
+ _, err := c.rwInfo.connStandby.begin()
+ if err != nil {
+ RWUtil.afterExceptionOnStandby(c, err)
+ }
+ }
+
+ return filterChain.DmConnectionBegin(c)
+}
+
+func (rwf *rwFilter) DmConnectionBeginTx(filterChain *filterChain, c *DmConnection, ctx context.Context, opts driver.TxOptions) (*DmConnection, error) {
+ if RWUtil.isStandbyAlive(c) {
+ _, err := c.rwInfo.connStandby.beginTx(ctx, opts)
+ if err != nil {
+ RWUtil.afterExceptionOnStandby(c, err)
+ }
+ }
+
+ return filterChain.DmConnectionBeginTx(c, ctx, opts)
+}
+
+func (rwf *rwFilter) DmConnectionCommit(filterChain *filterChain, c *DmConnection) error {
+ if RWUtil.isStandbyAlive(c) {
+ err := c.rwInfo.connStandby.commit()
+ if err != nil {
+ RWUtil.afterExceptionOnStandby(c, err)
+ }
+ }
+
+ return filterChain.DmConnectionCommit(c)
+}
+
+func (rwf *rwFilter) DmConnectionRollback(filterChain *filterChain, c *DmConnection) error {
+ if RWUtil.isStandbyAlive(c) {
+ err := c.rwInfo.connStandby.rollback()
+ if err != nil {
+ RWUtil.afterExceptionOnStandby(c, err)
+ }
+ }
+
+ return filterChain.DmConnectionRollback(c)
+}
+
+func (rwf *rwFilter) DmConnectionClose(filterChain *filterChain, c *DmConnection) error {
+ if RWUtil.isStandbyAlive(c) {
+ err := c.rwInfo.connStandby.close()
+ if err != nil {
+ RWUtil.afterExceptionOnStandby(c, err)
+ }
+ }
+
+ return filterChain.DmConnectionClose(c)
+}
+
+func (rwf *rwFilter) DmConnectionPing(filterChain *filterChain, c *DmConnection, ctx context.Context) error {
+ return filterChain.DmConnectionPing(c, ctx)
+}
+
+func (rwf *rwFilter) DmConnectionExec(filterChain *filterChain, c *DmConnection, query string, args []driver.Value) (*DmResult, error) {
+ ret, err := RWUtil.executeByConn(c, query, func() (interface{}, error) {
+ return c.rwInfo.connCurrent.exec(query, args)
+ }, func(otherConn *DmConnection) (interface{}, error) {
+ return otherConn.exec(query, args)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return ret.(*DmResult), nil
+}
+
+func (rwf *rwFilter) DmConnectionExecContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (*DmResult, error) {
+ ret, err := RWUtil.executeByConn(c, query, func() (interface{}, error) {
+ return c.rwInfo.connCurrent.execContext(ctx, query, args)
+ }, func(otherConn *DmConnection) (interface{}, error) {
+ return otherConn.execContext(ctx, query, args)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return ret.(*DmResult), nil
+}
+
+func (rwf *rwFilter) DmConnectionQuery(filterChain *filterChain, c *DmConnection, query string, args []driver.Value) (*DmRows, error) {
+ ret, err := RWUtil.executeByConn(c, query, func() (interface{}, error) {
+ return c.rwInfo.connCurrent.query(query, args)
+ }, func(otherConn *DmConnection) (interface{}, error) {
+ return otherConn.query(query, args)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return ret.(*DmRows), nil
+}
+
+func (rwf *rwFilter) DmConnectionQueryContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (*DmRows, error) {
+ ret, err := RWUtil.executeByConn(c, query, func() (interface{}, error) {
+ return c.rwInfo.connCurrent.queryContext(ctx, query, args)
+ }, func(otherConn *DmConnection) (interface{}, error) {
+ return otherConn.queryContext(ctx, query, args)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return ret.(*DmRows), nil
+}
+
+func (rwf *rwFilter) DmConnectionPrepare(filterChain *filterChain, c *DmConnection, query string) (*DmStatement, error) {
+ stmt, err := c.prepare(query)
+ if err != nil {
+ return nil, err
+ }
+ stmt.rwInfo.stmtCurrent = stmt
+ stmt.rwInfo.readOnly = RWUtil.checkReadonlyByStmt(stmt)
+ if RWUtil.isCreateStandbyStmt(stmt) {
+ stmt.rwInfo.stmtStandby, err = c.rwInfo.connStandby.prepare(query)
+ if err == nil {
+ stmt.rwInfo.stmtCurrent = stmt.rwInfo.stmtStandby
+ } else {
+ RWUtil.afterExceptionOnStandby(c, err)
+ }
+ }
+ return stmt, nil
+}
+
+func (rwf *rwFilter) DmConnectionPrepareContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string) (*DmStatement, error) {
+ stmt, err := c.prepareContext(ctx, query)
+ if err != nil {
+ return nil, err
+ }
+ stmt.rwInfo.stmtCurrent = stmt
+ stmt.rwInfo.readOnly = RWUtil.checkReadonlyByStmt(stmt)
+ if RWUtil.isCreateStandbyStmt(stmt) {
+ stmt.rwInfo.stmtStandby, err = c.rwInfo.connStandby.prepareContext(ctx, query)
+ if err == nil {
+ stmt.rwInfo.stmtCurrent = stmt.rwInfo.stmtStandby
+ } else {
+ RWUtil.afterExceptionOnStandby(c, err)
+ }
+ }
+ return stmt, nil
+}
+
+func (rwf *rwFilter) DmConnectionResetSession(filterChain *filterChain, c *DmConnection, ctx context.Context) error {
+ if RWUtil.isStandbyAlive(c) {
+ err := c.rwInfo.connStandby.resetSession(ctx)
+ if err != nil {
+ RWUtil.afterExceptionOnStandby(c, err)
+ }
+ }
+
+ return filterChain.DmConnectionResetSession(c, ctx)
+}
+
+func (rwf *rwFilter) DmConnectionCheckNamedValue(filterChain *filterChain, c *DmConnection, nv *driver.NamedValue) error {
+ return filterChain.DmConnectionCheckNamedValue(c, nv)
+}
+
+//DmStatement
+func (rwf *rwFilter) DmStatementClose(filterChain *filterChain, s *DmStatement) error {
+ if RWUtil.isStandbyStatementValid(s) {
+ err := s.rwInfo.stmtStandby.close()
+ if err != nil {
+ RWUtil.afterExceptionOnStandby(s.dmConn, err)
+ }
+ }
+
+ return filterChain.DmStatementClose(s)
+}
+
+func (rwf *rwFilter) DmStatementNumInput(filterChain *filterChain, s *DmStatement) int {
+ return filterChain.DmStatementNumInput(s)
+}
+
+func (rwf *rwFilter) DmStatementExec(filterChain *filterChain, s *DmStatement, args []driver.Value) (*DmResult, error) {
+ ret, err := RWUtil.executeByStmt(s, func() (interface{}, error) {
+ return s.rwInfo.stmtCurrent.exec(args)
+ }, func(otherStmt *DmStatement) (interface{}, error) {
+ return otherStmt.exec(args)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return ret.(*DmResult), nil
+}
+
+func (rwf *rwFilter) DmStatementExecContext(filterChain *filterChain, s *DmStatement, ctx context.Context, args []driver.NamedValue) (*DmResult, error) {
+ ret, err := RWUtil.executeByStmt(s, func() (interface{}, error) {
+ return s.rwInfo.stmtCurrent.execContext(ctx, args)
+ }, func(otherStmt *DmStatement) (interface{}, error) {
+ return otherStmt.execContext(ctx, args)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return ret.(*DmResult), nil
+}
+
+func (rwf *rwFilter) DmStatementQuery(filterChain *filterChain, s *DmStatement, args []driver.Value) (*DmRows, error) {
+ ret, err := RWUtil.executeByStmt(s, func() (interface{}, error) {
+ return s.rwInfo.stmtCurrent.query(args)
+ }, func(otherStmt *DmStatement) (interface{}, error) {
+ return otherStmt.query(args)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return ret.(*DmRows), nil
+}
+
+func (rwf *rwFilter) DmStatementQueryContext(filterChain *filterChain, s *DmStatement, ctx context.Context, args []driver.NamedValue) (*DmRows, error) {
+ ret, err := RWUtil.executeByStmt(s, func() (interface{}, error) {
+ return s.rwInfo.stmtCurrent.queryContext(ctx, args)
+ }, func(otherStmt *DmStatement) (interface{}, error) {
+ return otherStmt.queryContext(ctx, args)
+ })
+ if err != nil {
+ return nil, err
+ }
+ return ret.(*DmRows), nil
+}
+
+func (rwf *rwFilter) DmStatementCheckNamedValue(filterChain *filterChain, s *DmStatement, nv *driver.NamedValue) error {
+ return filterChain.DmStatementCheckNamedValue(s, nv)
+}
+
+//DmResult
+func (rwf *rwFilter) DmResultLastInsertId(filterChain *filterChain, r *DmResult) (int64, error) {
+ return filterChain.DmResultLastInsertId(r)
+}
+
+func (rwf *rwFilter) DmResultRowsAffected(filterChain *filterChain, r *DmResult) (int64, error) {
+ return filterChain.DmResultRowsAffected(r)
+}
+
+//DmRows
+func (rwf *rwFilter) DmRowsColumns(filterChain *filterChain, r *DmRows) []string {
+ return filterChain.DmRowsColumns(r)
+}
+
+func (rwf *rwFilter) DmRowsClose(filterChain *filterChain, r *DmRows) error {
+ return filterChain.DmRowsClose(r)
+}
+
+func (rwf *rwFilter) DmRowsNext(filterChain *filterChain, r *DmRows, dest []driver.Value) error {
+ return filterChain.DmRowsNext(r, dest)
+}
+
+func (rwf *rwFilter) DmRowsHasNextResultSet(filterChain *filterChain, r *DmRows) bool {
+ return filterChain.DmRowsHasNextResultSet(r)
+}
+
+func (rwf *rwFilter) DmRowsNextResultSet(filterChain *filterChain, r *DmRows) error {
+ return filterChain.DmRowsNextResultSet(r)
+}
+
+func (rwf *rwFilter) DmRowsColumnTypeScanType(filterChain *filterChain, r *DmRows, index int) reflect.Type {
+ return filterChain.DmRowsColumnTypeScanType(r, index)
+}
+
+func (rwf *rwFilter) DmRowsColumnTypeDatabaseTypeName(filterChain *filterChain, r *DmRows, index int) string {
+ return filterChain.DmRowsColumnTypeDatabaseTypeName(r, index)
+}
+
+func (rwf *rwFilter) DmRowsColumnTypeLength(filterChain *filterChain, r *DmRows, index int) (length int64, ok bool) {
+ return filterChain.DmRowsColumnTypeLength(r, index)
+}
+
+func (rwf *rwFilter) DmRowsColumnTypeNullable(filterChain *filterChain, r *DmRows, index int) (nullable, ok bool) {
+ return filterChain.DmRowsColumnTypeNullable(r, index)
+}
+
+func (rwf *rwFilter) DmRowsColumnTypePrecisionScale(filterChain *filterChain, r *DmRows, index int) (precision, scale int64, ok bool) {
+ return filterChain.DmRowsColumnTypePrecisionScale(r, index)
+}
diff --git a/dmr/zh.go b/dmr/zh.go
new file mode 100644
index 0000000..7afeaeb
--- /dev/null
+++ b/dmr/zh.go
@@ -0,0 +1,607 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import (
+ "bytes"
+ "context"
+ "database/sql/driver"
+ "fmt"
+ "reflect"
+ "time"
+)
+
+type statFilter struct {
+}
+
+//DmDriver
+func (sf *statFilter) DmDriverOpen(filterChain *filterChain, d *DmDriver, dsn string) (*DmConnection, error) {
+ conn, err := filterChain.DmDriverOpen(d, dsn)
+ if err != nil {
+ return nil, err
+ }
+ conn.statInfo.init(conn)
+ conn.statInfo.setConstructNano()
+ conn.statInfo.getConnStat().incrementConn()
+ return conn, nil
+}
+
+func (sf *statFilter) DmDriverOpenConnector(filterChain *filterChain, d *DmDriver, dsn string) (*DmConnector, error) {
+ return filterChain.DmDriverOpenConnector(d, dsn)
+}
+
+//DmConnector
+func (sf *statFilter) DmConnectorConnect(filterChain *filterChain, c *DmConnector, ctx context.Context) (*DmConnection, error) {
+ conn, err := filterChain.DmConnectorConnect(c, ctx)
+ if err != nil {
+ return nil, err
+ }
+ conn.statInfo.init(conn)
+ conn.statInfo.setConstructNano()
+ conn.statInfo.getConnStat().incrementConn()
+ return conn, nil
+}
+
+func (sf *statFilter) DmConnectorDriver(filterChain *filterChain, c *DmConnector) *DmDriver {
+ return filterChain.DmConnectorDriver(c)
+}
+
+//DmConnection
+func (sf *statFilter) DmConnectionBegin(filterChain *filterChain, c *DmConnection) (*DmConnection, error) {
+ return filterChain.DmConnectionBegin(c)
+}
+
+func (sf *statFilter) DmConnectionBeginTx(filterChain *filterChain, c *DmConnection, ctx context.Context, opts driver.TxOptions) (*DmConnection, error) {
+ return filterChain.DmConnectionBeginTx(c, ctx, opts)
+}
+
+func (sf *statFilter) DmConnectionCommit(filterChain *filterChain, c *DmConnection) error {
+ err := filterChain.DmConnectionCommit(c)
+ if err != nil {
+ return err
+ }
+ c.statInfo.getConnStat().incrementCommitCount()
+ return nil
+}
+
+func (sf *statFilter) DmConnectionRollback(filterChain *filterChain, c *DmConnection) error {
+ err := filterChain.DmConnectionRollback(c)
+ if err != nil {
+ return err
+ }
+ c.statInfo.getConnStat().incrementRollbackCount()
+ return nil
+}
+
+func (sf *statFilter) DmConnectionClose(filterChain *filterChain, c *DmConnection) error {
+ if !c.closed.IsSet() {
+ c.statInfo.getConnStat().decrementStmtByActiveStmtCount(int64(getActiveStmtCount(c)))
+ c.statInfo.getConnStat().decrementConn()
+ }
+
+ return filterChain.DmConnectionClose(c)
+}
+
+func (sf *statFilter) DmConnectionPing(filterChain *filterChain, c *DmConnection, ctx context.Context) error {
+ return c.ping(ctx)
+}
+
+func (sf *statFilter) DmConnectionExec(filterChain *filterChain, c *DmConnection, query string, args []driver.Value) (*DmResult, error) {
+ connExecBefore(c, query)
+ dr, err := filterChain.DmConnectionExec(c, query, args)
+ if err != nil {
+ connExecuteErrorAfter(c, args, err)
+ return nil, err
+ }
+ connExecAfter(c, query, args, int(dr.affectedRows))
+ return dr, nil
+}
+
+func (sf *statFilter) DmConnectionExecContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (*DmResult, error) {
+ connExecBefore(c, query)
+ dr, err := filterChain.DmConnectionExecContext(c, ctx, query, args)
+ if err != nil {
+ connExecuteErrorAfter(c, args, err)
+ return nil, err
+ }
+ connExecAfter(c, query, args, int(dr.affectedRows))
+ return dr, nil
+}
+
+func (sf *statFilter) DmConnectionQuery(filterChain *filterChain, c *DmConnection, query string, args []driver.Value) (*DmRows, error) {
+ connQueryBefore(c, query)
+ dr, err := filterChain.DmConnectionQuery(c, query, args)
+ if err != nil {
+ connExecuteErrorAfter(c, args, err)
+ return nil, err
+ }
+ connQueryAfter(c, query, args, dr)
+ return dr, nil
+}
+
+func (sf *statFilter) DmConnectionQueryContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (*DmRows, error) {
+ connQueryBefore(c, query)
+ dr, err := filterChain.DmConnectionQueryContext(c, ctx, query, args)
+ if err != nil {
+ connExecuteErrorAfter(c, args, err)
+ return nil, err
+ }
+ connQueryAfter(c, query, args, dr)
+ return dr, nil
+}
+
+func (sf *statFilter) DmConnectionPrepare(filterChain *filterChain, c *DmConnection, query string) (*DmStatement, error) {
+ stmt, err := filterChain.DmConnectionPrepare(c, query)
+ if err != nil {
+ return nil, err
+ }
+ statementCreateAfter(c, stmt)
+ return stmt, nil
+}
+
+func (sf *statFilter) DmConnectionPrepareContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string) (*DmStatement, error) {
+ stmt, err := filterChain.DmConnectionPrepareContext(c, ctx, query)
+ if err != nil {
+ return nil, err
+ }
+ statementCreateAfter(c, stmt)
+ return stmt, nil
+}
+
+func (sf *statFilter) DmConnectionResetSession(filterChain *filterChain, c *DmConnection, ctx context.Context) error {
+ return filterChain.DmConnectionResetSession(c, ctx)
+}
+
+func (sf *statFilter) DmConnectionCheckNamedValue(filterChain *filterChain, c *DmConnection, nv *driver.NamedValue) error {
+ return filterChain.DmConnectionCheckNamedValue(c, nv)
+}
+
+//DmStatement
+func (sf *statFilter) DmStatementClose(filterChain *filterChain, s *DmStatement) error {
+ if !s.closed {
+ statementCloseBefore(s)
+ }
+ return filterChain.DmStatementClose(s)
+}
+
+func (sf *statFilter) DmStatementNumInput(filterChain *filterChain, s *DmStatement) int {
+ return filterChain.DmStatementNumInput(s)
+}
+
+func (sf *statFilter) DmStatementExec(filterChain *filterChain, s *DmStatement, args []driver.Value) (*DmResult, error) {
+ stmtExecBefore(s)
+ dr, err := filterChain.DmStatementExec(s, args)
+ if err != nil {
+ statementExecuteErrorAfter(s, args, err)
+ return nil, err
+ }
+ stmtExecAfter(s, args, int(dr.affectedRows))
+ return dr, nil
+}
+
+func (sf *statFilter) DmStatementExecContext(filterChain *filterChain, s *DmStatement, ctx context.Context, args []driver.NamedValue) (*DmResult, error) {
+ stmtExecBefore(s)
+ dr, err := filterChain.DmStatementExecContext(s, ctx, args)
+ if err != nil {
+ statementExecuteErrorAfter(s, args, err)
+ return nil, err
+ }
+ stmtExecAfter(s, args, int(dr.affectedRows))
+ return dr, nil
+}
+
+func (sf *statFilter) DmStatementQuery(filterChain *filterChain, s *DmStatement, args []driver.Value) (*DmRows, error) {
+ stmtQueryBefore(s)
+ dr, err := filterChain.DmStatementQuery(s, args)
+ if err != nil {
+ statementExecuteErrorAfter(s, args, err)
+ return nil, err
+ }
+ stmtQueryAfter(s, args, dr)
+ return dr, nil
+}
+
+func (sf *statFilter) DmStatementQueryContext(filterChain *filterChain, s *DmStatement, ctx context.Context, args []driver.NamedValue) (*DmRows, error) {
+ stmtQueryBefore(s)
+ dr, err := filterChain.DmStatementQueryContext(s, ctx, args)
+ if err != nil {
+ statementExecuteErrorAfter(s, args, err)
+ return nil, err
+ }
+ stmtQueryAfter(s, args, dr)
+ return dr, nil
+}
+
+func (sf *statFilter) DmStatementCheckNamedValue(filterChain *filterChain, s *DmStatement, nv *driver.NamedValue) error {
+ return filterChain.DmStatementCheckNamedValue(s, nv)
+}
+
+//DmResult
+func (sf *statFilter) DmResultLastInsertId(filterChain *filterChain, r *DmResult) (int64, error) {
+ return filterChain.DmResultLastInsertId(r)
+}
+
+func (sf *statFilter) DmResultRowsAffected(filterChain *filterChain, r *DmResult) (int64, error) {
+ return filterChain.DmResultRowsAffected(r)
+}
+
+//DmRows
+func (sf *statFilter) DmRowsColumns(filterChain *filterChain, r *DmRows) []string {
+ return filterChain.DmRowsColumns(r)
+}
+
+func (sf *statFilter) DmRowsClose(filterChain *filterChain, r *DmRows) error {
+ if !r.CurrentRows.closed {
+ resultSetCloseBefore(r)
+ }
+ return filterChain.DmRowsClose(r)
+}
+
+func (sf *statFilter) DmRowsNext(filterChain *filterChain, r *DmRows, dest []driver.Value) error {
+ return filterChain.DmRowsNext(r, dest)
+}
+
+func (sf *statFilter) DmRowsHasNextResultSet(filterChain *filterChain, r *DmRows) bool {
+ return filterChain.DmRowsHasNextResultSet(r)
+}
+
+func (sf *statFilter) DmRowsNextResultSet(filterChain *filterChain, r *DmRows) error {
+ return filterChain.DmRowsNextResultSet(r)
+}
+
+func (sf *statFilter) DmRowsColumnTypeScanType(filterChain *filterChain, r *DmRows, index int) reflect.Type {
+ return filterChain.DmRowsColumnTypeScanType(r, index)
+}
+
+func (sf *statFilter) DmRowsColumnTypeDatabaseTypeName(filterChain *filterChain, r *DmRows, index int) string {
+ return filterChain.DmRowsColumnTypeDatabaseTypeName(r, index)
+}
+
+func (sf *statFilter) DmRowsColumnTypeLength(filterChain *filterChain, r *DmRows, index int) (length int64, ok bool) {
+ return filterChain.DmRowsColumnTypeLength(r, index)
+}
+
+func (sf *statFilter) DmRowsColumnTypeNullable(filterChain *filterChain, r *DmRows, index int) (nullable, ok bool) {
+ return filterChain.DmRowsColumnTypeNullable(r, index)
+}
+
+func (sf *statFilter) DmRowsColumnTypePrecisionScale(filterChain *filterChain, r *DmRows, index int) (precision, scale int64, ok bool) {
+ return filterChain.DmRowsColumnTypePrecisionScale(r, index)
+}
+
+func getActiveStmtCount(conn *DmConnection) int {
+ if conn.stmtMap == nil {
+ return 0
+ } else {
+ return len(conn.stmtMap)
+ }
+}
+
+func statementCreateAfter(conn *DmConnection, stmt *DmStatement) {
+ stmt.statInfo.setConstructNano()
+ conn.statInfo.getConnStat().incrementStmt()
+}
+
+func connExecBefore(conn *DmConnection, sql string) {
+ conn.statInfo.setLastExecuteSql(sql)
+ conn.statInfo.setFirstResultSet(false)
+ conn.statInfo.setLastExecuteType(ExecuteUpdate)
+ internalBeforeConnExecute(conn, sql)
+}
+
+func connExecAfter(conn *DmConnection, sql string, args interface{}, updateCount int) {
+ internalAfterConnExecute(conn, args, updateCount)
+}
+
+func connQueryBefore(conn *DmConnection, sql string) {
+ conn.statInfo.setLastExecuteSql(sql)
+ conn.statInfo.setFirstResultSet(true)
+ conn.statInfo.setLastExecuteType(ExecuteQuery)
+ internalBeforeConnExecute(conn, sql)
+}
+
+func connQueryAfter(conn *DmConnection, sql string, args interface{}, resultSet *DmRows) {
+ if resultSet != nil {
+ connResultSetCreateAfter(resultSet, conn)
+ }
+ internalAfterConnExecute(conn, args, 0)
+}
+
+func stmtExecBefore(stmt *DmStatement) {
+ stmt.statInfo.setLastExecuteSql(stmt.nativeSql)
+ stmt.statInfo.setFirstResultSet(false)
+ stmt.statInfo.setLastExecuteType(ExecuteUpdate)
+ internalBeforeStatementExecute(stmt, stmt.nativeSql)
+}
+
+func stmtExecAfter(stmt *DmStatement, args interface{}, updateCount int) {
+ internalAfterStatementExecute(stmt, args, updateCount)
+}
+
+func stmtQueryBefore(stmt *DmStatement) {
+ stmt.statInfo.setLastExecuteSql(stmt.nativeSql)
+ stmt.statInfo.setFirstResultSet(true)
+ stmt.statInfo.setLastExecuteType(ExecuteQuery)
+ internalBeforeStatementExecute(stmt, stmt.nativeSql)
+}
+
+func stmtQueryAfter(stmt *DmStatement, args interface{}, resultSet *DmRows) {
+ if resultSet != nil {
+ stmtResultSetCreateAfter(resultSet, stmt)
+ }
+ internalAfterStatementExecute(stmt, args, 0)
+}
+
+func internalBeforeConnExecute(conn *DmConnection, sql string) {
+ connStat := conn.statInfo.getConnStat()
+ connStat.incrementExecuteCount()
+ conn.statInfo.beforeExecute()
+
+ sqlStat := conn.statInfo.getSqlStat()
+ if sqlStat == nil || sqlStat.Removed == 1 || !(sqlStat.Sql == sql) {
+ sqlStat = connStat.createSqlStat(sql)
+ conn.statInfo.setSqlStat(sqlStat)
+ }
+
+ inTransaction := false
+ inTransaction = !conn.autoCommit
+
+ if sqlStat != nil {
+ sqlStat.ExecuteLastStartTime = time.Now().UnixNano()
+ sqlStat.incrementRunningCount()
+
+ if inTransaction {
+ sqlStat.incrementInTransactionCount()
+ }
+ }
+}
+
+func internalAfterConnExecute(conn *DmConnection, args interface{}, updateCount int) {
+ nowNano := time.Now().UnixNano()
+ nanos := nowNano - conn.statInfo.getLastExecuteStartNano()
+
+ conn.statInfo.afterExecute(nanos)
+
+ sqlStat := conn.statInfo.getSqlStat()
+
+ if sqlStat != nil {
+ sqlStat.incrementExecuteSuccessCount()
+
+ sqlStat.decrementRunningCount()
+
+ parameters := buildSlowParameters(args)
+
+ sqlStat.addExecuteTimeAndResultHoldTimeHistogramRecord(conn.statInfo.getLastExecuteType(), conn.statInfo.isFirstResultSet(),
+ nanos, parameters)
+
+ if !conn.statInfo.isFirstResultSet() &&
+ conn.statInfo.getLastExecuteType() == ExecuteUpdate {
+ if updateCount < 0 {
+ updateCount = 0
+ }
+ sqlStat.addUpdateCount(int64(updateCount))
+ }
+ }
+
+}
+
+func internalBeforeStatementExecute(stmt *DmStatement, sql string) {
+ connStat := stmt.dmConn.statInfo.getConnStat()
+ connStat.incrementExecuteCount()
+ stmt.statInfo.beforeExecute()
+
+ sqlStat := stmt.statInfo.getSqlStat()
+ if sqlStat == nil || sqlStat.Removed == 1 || !(sqlStat.Sql == sql) {
+ sqlStat = connStat.createSqlStat(sql)
+ stmt.statInfo.setSqlStat(sqlStat)
+ }
+
+ inTransaction := false
+ inTransaction = !stmt.dmConn.autoCommit
+
+ if sqlStat != nil {
+ sqlStat.ExecuteLastStartTime = time.Now().UnixNano()
+ sqlStat.incrementRunningCount()
+
+ if inTransaction {
+ sqlStat.incrementInTransactionCount()
+ }
+ }
+}
+
+func internalAfterStatementExecute(stmt *DmStatement, args interface{}, updateCount int) {
+ nowNano := time.Now().UnixNano()
+ nanos := nowNano - stmt.statInfo.getLastExecuteStartNano()
+
+ stmt.statInfo.afterExecute(nanos)
+
+ sqlStat := stmt.statInfo.getSqlStat()
+
+ if sqlStat != nil {
+ sqlStat.incrementExecuteSuccessCount()
+
+ sqlStat.decrementRunningCount()
+
+ parameters := ""
+ if stmt.paramCount > 0 {
+ parameters = buildStmtSlowParameters(stmt, args)
+ }
+ sqlStat.addExecuteTimeAndResultHoldTimeHistogramRecord(stmt.statInfo.getLastExecuteType(), stmt.statInfo.isFirstResultSet(),
+ nanos, parameters)
+
+ if (!stmt.statInfo.isFirstResultSet()) &&
+ stmt.statInfo.getLastExecuteType() == ExecuteUpdate {
+ updateCount := stmt.execInfo.updateCount
+ if updateCount < 0 {
+ updateCount = 0
+ }
+ sqlStat.addUpdateCount(updateCount)
+ }
+
+ }
+
+}
+
+func buildSlowParameters(args interface{}) string {
+ switch v := args.(type) {
+ case []driver.Value:
+ sb := bytes.NewBufferString("")
+ for i := 0; i < len(v); i++ {
+ if i != 0 {
+ sb.WriteString(",")
+ } else {
+ sb.WriteString("[")
+ }
+
+ sb.WriteString(fmt.Sprint(v[i]))
+ }
+
+ if len(v) > 0 {
+ sb.WriteString("]")
+ }
+ return sb.String()
+ case []driver.NamedValue:
+ sb := bytes.NewBufferString("")
+ for i := 0; i < len(v); i++ {
+ if i != 0 {
+ sb.WriteString(",")
+ } else {
+ sb.WriteString("[")
+ }
+
+ sb.WriteString(fmt.Sprint(v[i]))
+ }
+ if len(v) > 0 {
+ sb.WriteString("]")
+ }
+ return sb.String()
+ default:
+ return ""
+ }
+}
+
+func buildStmtSlowParameters(stmt *DmStatement, args interface{}) string {
+ switch v := args.(type) {
+ case []driver.Value:
+ sb := bytes.NewBufferString("")
+ for i := 0; i < int(stmt.paramCount); i++ {
+ if i != 0 {
+ sb.WriteString(",")
+ } else {
+ sb.WriteString("[")
+ }
+
+ sb.WriteString(fmt.Sprint(v[i]))
+ }
+ if len(v) > 0 {
+ sb.WriteString("]")
+ }
+ return sb.String()
+ case []driver.NamedValue:
+ sb := bytes.NewBufferString("")
+ for i := 0; i < int(stmt.paramCount); i++ {
+ if i != 0 {
+ sb.WriteString(",")
+ } else {
+ sb.WriteString("[")
+ }
+
+ sb.WriteString(fmt.Sprint(v[i]))
+ }
+ if len(v) > 0 {
+ sb.WriteString("]")
+ }
+ return sb.String()
+ default:
+ return ""
+ }
+}
+
+func connExecuteErrorAfter(conn *DmConnection, args interface{}, err error) {
+ nanos := time.Now().UnixNano() - conn.statInfo.getLastExecuteStartNano()
+ conn.statInfo.getConnStat().incrementErrorCount()
+ conn.statInfo.afterExecute(nanos)
+
+ // SQL
+ sqlStat := conn.statInfo.getSqlStat()
+ if sqlStat != nil {
+ sqlStat.decrementRunningCount()
+ sqlStat.error(err)
+ parameters := buildSlowParameters(args)
+ sqlStat.addExecuteTimeAndResultHoldTimeHistogramRecord(conn.statInfo.getLastExecuteType(), conn.statInfo.isFirstResultSet(),
+ nanos, parameters)
+ }
+
+}
+
+func statementExecuteErrorAfter(stmt *DmStatement, args interface{}, err error) {
+ nanos := time.Now().UnixNano() - stmt.statInfo.getLastExecuteStartNano()
+ stmt.dmConn.statInfo.getConnStat().incrementErrorCount()
+ stmt.statInfo.afterExecute(nanos)
+
+ // SQL
+ sqlStat := stmt.statInfo.getSqlStat()
+ if sqlStat != nil {
+ sqlStat.decrementRunningCount()
+ sqlStat.error(err)
+ parameters := ""
+ if stmt.paramCount > 0 {
+ parameters = buildStmtSlowParameters(stmt, args)
+ }
+ sqlStat.addExecuteTimeAndResultHoldTimeHistogramRecord(stmt.statInfo.getLastExecuteType(), stmt.statInfo.isFirstResultSet(),
+ nanos, parameters)
+ }
+
+}
+
+func statementCloseBefore(stmt *DmStatement) {
+ stmt.dmConn.statInfo.getConnStat().decrementStmt()
+}
+
+func connResultSetCreateAfter(dmdbResultSet *DmRows, conn *DmConnection) {
+ dmdbResultSet.statInfo.setSql(conn.statInfo.getLastExecuteSql())
+ dmdbResultSet.statInfo.setSqlStat(conn.statInfo.getSqlStat())
+ dmdbResultSet.statInfo.setConstructNano()
+}
+
+func stmtResultSetCreateAfter(dmdbResultSet *DmRows, stmt *DmStatement) {
+ dmdbResultSet.statInfo.setSql(stmt.statInfo.getLastExecuteSql())
+ dmdbResultSet.statInfo.setSqlStat(stmt.statInfo.getSqlStat())
+ dmdbResultSet.statInfo.setConstructNano()
+}
+
+func resultSetCloseBefore(resultSet *DmRows) {
+ nanos := time.Now().UnixNano() - resultSet.statInfo.getConstructNano()
+ fetchRowCount := getFetchedRows(resultSet)
+ sqlStat := resultSet.statInfo.getSqlStat()
+ if sqlStat != nil && resultSet.statInfo.getCloseCount() == 0 {
+ sqlStat.addFetchRowCount(fetchRowCount)
+ stmtExecuteNano := resultSet.statInfo.getLastExecuteTimeNano()
+ sqlStat.addResultSetHoldTimeNano2(stmtExecuteNano, nanos)
+ if resultSet.statInfo.getReadStringLength() > 0 {
+ sqlStat.addStringReadLength(resultSet.statInfo.getReadStringLength())
+ }
+ if resultSet.statInfo.getReadBytesLength() > 0 {
+ sqlStat.addReadBytesLength(resultSet.statInfo.getReadBytesLength())
+ }
+ if resultSet.statInfo.getOpenInputStreamCount() > 0 {
+ sqlStat.addInputStreamOpenCount(int64(resultSet.statInfo.getOpenInputStreamCount()))
+ }
+ if resultSet.statInfo.getOpenReaderCount() > 0 {
+ sqlStat.addReaderOpenCount(int64(resultSet.statInfo.getOpenReaderCount()))
+ }
+ }
+
+ resultSet.statInfo.incrementCloseCount()
+}
+
+func getFetchedRows(rs *DmRows) int64 {
+ if rs.CurrentRows.currentPos >= rs.CurrentRows.totalRowCount {
+ return rs.CurrentRows.totalRowCount
+ } else {
+ return rs.CurrentRows.currentPos + 1
+ }
+}
diff --git a/dmr/zi.go b/dmr/zi.go
new file mode 100644
index 0000000..cb217fd
--- /dev/null
+++ b/dmr/zi.go
@@ -0,0 +1,1015 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "bytes"
+ "io"
+ "math/big"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+var G2DB g2db
+
+type g2db struct {
+}
+
+func (G2DB g2db) checkTinyint(val interface{}) error {
+ switch v := val.(type) {
+ case float64:
+ if v < float64(INT8_MIN) || v > float64(INT8_MAX) {
+ return ECGO_DATA_OVERFLOW.throw()
+ }
+ case DmDecimal:
+ if v.ToBigInt().Cmp(big.NewInt(int64(INT8_MIN))) < 0 ||
+ v.ToBigInt().Cmp(big.NewInt(int64(INT8_MAX))) > 0 {
+ return ECGO_DATA_OVERFLOW.throw()
+ }
+ }
+ return nil
+}
+
+func (G2DB g2db) checkSmallint(val interface{}) error {
+ switch v := val.(type) {
+ case float64:
+ if v < float64(INT16_MIN) || v > float64(INT16_MAX) {
+ return ECGO_DATA_OVERFLOW.throw()
+ }
+ case DmDecimal:
+ if v.ToBigInt().Cmp(big.NewInt(int64(INT16_MIN))) < 0 ||
+ v.ToBigInt().Cmp(big.NewInt(int64(INT16_MAX))) > 0 {
+ return ECGO_DATA_OVERFLOW.throw()
+ }
+ }
+ return nil
+}
+
+func (G2DB g2db) checkInt(val interface{}) error {
+ switch v := val.(type) {
+ case float64:
+ if v < float64(INT32_MIN) || v > float64(INT32_MAX) {
+ return ECGO_DATA_OVERFLOW.throw()
+ }
+ case DmDecimal:
+ if v.ToBigInt().Cmp(big.NewInt(int64(INT32_MIN))) < 0 ||
+ v.ToBigInt().Cmp(big.NewInt(int64(INT32_MAX))) > 0 {
+ return ECGO_DATA_OVERFLOW.throw()
+ }
+ }
+ return nil
+}
+
+func (G2DB g2db) checkBigint(val interface{}) error {
+ switch v := val.(type) {
+ case float64:
+ if v < float64(INT64_MIN) || v > float64(INT64_MAX) {
+ return ECGO_DATA_OVERFLOW.throw()
+ }
+ case DmDecimal:
+ if v.ToBigInt().Cmp(big.NewInt(INT64_MIN)) < 0 ||
+ v.ToBigInt().Cmp(big.NewInt(INT64_MAX)) > 0 {
+ return ECGO_DATA_OVERFLOW.throw()
+ }
+ }
+ return nil
+}
+
+func (G2DB g2db) checkReal(val interface{}) error {
+ switch v := val.(type) {
+ case float64:
+ if v < float64(FLOAT32_MIN) || v > float64(FLOAT32_MAX) {
+ return ECGO_DATA_OVERFLOW.throw()
+ }
+ case DmDecimal:
+ if v.ToBigFloat().Cmp(big.NewFloat(float64(FLOAT32_MIN))) < 0 ||
+ v.ToBigFloat().Cmp(big.NewFloat(float64(FLOAT32_MAX))) > 0 {
+ return ECGO_DATA_OVERFLOW.throw()
+ }
+ }
+ return nil
+}
+
+func (G2DB g2db) fromBool(val bool, param parameter, conn *DmConnection) ([]byte, error) {
+ switch param.colType {
+ case BOOLEAN, BIT, TINYINT, SMALLINT, INT, BIGINT, REAL, DOUBLE, DECIMAL, CHAR,
+ VARCHAR2, VARCHAR, CLOB:
+ if val {
+ return G2DB.fromInt64(1, param, conn)
+ } else {
+ return G2DB.fromInt64(0, param, conn)
+ }
+ case BINARY, VARBINARY, BLOB:
+ if val {
+ return Dm_build_1220.Dm_build_1398(byte(1)), nil
+ } else {
+ return Dm_build_1220.Dm_build_1398(byte(0)), nil
+ }
+ }
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (G2DB g2db) fromInt64(val int64, param parameter, conn *DmConnection) ([]byte, error) {
+
+ switch param.colType {
+ case BOOLEAN, BIT:
+ if val == 0 {
+ return Dm_build_1220.Dm_build_1398(byte(0)), nil
+ }
+
+ return Dm_build_1220.Dm_build_1398(byte(1)), nil
+
+ case TINYINT:
+ err := G2DB.checkTinyint(float64(val))
+
+ if err != nil {
+ return nil, err
+ }
+
+ return Dm_build_1220.Dm_build_1398(byte(val)), nil
+ case SMALLINT:
+ err := G2DB.checkSmallint(float64(val))
+
+ if err != nil {
+ return nil, err
+ }
+
+ return Dm_build_1220.Dm_build_1401(int16(val)), nil
+ case INT:
+ err := G2DB.checkInt(float64(val))
+
+ if err != nil {
+ return nil, err
+ }
+
+ return Dm_build_1220.Dm_build_1404(int32(val)), nil
+ case BIGINT:
+ err := G2DB.checkBigint(float64(val))
+
+ if err != nil {
+ return nil, err
+ }
+
+ return Dm_build_1220.Dm_build_1407(int64(val)), nil
+ case REAL:
+ err := G2DB.checkReal(float64(val))
+
+ if err != nil {
+ return nil, err
+ }
+
+ return Dm_build_1220.Dm_build_1410(float32(val)), nil
+ case DOUBLE:
+ return Dm_build_1220.Dm_build_1413(float64(val)), nil
+ case DECIMAL:
+ d, err := newDecimal(big.NewInt(val), int(param.prec), int(param.scale))
+ if err != nil {
+ return nil, err
+ }
+ return d.encodeDecimal()
+ case CHAR, VARCHAR2, VARCHAR, CLOB:
+ return Dm_build_1220.Dm_build_1433(strconv.FormatInt(val, 10), conn.getServerEncoding(), conn), nil
+ case BINARY, VARBINARY, BLOB:
+ return G2DB.ToBinary(val, int(param.prec)), nil
+ case DATE, TIME, DATETIME:
+ if err := G2DB.checkInt(float64(val)); err != nil {
+ return nil, err
+ }
+ return encodeByDateNumber(val, int(param.colType), int(param.scale), int(conn.dmConnector.localTimezone), conn.DbTimezone)
+ }
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (G2DB g2db) ToBinary(x int64, prec int) []byte {
+ b := make([]byte, 8)
+ b[7] = byte(x)
+ b[6] = byte(x >> 8)
+ b[5] = byte(x >> 16)
+ b[4] = byte(x >> 24)
+ b[3] = byte(x >> 32)
+ b[2] = byte(x >> 40)
+ b[1] = byte(x >> 48)
+ b[0] = byte(x >> 56)
+
+ if prec > 0 && prec < len(b) {
+ dest := make([]byte, prec)
+ copy(dest, b[len(b)-prec:])
+ return dest
+ }
+ return b
+}
+
+func (G2DB g2db) fromFloat32(val float32, param parameter, conn *DmConnection) ([]byte, error) {
+ switch param.colType {
+ case BOOLEAN, BIT:
+ if val == 0.0 {
+ return Dm_build_1220.Dm_build_1398(0), nil
+ }
+ return Dm_build_1220.Dm_build_1398(1), nil
+ case TINYINT:
+ if err := G2DB.checkTinyint(float64(val)); err != nil {
+ return nil, err
+ }
+ return Dm_build_1220.Dm_build_1398(byte(val)), nil
+ case SMALLINT:
+ if err := G2DB.checkSmallint(float64(val)); err != nil {
+ return nil, err
+ }
+ return Dm_build_1220.Dm_build_1401(int16(val)), nil
+ case INT:
+ if err := G2DB.checkInt(float64(val)); err != nil {
+ return nil, err
+ }
+ return Dm_build_1220.Dm_build_1404(int32(val)), nil
+ case BIGINT:
+ if err := G2DB.checkBigint(float64(val)); err != nil {
+ return nil, err
+ }
+ return Dm_build_1220.Dm_build_1407(int64(val)), nil
+ case REAL:
+ if err := G2DB.checkReal(float64(val)); err != nil {
+ return nil, err
+ }
+ return Dm_build_1220.Dm_build_1410(val), nil
+ case DOUBLE:
+ return Dm_build_1220.Dm_build_1413(float64(val)), nil
+ case DECIMAL:
+ d, err := newDecimal(big.NewFloat(float64(val)), int(param.prec), int(param.scale))
+ if err != nil {
+ return nil, err
+ }
+ return d.encodeDecimal()
+ case CHAR, VARCHAR2, VARCHAR, CLOB:
+ return Dm_build_1220.Dm_build_1433(strconv.FormatFloat(float64(val), 'f', -1, 32), conn.getServerEncoding(), conn), nil
+ }
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (G2DB g2db) fromFloat64(val float64, param parameter, conn *DmConnection) ([]byte, error) {
+
+ switch param.colType {
+ case BOOLEAN, BIT:
+ if val == 0.0 {
+ return Dm_build_1220.Dm_build_1398(0), nil
+ }
+ return Dm_build_1220.Dm_build_1398(1), nil
+
+ case TINYINT:
+ err := G2DB.checkTinyint(val)
+
+ if err != nil {
+ return nil, err
+ }
+
+ return Dm_build_1220.Dm_build_1398(byte(val)), nil
+ case SMALLINT:
+ err := G2DB.checkSmallint(val)
+
+ if err != nil {
+ return nil, err
+ }
+
+ return Dm_build_1220.Dm_build_1401(int16(val)), nil
+ case INT:
+ err := G2DB.checkInt(val)
+
+ if err != nil {
+ return nil, err
+ }
+
+ return Dm_build_1220.Dm_build_1404(int32(val)), nil
+ case BIGINT:
+ err := G2DB.checkBigint(val)
+
+ if err != nil {
+ return nil, err
+ }
+
+ return Dm_build_1220.Dm_build_1407(int64(val)), nil
+ case REAL:
+ err := G2DB.checkReal(val)
+
+ if err != nil {
+ return nil, err
+ }
+
+ return Dm_build_1220.Dm_build_1410(float32(val)), nil
+ case DOUBLE:
+ return Dm_build_1220.Dm_build_1413(float64(val)), nil
+ case DECIMAL:
+ d, err := newDecimal(big.NewFloat(val), int(param.prec), int(param.scale))
+ if err != nil {
+ return nil, err
+ }
+ return d.encodeDecimal()
+ case CHAR, VARCHAR2, VARCHAR, CLOB:
+ return Dm_build_1220.Dm_build_1433(strconv.FormatFloat(val, 'f', -1, 64), conn.getServerEncoding(), conn), nil
+ }
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (G2DB g2db) fromBytes(val []byte, param parameter, conn *DmConnection) (interface{}, error) {
+ switch param.colType {
+ case CHAR, VARCHAR2, VARCHAR:
+ return G2DB.toVarchar(val)
+ case CLOB:
+ b, err := G2DB.toVarchar(val)
+ if err != nil {
+ return nil, err
+ }
+ return G2DB.changeOffRowData(param, b, conn.getServerEncoding())
+ case BINARY, VARBINARY:
+ return val, nil
+ case BLOB:
+ return G2DB.bytes2Blob(val, param, conn)
+ case ARRAY, CLASS, PLTYPE_RECORD, SARRAY:
+ if param.typeDescriptor == nil {
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+ return TypeDataSV.objBlobToBytes(val, param.typeDescriptor)
+ }
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (G2DB g2db) toVarchar(bsArr []byte) ([]byte, error) {
+ if bsArr == nil || len(bsArr) == 0 {
+ return make([]byte, 0), nil
+ }
+
+ realLen := len(bsArr) * 2
+ bsRet := make([]byte, realLen)
+ for i := 0; i < len(bsArr); i++ {
+ bsTemp, err := G2DB.toChar(bsArr[i])
+ if err != nil {
+ return nil, err
+ }
+
+ bsRet[i*2] = bsTemp[0]
+ bsRet[i*2+1] = bsTemp[1]
+ }
+
+ return bsRet, nil
+}
+
+func (G2DB g2db) toChar(bt byte) ([]byte, error) {
+ bytes := make([]byte, 2)
+ var err error
+
+ bytes[0], err = G2DB.getCharByNumVal((bt >> 4) & 0x0F)
+ if err != nil {
+ return nil, err
+ }
+
+ bytes[1], err = G2DB.getCharByNumVal(bt & 0x0F)
+ if err != nil {
+ return nil, err
+ }
+
+ return bytes, nil
+}
+
+func (G2DB g2db) getCharByNumVal(val byte) (byte, error) {
+ if val >= 0 && val <= 9 {
+ return (byte)(val + '0'), nil
+ }
+
+ if val >= 0x0a && val <= 0x0F {
+ return (byte)(val + 'A' - 0x0a), nil
+ }
+ return 0, ECGO_INVALID_HEX.throw()
+}
+
+func (G2DB g2db) fromString(val string, param parameter, conn *DmConnection) (interface{}, error) {
+ switch param.colType {
+ case BOOLEAN, BIT:
+ ret, err := G2DB.toBool(val)
+ if err != nil {
+ return nil, err
+ }
+
+ if ret {
+ return Dm_build_1220.Dm_build_1398(byte(1)), nil
+ } else {
+ return Dm_build_1220.Dm_build_1398(byte(0)), nil
+ }
+
+ case TINYINT, SMALLINT, INT, BIGINT:
+ f, ok := new(big.Float).SetString(val)
+ if !ok {
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+ if f.Sign() < 0 {
+ f.Sub(f, big.NewFloat(0.5))
+ } else {
+ f.Add(f, big.NewFloat(0.5))
+ }
+ z, _ := f.Int(nil)
+ return G2DB.fromBigInt(z, param, conn)
+ case REAL, DOUBLE, DECIMAL:
+ f, ok := new(big.Float).SetString(val)
+ if ok {
+ return G2DB.fromBigFloat(f, param, conn)
+ } else {
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+
+ case CHAR, VARCHAR2, VARCHAR:
+ if isBFile(int(param.colType), int(param.prec), int(param.scale)) && !checkBFileStr(val) {
+ return nil, ECGO_INVALID_BFILE_STR.throw()
+ }
+ return Dm_build_1220.Dm_build_1433(val, conn.getServerEncoding(), conn), nil
+ case CLOB:
+ return G2DB.string2Clob(val, param, conn)
+ case BINARY, VARBINARY:
+ return util.StringUtil.HexStringToBytes(val), nil
+ case BLOB:
+ return G2DB.bytes2Blob(util.StringUtil.HexStringToBytes(val), param, conn)
+ case DATE:
+ if conn.FormatDate != "" {
+ dt, err := parse(val, conn.FormatDate, int(conn.OracleDateLanguage))
+ if err != nil {
+ return nil, err
+ }
+
+ return encode(dt, int(param.colType), int(param.scale), int(conn.dmConnector.localTimezone))
+ }
+
+ return encodeByString(val, int(param.colType), int(param.scale), int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
+ case TIME:
+ if conn.FormatTime != "" {
+ dt, err := parse(val, conn.FormatTime, int(conn.OracleDateLanguage))
+ if err != nil {
+ return nil, err
+ }
+
+ return encode(dt, int(param.colType), int(param.scale), int(conn.dmConnector.localTimezone))
+ }
+
+ return encodeByString(val, int(param.colType), int(param.scale), int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
+ case DATETIME:
+ if conn.FormatTimestamp != "" {
+ dt, err := parse(val, conn.FormatTimestamp, int(conn.OracleDateLanguage))
+ if err != nil {
+ return nil, err
+ }
+
+ return encode(dt, int(param.colType), int(param.scale), int(conn.dmConnector.localTimezone))
+ }
+
+ return encodeByString(val, int(param.colType), int(param.scale), int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
+ case TIME_TZ:
+ dt, err := parse(val, conn.FormatTimeTZ, int(conn.OracleDateLanguage))
+ if err != nil {
+ return nil, err
+ }
+
+ if conn.FormatTimeTZ != "" {
+ return encode(dt, int(param.colType), int(param.scale), int(conn.dmConnector.localTimezone))
+ }
+
+ return encodeByString(val, int(param.colType), int(param.scale), int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
+ case DATETIME_TZ:
+ if conn.FormatTimestampTZ != "" {
+ dt, err := parse(val, conn.FormatTimestampTZ, int(conn.OracleDateLanguage))
+ if err != nil {
+ return nil, err
+ }
+
+ return encode(dt, int(param.colType), int(param.scale), int(conn.dmConnector.localTimezone))
+ }
+
+ return encodeByString(val, int(param.colType), int(param.scale), int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
+ case INTERVAL_DT:
+ dt, err := NewDmIntervalDTByString(val)
+ if err != nil {
+ return nil, err
+ }
+ return dt.encode(int(param.scale))
+
+ case INTERVAL_YM:
+ ym, err := NewDmIntervalYMByString(val)
+ if err != nil {
+ return nil, err
+ }
+ return ym.encode(int(param.scale))
+ }
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (G2DB g2db) toBool(str string) (bool, error) {
+ str = strings.TrimSpace(str)
+ if util.StringUtil.Equals(str, "0") {
+ return false, nil
+ } else if util.StringUtil.Equals(str, "1") {
+ return true, nil
+ }
+
+ return strings.ToLower(str) == "true", nil
+}
+
+func (G2DB g2db) fromBigInt(val *big.Int, param parameter, conn *DmConnection) ([]byte, error) {
+ var ret []byte
+ switch param.colType {
+ case BOOLEAN, BIT:
+ if val.Sign() == 0 {
+ ret = Dm_build_1220.Dm_build_1398(0)
+ } else {
+ ret = Dm_build_1220.Dm_build_1398(1)
+ }
+ case TINYINT:
+ err := G2DB.checkTinyint(float64(val.Int64()))
+
+ if err != nil {
+ return nil, err
+ }
+
+ ret = Dm_build_1220.Dm_build_1398(byte(val.Int64()))
+ case SMALLINT:
+ err := G2DB.checkSmallint(float64(val.Int64()))
+
+ if err != nil {
+ return nil, err
+ }
+
+ ret = Dm_build_1220.Dm_build_1401(int16(val.Int64()))
+ case INT:
+ err := G2DB.checkInt(float64(val.Int64()))
+
+ if err != nil {
+ return nil, err
+ }
+
+ ret = Dm_build_1220.Dm_build_1404(int32(val.Int64()))
+ case BIGINT:
+ err := G2DB.checkBigint(float64(val.Int64()))
+
+ if err != nil {
+ return nil, err
+ }
+
+ ret = Dm_build_1220.Dm_build_1407(val.Int64())
+ case REAL:
+ err := G2DB.checkReal(float64(val.Int64()))
+
+ if err != nil {
+ return nil, err
+ }
+
+ ret = Dm_build_1220.Dm_build_1410(float32(val.Int64()))
+ case DOUBLE:
+ ret = Dm_build_1220.Dm_build_1413(float64(val.Int64()))
+ case DECIMAL, BINARY, VARBINARY, BLOB:
+ d, err := newDecimal(val, int(param.prec), int(param.scale))
+ if err != nil {
+ return nil, err
+ }
+ ret, err = d.encodeDecimal()
+ if err != nil {
+ return nil, err
+ }
+ case CHAR, VARCHAR2, VARCHAR, CLOB:
+ ret = Dm_build_1220.Dm_build_1433(val.String(), conn.getServerEncoding(), conn)
+ default:
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+ return ret, nil
+}
+
+func (G2DB g2db) fromBigFloat(val *big.Float, param parameter, conn *DmConnection) ([]byte, error) {
+ var ret []byte
+ switch param.colType {
+ case BOOLEAN, BIT:
+ if val.Sign() == 0 {
+ ret = Dm_build_1220.Dm_build_1398(0)
+ } else {
+ ret = Dm_build_1220.Dm_build_1398(1)
+ }
+ case TINYINT:
+ f, _ := val.Float64()
+
+ err := G2DB.checkTinyint(f)
+
+ if err != nil {
+ return nil, err
+ }
+
+ ret = Dm_build_1220.Dm_build_1398(byte(f))
+ case SMALLINT:
+ f, _ := val.Float64()
+
+ err := G2DB.checkSmallint(f)
+
+ if err != nil {
+ return nil, err
+ }
+
+ ret = Dm_build_1220.Dm_build_1401(int16(f))
+ case INT:
+ f, _ := val.Float64()
+
+ err := G2DB.checkInt(f)
+
+ if err != nil {
+ return nil, err
+ }
+
+ ret = Dm_build_1220.Dm_build_1404(int32(f))
+ case BIGINT:
+ f, _ := val.Float64()
+
+ err := G2DB.checkBigint(f)
+
+ if err != nil {
+ return nil, err
+ }
+
+ ret = Dm_build_1220.Dm_build_1407(int64(f))
+ case REAL:
+ f, _ := val.Float64()
+
+ err := G2DB.checkReal(f)
+
+ if err != nil {
+ return nil, err
+ }
+
+ ret = Dm_build_1220.Dm_build_1410(float32(f))
+ case DOUBLE:
+ f, _ := val.Float64()
+ ret = Dm_build_1220.Dm_build_1413(f)
+ case DECIMAL:
+ d, err := newDecimal(val, int(param.prec), int(param.scale))
+ if err != nil {
+ return nil, err
+ }
+ ret, err = d.encodeDecimal()
+ if err != nil {
+ return nil, err
+ }
+ case CHAR, VARCHAR2, VARCHAR, CLOB:
+ ret = Dm_build_1220.Dm_build_1433(val.Text('f', int(param.scale)), conn.getServerEncoding(), conn)
+ default:
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+ return ret, nil
+}
+
+func (G2DB g2db) fromDecimal(val DmDecimal, param parameter, conn *DmConnection) ([]byte, error) {
+ var ret []byte
+ switch param.colType {
+ case BOOLEAN, BIT:
+ if val.Sign() == 0 {
+ ret = Dm_build_1220.Dm_build_1398(0)
+ } else {
+ ret = Dm_build_1220.Dm_build_1398(1)
+ }
+ case TINYINT:
+ if err := G2DB.checkTinyint(val); err != nil {
+ return nil, err
+ }
+ ret = Dm_build_1220.Dm_build_1398(byte(val.ToBigInt().Int64()))
+ case SMALLINT:
+ if err := G2DB.checkSmallint(val); err != nil {
+ return nil, err
+ }
+ ret = Dm_build_1220.Dm_build_1401(int16(val.ToBigInt().Int64()))
+ case INT:
+ if err := G2DB.checkInt(val); err != nil {
+ return nil, err
+ }
+ ret = Dm_build_1220.Dm_build_1404(int32(val.ToBigInt().Int64()))
+ case BIGINT:
+ if err := G2DB.checkBigint(val); err != nil {
+ return nil, err
+ }
+ ret = Dm_build_1220.Dm_build_1407(int64(val.ToBigInt().Int64()))
+ case REAL:
+ if err := G2DB.checkReal(val); err != nil {
+ return nil, err
+ }
+ f, _ := val.ToBigFloat().Float32()
+ ret = Dm_build_1220.Dm_build_1410(f)
+ case DOUBLE:
+ f, _ := val.ToBigFloat().Float64()
+ ret = Dm_build_1220.Dm_build_1413(f)
+ case DECIMAL:
+ var err error
+ ret, err = val.encodeDecimal()
+ if err != nil {
+ return nil, err
+ }
+ case CHAR, VARCHAR2, VARCHAR, CLOB:
+ ret = Dm_build_1220.Dm_build_1433(val.ToBigFloat().Text('f', -1), conn.getServerEncoding(), conn)
+ default:
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+ return ret, nil
+}
+
+func (G2DB g2db) fromTime(val time.Time, param parameter, conn *DmConnection) ([]byte, error) {
+
+ switch param.colType {
+ case DATE, DATETIME, DATETIME_TZ, TIME, TIME_TZ:
+ return encodeByTime(val, int(param.colType), int(param.scale), int(conn.dmConnector.localTimezone), int(conn.DbTimezone))
+ case CHAR, VARCHAR2, VARCHAR, CLOB:
+ return Dm_build_1220.Dm_build_1433(val.Format("2006-01-02 15:04:05.999999999 -07:00"), conn.getServerEncoding(), conn), nil
+ }
+
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (G2DB g2db) fromDmIntervalDT(val DmIntervalDT, param parameter, conn *DmConnection) ([]byte, error) {
+ switch param.colType {
+ case CHAR, VARCHAR2, VARCHAR, CLOB:
+ return Dm_build_1220.Dm_build_1433(val.String(), conn.getServerEncoding(), conn), nil
+ case INTERVAL_DT:
+ return val.encode(int(param.scale))
+ default:
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+}
+
+func (G2DB g2db) fromDmdbIntervalYM(val DmIntervalYM, param parameter, conn *DmConnection) ([]byte, error) {
+
+ switch param.colType {
+ case CHAR, VARCHAR, VARCHAR2, CLOB:
+ return Dm_build_1220.Dm_build_1433(val.String(), conn.getServerEncoding(), conn), nil
+ case INTERVAL_YM:
+ return val.encode(int(param.scale))
+ default:
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+}
+
+func (G2DB g2db) fromBlob(val DmBlob, param parameter, conn *DmConnection) (interface{}, error) {
+ var ret interface{}
+ switch param.colType {
+ case BINARY, VARBINARY:
+ len, err := val.GetLength()
+ if err != nil {
+ return nil, err
+ }
+ ret, err = val.getBytes(1, int32(len))
+ if err != nil {
+ return nil, err
+ }
+ case BLOB:
+ var err error
+ ret, err = G2DB.blob2Blob(val, param, conn)
+ if err != nil {
+ return nil, err
+ }
+ case ARRAY, CLASS, PLTYPE_RECORD, SARRAY:
+
+ default:
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+ return ret, nil
+}
+
+func (G2DB g2db) fromClob(val DmClob, param parameter, conn *DmConnection) (interface{}, error) {
+ var ret interface{}
+ switch param.colType {
+ case CHAR, VARCHAR, VARCHAR2:
+ var len int64
+ var s string
+ var err error
+ len, err = val.GetLength()
+ if err != nil {
+ return nil, err
+ }
+ s, err = val.getSubString(1, int32(len))
+ if err != nil {
+ return nil, err
+ }
+ ret = []byte(s)
+ case CLOB:
+ var err error
+ ret, err = G2DB.clob2Clob(val, param, conn)
+ if err != nil {
+ return nil, err
+ }
+ default:
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+ return ret, nil
+}
+
+func (G2DB g2db) fromReader(val io.Reader, param parameter, conn *DmConnection) (interface{}, error) {
+ var ret interface{}
+ switch param.colType {
+ case CHAR, VARCHAR2, VARCHAR:
+ var bytesBuf = new(bytes.Buffer)
+ if _, err := bytesBuf.ReadFrom(val); err != nil {
+ return nil, err
+ }
+ return Dm_build_1220.Dm_build_1433(string(bytesBuf.Bytes()), conn.getServerEncoding(), conn), nil
+ case BINARY, VARBINARY:
+ var bytesBuf = new(bytes.Buffer)
+ if _, err := bytesBuf.ReadFrom(val); err != nil {
+ return nil, err
+ }
+ return util.StringUtil.HexStringToBytes(string(bytesBuf.Bytes())), nil
+ case BLOB, CLOB:
+ var binder = newOffRowReaderBinder(val, conn.getServerEncoding())
+ if binder.offRow {
+ ret = binder
+ } else {
+ ret = binder.readAll()
+ }
+ default:
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+ return ret, nil
+}
+
+func (G2DB g2db) string2Clob(val string, param parameter, conn *DmConnection) (interface{}, error) {
+ return G2DB.changeOffRowData(param, Dm_build_1220.Dm_build_1433(val, conn.getServerEncoding(), conn), conn.getServerEncoding())
+}
+
+func (G2DB g2db) bytes2Blob(val []byte, param parameter, conn *DmConnection) (interface{}, error) {
+ return G2DB.changeOffRowData(param, val, conn.getServerEncoding())
+}
+
+func (G2DB g2db) clob2Clob(val DmClob, param parameter, conn *DmConnection) (interface{}, error) {
+ var clobLen int64
+ var err error
+ if clobLen, err = val.GetLength(); err != nil {
+ return nil, err
+ }
+ if G2DB.isOffRow(param.colType, clobLen) {
+ return newOffRowClobBinder(val, conn.getServerEncoding()), nil
+ } else {
+ var length int64
+ var str string
+ if length, err = val.GetLength(); err != nil {
+ return nil, err
+ }
+ if str, err = val.getSubString(1, int32(length)); err != nil {
+ return nil, err
+ }
+ return Dm_build_1220.Dm_build_1433(str, conn.getServerEncoding(), conn), nil
+ }
+}
+
+func (G2DB g2db) blob2Blob(val DmBlob, param parameter, conn *DmConnection) (interface{}, error) {
+ var clobLen int64
+ var err error
+ if clobLen, err = val.GetLength(); err != nil {
+ return nil, err
+ }
+ if G2DB.isOffRow(param.colType, clobLen) {
+ return newOffRowBlobBinder(val, conn.getServerEncoding()), nil
+ } else {
+ var length int64
+ if length, err = val.GetLength(); err != nil {
+ return nil, err
+ }
+ return val.getBytes(1, int32(length))
+ }
+}
+
+func (G2DB g2db) changeOffRowData(paramDesc parameter, paramData []byte, encoding string) (interface{}, error) {
+ if G2DB.isOffRow(paramDesc.colType, int64(len(paramData))) {
+ return newOffRowBytesBinder(paramData, encoding), nil
+ } else {
+ return paramData, nil
+ }
+}
+
+func (G2DB g2db) isOffRow(dtype int32, length int64) bool {
+ return (dtype == BLOB || dtype == CLOB) && length > Dm_build_714
+}
+
+func (G2DB g2db) fromObject(mem interface{}, param parameter, conn *DmConnection) ([]byte, error) {
+ switch v := mem.(type) {
+ case bool:
+ return G2DB.fromBool(v, param, conn)
+ case rune:
+ val, err := G2DB.fromString(string(v), param, conn)
+ return val.([]byte), err
+ case string:
+ val, err := G2DB.fromString(v, param, conn)
+ return val.([]byte), err
+ case byte:
+ return G2DB.fromInt64(int64(v), param, conn)
+ case int:
+ return G2DB.fromInt64(int64(v), param, conn)
+ case int16:
+ return G2DB.fromInt64(int64(v), param, conn)
+ case int64:
+ return G2DB.fromInt64(v, param, conn)
+ case float32:
+ return G2DB.fromFloat64(float64(v), param, conn)
+ case float64:
+ return G2DB.fromFloat64(v, param, conn)
+ case time.Time:
+ return G2DB.fromTime(v, param, conn)
+ case DmDecimal:
+ return G2DB.fromDecimal(v, param, conn)
+ case DmIntervalDT:
+ return G2DB.fromDmIntervalDT(v, param, conn)
+ case DmIntervalYM:
+ return G2DB.fromDmdbIntervalYM(v, param, conn)
+ case DmBlob:
+ length, _ := v.GetLength()
+ return v.getBytes(1, int32(length))
+ case DmClob:
+ length, _ := v.GetLength()
+ str, err := v.getSubString(1, int32(length))
+ if err != nil {
+ return nil, err
+ }
+ return Dm_build_1220.Dm_build_1433(str, conn.getServerEncoding(), conn), nil
+ default:
+ return nil, ECGO_UNSUPPORTED_TYPE.throw()
+ }
+
+}
+
+func (G2DB g2db) toInt32(val int32) []byte {
+ bytes := make([]byte, 4)
+ Dm_build_1220.Dm_build_1236(bytes, 0, val)
+ return bytes
+}
+
+func (G2DB g2db) toInt64(val int64) []byte {
+ bytes := make([]byte, 8)
+ Dm_build_1220.Dm_build_1241(bytes, 0, val)
+ return bytes
+}
+
+func (G2DB g2db) toFloat32(val float32) []byte {
+ bytes := make([]byte, 4)
+ Dm_build_1220.Dm_build_1246(bytes, 0, val)
+ return bytes
+}
+
+func (G2DB g2db) toFloat64(val float64) []byte {
+ bytes := make([]byte, 8)
+ Dm_build_1220.Dm_build_1251(bytes, 0, val)
+ return bytes
+}
+
+func (G2DB g2db) toDecimal(val string, prec int, scale int) ([]byte, error) {
+ d, err := decodeDecimal([]byte(val), prec, scale)
+ if err != nil {
+ return nil, err
+ }
+ return d.encodeDecimal()
+}
+
+func (G2DB g2db) fromArray(x *DmArray, param parameter, connection *DmConnection) (interface{}, error) {
+ var ret interface{}
+ var err error
+ switch param.colType {
+ case SARRAY:
+ ret, err = TypeDataSV.sarrayToBytes(x, param.typeDescriptor)
+ case CLASS, ARRAY:
+ ret, err = TypeDataSV.arrayToBytes(x, param.typeDescriptor)
+ case BLOB:
+ ret, err = TypeDataSV.toBytesFromDmArray(x, param.typeDescriptor)
+ if err == nil {
+ ret, err = G2DB.bytes2Blob(ret.([]byte), param, connection)
+ }
+ default:
+ err = ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+ return ret, err
+}
+
+func (G2DB g2db) fromStruct(x *DmStruct, param parameter, connection *DmConnection) (interface{}, error) {
+ var ret interface{}
+ var err error
+ switch param.colType {
+ case CLASS:
+ ret, err = TypeDataSV.structToBytes(x, param.typeDescriptor)
+ case PLTYPE_RECORD:
+ ret, err = TypeDataSV.recordToBytes(x, param.typeDescriptor)
+ case BLOB:
+ ret, err = TypeDataSV.toBytesFromDmStruct(x, param.typeDescriptor)
+ if err == nil {
+ ret, err = G2DB.bytes2Blob(ret.([]byte), param, connection)
+ }
+
+ default:
+ err = ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+ return ret, err
+}
+
+func checkBFileStr(s string) bool {
+ strs := strings.Split(strings.TrimSpace(s), ":")
+ if len(strs) != 2 {
+ return false
+ }
+ if len(strs[0]) > 128 || len(strs[1]) > 256 {
+ return false
+ }
+ return true
+}
diff --git a/dmr/zn.go b/dmr/zn.go
new file mode 100644
index 0000000..4b8654d
--- /dev/null
+++ b/dmr/zn.go
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+const (
+ LOB_FLAG_BYTE = 0
+ LOB_FLAG_CHAR = 1
+
+ LOB_IN_ROW = 0x1
+ LOB_OFF_ROW = 0x2
+
+ NBLOB_HEAD_IN_ROW_FLAG = 0
+ NBLOB_HEAD_BLOBID = NBLOB_HEAD_IN_ROW_FLAG + BYTE_SIZE
+ NBLOB_HEAD_BLOB_LEN = NBLOB_HEAD_BLOBID + DDWORD_SIZE
+
+ NBLOB_HEAD_OUTROW_GROUPID = NBLOB_HEAD_BLOB_LEN + ULINT_SIZE
+ NBLOB_HEAD_OUTROW_FILEID = NBLOB_HEAD_OUTROW_GROUPID + USINT_SIZE
+ NBLOB_HEAD_OUTROW_PAGENO = NBLOB_HEAD_OUTROW_FILEID + USINT_SIZE
+
+ NBLOB_EX_HEAD_TABLE_ID = NBLOB_HEAD_OUTROW_PAGENO + ULINT_SIZE
+ NBLOB_EX_HEAD_COL_ID = NBLOB_EX_HEAD_TABLE_ID + ULINT_SIZE
+ NBLOB_EX_HEAD_ROW_ID = NBLOB_EX_HEAD_COL_ID + USINT_SIZE
+ NBLOB_EX_HEAD_FPA_GRPID = NBLOB_EX_HEAD_ROW_ID + LINT64_SIZE
+ NBLOB_EX_HEAD_FPA_FILEID = NBLOB_EX_HEAD_FPA_GRPID + USINT_SIZE
+ NBLOB_EX_HEAD_FPA_PAGENO = NBLOB_EX_HEAD_FPA_FILEID + USINT_SIZE
+ NBLOB_EX_HEAD_SIZE = NBLOB_EX_HEAD_FPA_PAGENO + ULINT_SIZE
+
+ NBLOB_OUTROW_HEAD_SIZE = NBLOB_HEAD_OUTROW_PAGENO + ULINT_SIZE
+
+ NBLOB_INROW_HEAD_SIZE = NBLOB_HEAD_BLOB_LEN + ULINT_SIZE
+)
+
+type lob struct {
+ blobId int64
+ inRow bool
+
+ groupId int16
+ fileId int16
+ pageNo int32
+ tabId int32
+ colId int16
+ rowId int64
+ exGroupId int16
+ exFileId int16
+ exPageNo int32
+
+ curFileId int16
+ curPageNo int32
+ curPageOffset int16
+ totalOffset int32
+ readOver bool
+
+ connection *DmConnection
+ local bool
+ updateable bool
+ lobFlag int8
+ length int64
+ compatibleOracle bool
+ fetchAll bool
+ freed bool
+ modify bool
+
+ Valid bool
+}
+
+func (lob *lob) GetLength() (int64, error) {
+ var err error
+ if err = lob.checkValid(); err != nil {
+ return -1, err
+ }
+ if err = lob.checkFreed(); err != nil {
+ return -1, err
+ }
+ if lob.length == -1 {
+
+ if lob.length, err = lob.connection.Access.dm_build_491(lob); err != nil {
+ return -1, err
+ }
+ }
+ return lob.length, nil
+}
+
+func (lob *lob) resetCurrentInfo() {
+ lob.curFileId = lob.fileId
+ lob.curPageNo = lob.pageNo
+ lob.totalOffset = 0
+ lob.curPageOffset = 0
+}
+
+func (lob *lob) getLengthFromHead(head []byte) int64 {
+ return int64(Dm_build_1220.Dm_build_1322(head, NBLOB_HEAD_BLOB_LEN))
+}
+
+func (lob *lob) canOptimized(connection *DmConnection) bool {
+ return !(lob.inRow || lob.fetchAll || lob.local || connection != lob.connection)
+}
+
+func (lob *lob) buildCtlData() (bytes []byte) {
+ if lob.connection.NewLobFlag {
+ bytes = make([]byte, NBLOB_EX_HEAD_SIZE, NBLOB_EX_HEAD_SIZE)
+ } else {
+ bytes = make([]byte, NBLOB_OUTROW_HEAD_SIZE, NBLOB_OUTROW_HEAD_SIZE)
+ }
+ Dm_build_1220.Dm_build_1221(bytes, NBLOB_HEAD_IN_ROW_FLAG, LOB_OFF_ROW)
+ Dm_build_1220.Dm_build_1241(bytes, NBLOB_HEAD_BLOBID, lob.blobId)
+ Dm_build_1220.Dm_build_1236(bytes, NBLOB_HEAD_BLOB_LEN, -1)
+
+ Dm_build_1220.Dm_build_1231(bytes, NBLOB_HEAD_OUTROW_GROUPID, lob.groupId)
+ Dm_build_1220.Dm_build_1231(bytes, NBLOB_HEAD_OUTROW_FILEID, lob.fileId)
+ Dm_build_1220.Dm_build_1236(bytes, NBLOB_HEAD_OUTROW_PAGENO, lob.pageNo)
+
+ if lob.connection.NewLobFlag {
+ Dm_build_1220.Dm_build_1236(bytes, NBLOB_EX_HEAD_TABLE_ID, lob.tabId)
+ Dm_build_1220.Dm_build_1231(bytes, NBLOB_EX_HEAD_COL_ID, lob.colId)
+ Dm_build_1220.Dm_build_1241(bytes, NBLOB_EX_HEAD_ROW_ID, lob.rowId)
+ Dm_build_1220.Dm_build_1231(bytes, NBLOB_EX_HEAD_FPA_GRPID, lob.exGroupId)
+ Dm_build_1220.Dm_build_1231(bytes, NBLOB_EX_HEAD_FPA_FILEID, lob.exFileId)
+ Dm_build_1220.Dm_build_1236(bytes, NBLOB_EX_HEAD_FPA_PAGENO, lob.exPageNo)
+ }
+ return
+}
+
+func (lob *lob) checkFreed() (err error) {
+ if lob.freed {
+ err = ECGO_LOB_FREED.throw()
+ }
+ return
+}
+
+func (lob *lob) checkValid() error {
+ if !lob.Valid {
+ return ECGO_IS_NULL.throw()
+ }
+ return nil
+}
diff --git a/dmr/zo.go b/dmr/zo.go
new file mode 100644
index 0000000..98f0861
--- /dev/null
+++ b/dmr/zo.go
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+const (
+ ParamDataEnum_Null = 0
+ /**
+ * 只有大字段才有行内数据、行外数据的概念
+ */
+ ParamDataEnum_OFF_ROW = 1
+)
+
+type lobCtl struct {
+ value []byte
+}
diff --git a/dmr/zp.go b/dmr/zp.go
new file mode 100644
index 0000000..223566b
--- /dev/null
+++ b/dmr/zp.go
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "os"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+const (
+ MAX_FILE_SIZE = 100 * 1024 * 1024
+ FLUSH_SIZE = 32 * 1024
+)
+
+type goRun interface {
+ doRun()
+}
+
+type logWriter struct {
+ flushQueue chan []byte
+ date string
+ logFile *os.File
+ flushFreq int
+ filePath string
+ filePrefix string
+ buffer *Dm_build_1499
+}
+
+func (lw *logWriter) doRun() {
+ defer func() {
+ lw.beforeExit()
+ lw.closeCurrentFile()
+ }()
+
+ i := 0
+ for {
+ var ibytes []byte
+
+ select {
+ case ibytes = <-lw.flushQueue:
+ if LogLevel != LOG_OFF {
+ if i == LogFlushQueueSize {
+ lw.doFlush(lw.buffer)
+ i = 0
+ } else {
+ lw.buffer.Dm_build_1525(ibytes, 0, len(ibytes))
+ i++
+ }
+ }
+ case <-time.After(time.Duration(LogFlushFreq) * time.Millisecond):
+ if LogLevel != LOG_OFF && lw.buffer.Dm_build_1504() > 0 {
+ lw.doFlush(lw.buffer)
+ i = 0
+ }
+
+ }
+
+ }
+}
+
+func (lw *logWriter) doFlush(buffer *Dm_build_1499) {
+ if lw.needCreateNewFile() {
+ lw.closeCurrentFile()
+ lw.logFile = lw.createNewFile()
+ }
+ buffer.Dm_build_1519(lw.logFile, buffer.Dm_build_1504())
+}
+func (lw *logWriter) closeCurrentFile() {
+ if lw.logFile != nil {
+ lw.logFile.Close()
+ lw.logFile = nil
+ }
+}
+func (lw *logWriter) createNewFile() *os.File {
+ lw.date = time.Now().Format("2006-01-02")
+ fileName := lw.filePrefix + "_" + lw.date + "_" + strconv.Itoa(time.Now().Nanosecond()) + ".log"
+ lw.filePath = LogDir
+ if len(lw.filePath) > 0 {
+ if _, err := os.Stat(lw.filePath); err != nil {
+ os.MkdirAll(lw.filePath, 0755)
+ }
+ if _, err := os.Stat(lw.filePath + fileName); err != nil {
+ logFile, err := os.Create(lw.filePath + fileName)
+ if err != nil {
+ panic(err)
+ }
+ return logFile
+ }
+ }
+ return nil
+}
+func (lw *logWriter) needCreateNewFile() bool {
+ now := time.Now().Format("2006-01-02")
+ fileInfo, err := lw.logFile.Stat()
+ return now != lw.date || err != nil || lw.logFile == nil || fileInfo.Size() > int64(MAX_FILE_SIZE)
+}
+func (lw *logWriter) beforeExit() {
+ close(lw.flushQueue)
+ var ibytes []byte
+ for ibytes = <-lw.flushQueue; ibytes != nil; ibytes = <-lw.flushQueue {
+ lw.buffer.Dm_build_1525(ibytes, 0, len(ibytes))
+ if lw.buffer.Dm_build_1504() >= LogBufferSize {
+ lw.doFlush(lw.buffer)
+ }
+ }
+ if lw.buffer.Dm_build_1504() > 0 {
+ lw.doFlush(lw.buffer)
+ }
+}
+
+func (lw *logWriter) WriteLine(msg string) {
+ var b = []byte(strings.TrimSpace(msg) + util.LINE_SEPARATOR)
+ lw.flushQueue <- b
+}
diff --git a/dmr/zq.go b/dmr/zq.go
new file mode 100644
index 0000000..08691ee
--- /dev/null
+++ b/dmr/zq.go
@@ -0,0 +1,2762 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "os"
+ "strconv"
+ "strings"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+const (
+ Dm_build_597 = "7.6.0.0"
+
+ Dm_build_598 = "7.0.0.9"
+
+ Dm_build_599 = "8.0.0.73"
+
+ Dm_build_600 = "7.1.2.128"
+
+ Dm_build_601 = "7.1.5.144"
+
+ Dm_build_602 = "7.1.6.123"
+
+ Dm_build_603 = 2
+
+ Dm_build_604 = 32768 - 128
+
+ Dm_build_605 = 0x20000000
+
+ Dm_build_606 int16 = 1
+
+ Dm_build_607 int16 = 2
+
+ Dm_build_608 int16 = 3
+
+ Dm_build_609 int16 = 4
+
+ Dm_build_610 int16 = 5
+
+ Dm_build_611 int16 = 6
+
+ Dm_build_612 int16 = 7
+
+ Dm_build_613 int16 = 8
+
+ Dm_build_614 int16 = 9
+
+ Dm_build_615 int16 = 13
+
+ Dm_build_616 int16 = 14
+
+ Dm_build_617 int16 = 15
+
+ Dm_build_618 int16 = 17
+
+ Dm_build_619 int16 = 21
+
+ Dm_build_620 int16 = 24
+
+ Dm_build_621 int16 = 27
+
+ Dm_build_622 int16 = 29
+
+ Dm_build_623 int16 = 30
+
+ Dm_build_624 int16 = 31
+
+ Dm_build_625 int16 = 32
+
+ Dm_build_626 int16 = 44
+
+ Dm_build_627 int16 = 52
+
+ Dm_build_628 int16 = 60
+
+ Dm_build_629 int16 = 71
+
+ Dm_build_630 int16 = 90
+
+ Dm_build_631 int16 = 91
+
+ Dm_build_632 int16 = 200
+
+ Dm_build_633 = 64
+
+ Dm_build_634 = 20
+
+ Dm_build_635 = 0
+
+ Dm_build_636 = 4
+
+ Dm_build_637 = 6
+
+ Dm_build_638 = 10
+
+ Dm_build_639 = 14
+
+ Dm_build_640 = 18
+
+ Dm_build_641 = 19
+
+ Dm_build_642 = 128
+
+ Dm_build_643 = 256
+
+ Dm_build_644 = 0xffff
+
+ Dm_build_645 int32 = 2
+
+ Dm_build_646 int32 = 5
+
+ Dm_build_647 = -1
+
+ Dm_build_648 uint16 = 0xFFFE
+
+ Dm_build_649 uint16 = uint16(Dm_build_648 - 3)
+
+ Dm_build_650 uint16 = Dm_build_648
+
+ Dm_build_651 int32 = 0xFFFF
+
+ Dm_build_652 int32 = 0x80
+
+ Dm_build_653 byte = 0x60
+
+ Dm_build_654 uint16 = uint16(Dm_build_650)
+
+ Dm_build_655 uint16 = uint16(Dm_build_651)
+
+ Dm_build_656 int16 = 0x00
+
+ Dm_build_657 int16 = 0x03
+
+ Dm_build_658 int32 = 0x80
+
+ Dm_build_659 byte = 0
+
+ Dm_build_660 byte = 1
+
+ Dm_build_661 byte = 2
+
+ Dm_build_662 byte = 3
+
+ Dm_build_663 byte = 4
+
+ Dm_build_664 byte = Dm_build_659
+
+ Dm_build_665 int = 10
+
+ Dm_build_666 int32 = 32
+
+ Dm_build_667 int32 = 65536
+
+ Dm_build_668 byte = 0
+
+ Dm_build_669 byte = 1
+
+ Dm_build_670 int32 = 0x00000000
+
+ Dm_build_671 int32 = 0x00000020
+
+ Dm_build_672 int32 = 0x00000040
+
+ Dm_build_673 int32 = 0x00000FFF
+
+ Dm_build_674 int32 = 0
+
+ Dm_build_675 int32 = 1
+
+ Dm_build_676 int32 = 2
+
+ Dm_build_677 int32 = 3
+
+ Dm_build_678 = 8192
+
+ Dm_build_679 = 1
+
+ Dm_build_680 = 2
+
+ Dm_build_681 = 0
+
+ Dm_build_682 = 0
+
+ Dm_build_683 = 1
+
+ Dm_build_684 = -1
+
+ Dm_build_685 int16 = 0
+
+ Dm_build_686 int16 = 1
+
+ Dm_build_687 int16 = 2
+
+ Dm_build_688 int16 = 3
+
+ Dm_build_689 int16 = 4
+
+ Dm_build_690 int16 = 127
+
+ Dm_build_691 int16 = Dm_build_690 + 20
+
+ Dm_build_692 int16 = Dm_build_690 + 21
+
+ Dm_build_693 int16 = Dm_build_690 + 22
+
+ Dm_build_694 int16 = Dm_build_690 + 24
+
+ Dm_build_695 int16 = Dm_build_690 + 25
+
+ Dm_build_696 int16 = Dm_build_690 + 26
+
+ Dm_build_697 int16 = Dm_build_690 + 30
+
+ Dm_build_698 int16 = Dm_build_690 + 31
+
+ Dm_build_699 int16 = Dm_build_690 + 32
+
+ Dm_build_700 int16 = Dm_build_690 + 33
+
+ Dm_build_701 int16 = Dm_build_690 + 35
+
+ Dm_build_702 int16 = Dm_build_690 + 38
+
+ Dm_build_703 int16 = Dm_build_690 + 39
+
+ Dm_build_704 int16 = Dm_build_690 + 51
+
+ Dm_build_705 int16 = Dm_build_690 + 71
+
+ Dm_build_706 int16 = Dm_build_690 + 124
+
+ Dm_build_707 int16 = Dm_build_690 + 125
+
+ Dm_build_708 int16 = Dm_build_690 + 126
+
+ Dm_build_709 int16 = Dm_build_690 + 127
+
+ Dm_build_710 int16 = Dm_build_690 + 128
+
+ Dm_build_711 int16 = Dm_build_690 + 129
+
+ Dm_build_712 byte = 0
+
+ Dm_build_713 byte = 2
+
+ Dm_build_714 = 2048
+
+ Dm_build_715 = -1
+
+ Dm_build_716 = 0
+
+ Dm_build_717 = 16000
+
+ Dm_build_718 = 32000
+
+ Dm_build_719 = 0x00000000
+
+ Dm_build_720 = 0x00000020
+
+ Dm_build_721 = 0x00000040
+
+ Dm_build_722 = 0x00000FFF
+
+ Dm_build_723 = 4
+)
+
+var Dm_build_724 = [8][256]uint32{
+
+ {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535,
+ 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b,
+ 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148,
+ 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63,
+ 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1,
+ 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6,
+ 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac,
+ 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87,
+ 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc,
+ 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2,
+ 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97,
+ 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea,
+ 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158,
+ 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d,
+ 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73,
+ 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e,
+ 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b,
+ 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739,
+ 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e,
+ 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671,
+ 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f,
+ 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4,
+ 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda,
+ 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795,
+ 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92,
+ 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0,
+ 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785,
+ 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8,
+ 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6,
+ 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3,
+ 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661,
+ 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c,
+ 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729,
+ 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37,
+ 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d},
+
+ {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, 0x7d77f445, 0x565aa786,
+ 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c,
+ 0xb5ae7e4d, 0x9e832d8e, 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3,
+ 0x61ef4192, 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859,
+ 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, 0xd4413fdf,
+ 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, 0xbea97761, 0xf1e8e1a6,
+ 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, 0x5d5daeaa, 0x44469feb, 0x6f6bcc28,
+ 0x7670fd69, 0x39316bae, 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3,
+ 0xc65d07b2, 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175,
+ 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, 0x73f379ff,
+ 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, 0xe9627e44, 0xc24f2d87,
+ 0xdb541cc6, 0x94158a01, 0x8d0ebb40, 0xa623e883, 0xbf38d9c2, 0x38a0c50d,
+ 0x21bbf44c, 0x0a96a78f, 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b,
+ 0x77e153ca, 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850,
+ 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, 0x4054b5de,
+ 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, 0x3d23419b, 0x65fd6ba7,
+ 0x7ce65ae6, 0x57cb0925, 0x4ed03864, 0x0191aea3, 0x188a9fe2, 0x33a7cc21,
+ 0x2abcfd60, 0xad24e1af, 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab,
+ 0xd05315ea, 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74,
+ 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, 0xe7e6f3fe,
+ 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, 0x9a9107bb, 0xb1bc5478,
+ 0xa8a76539, 0x3b83984b, 0x2298a90a, 0x09b5fac9, 0x10aecb88, 0x5fef5d4f,
+ 0x46f46c0e, 0x6dd93fcd, 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1,
+ 0xd8774180, 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a,
+ 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, 0x271b2d9c,
+ 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, 0x92b553d1, 0xddf4c516,
+ 0xc4eff457, 0xefc2a794, 0xf6d996d5, 0xae07bce9, 0xb71c8da8, 0x9c31de6b,
+ 0x852aef2a, 0xca6b79ed, 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1,
+ 0x7fc507a0, 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167,
+ 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, 0x80a96bbc,
+ 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, 0x350715f1, 0x1e2a4632,
+ 0x07317773, 0x4870e1b4, 0x516bd0f5, 0x7a468336, 0x635db277, 0xcbfad74e,
+ 0xd2e1e60f, 0xf9ccb5cc, 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8,
+ 0x84bb4189, 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842,
+ 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, 0xb30ea79d,
+ 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, 0xce7953d8, 0x49e14f17,
+ 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, 0x2d8d8a13, 0x3496bb52, 0x1fbbe891,
+ 0x06a0d9d0, 0x5e7ef3ec, 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8,
+ 0x230907a9, 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66,
+ 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, 0x14bce1bd,
+ 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, 0x69cb15f8, 0x42e6463b,
+ 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, 0xee530937, 0xf7483876, 0xb809aeb1,
+ 0xa1129ff0, 0x8a3fcc33, 0x9324fd72},
+
+ {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, 0x06cbc2eb, 0x048d7cb2,
+ 0x054f1685, 0x0e1351b8, 0x0fd13b8f, 0x0d9785d6, 0x0c55efe1, 0x091af964,
+ 0x08d89353, 0x0a9e2d0a, 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e,
+ 0x1e601d29, 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8,
+ 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, 0x16b88e7a,
+ 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, 0x3a0bf8b9, 0x3f44ee3c,
+ 0x3e86840b, 0x3cc03a52, 0x3d025065, 0x365e1758, 0x379c7d6f, 0x35dac336,
+ 0x3418a901, 0x3157bf84, 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590,
+ 0x25a98fa7, 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922,
+ 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, 0x2d711cf4,
+ 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, 0x7158e7f7, 0x731e59ae,
+ 0x72dc3399, 0x7793251c, 0x76514f2b, 0x7417f172, 0x75d59b45, 0x7e89dc78,
+ 0x7f4bb64f, 0x7d0d0816, 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca,
+ 0x7bc6cafd, 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c,
+ 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, 0x612bab66,
+ 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, 0x67e0698d, 0x48d7cb20,
+ 0x4915a117, 0x4b531f4e, 0x4a917579, 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792,
+ 0x4d98dda5, 0x46c49a98, 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244,
+ 0x400f5873, 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e,
+ 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, 0x5ae239e8,
+ 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, 0x5c29fb03, 0x5e6f455a,
+ 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c,
+ 0xe7fed96b, 0xe5b86732, 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56,
+ 0xed60f461, 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0,
+ 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, 0xf99ec442,
+ 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, 0xf1465711, 0xf4094194,
+ 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, 0xd9785d60, 0xd8ba3757, 0xdafc890e,
+ 0xdb3ee339, 0xde71f5bc, 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8,
+ 0xd6a966ef, 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a,
+ 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, 0xc25756cc,
+ 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, 0xca8fc59f, 0xc8c97bc6,
+ 0xc90b11f1, 0xcc440774, 0xcd866d43, 0xcfc0d31a, 0xce02b92d, 0x91af9640,
+ 0x906dfc77, 0x922b422e, 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2,
+ 0x94e080c5, 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24,
+ 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, 0x8e0de15e,
+ 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, 0x88c623b5, 0x839a6488,
+ 0x82580ebf, 0x801eb0e6, 0x81dcdad1, 0x8493cc54, 0x8551a663, 0x8717183a,
+ 0x86d5720d, 0xa9e2d0a0, 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c,
+ 0xaf29124b, 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576,
+ 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, 0xb5c473d0,
+ 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, 0xb30fb13b, 0xb1490f62,
+ 0xb08b6555, 0xbbd72268, 0xba15485f, 0xb853f606, 0xb9919c31, 0xbcde8ab4,
+ 0xbd1ce083, 0xbf5a5eda, 0xbe9834ed},
+
+ {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, 0x37def032, 0x256b5fdc,
+ 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, 0x6fbde064, 0xd7018701, 0x4ad6bfb8,
+ 0xf26ad8dd, 0xe0df7733, 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14,
+ 0x42acf871, 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70,
+ 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, 0xb0c620ac,
+ 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, 0xb28700d0, 0x2f503869,
+ 0x97ec5f0c, 0x8559f0e2, 0x3de59787, 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a,
+ 0x7733283f, 0xeae41086, 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1,
+ 0x48979fc4, 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d,
+ 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, 0xbafd4719,
+ 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, 0x23a83f58, 0x311d90b6,
+ 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, 0xbe7f07e1, 0x06c36084, 0x5ea070d2,
+ 0xe61c17b7, 0xf4a9b859, 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e,
+ 0xc377486b, 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5,
+ 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, 0xa4b0efc6,
+ 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, 0x936e1ff4, 0x3b26f703,
+ 0x839a9066, 0x912f3f88, 0x299358ed, 0xb4446054, 0x0cf80731, 0x1e4da8df,
+ 0xa6f1cfba, 0xfe92dfec, 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb,
+ 0xc94c2fde, 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817,
+ 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, 0xae8b8873,
+ 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, 0x99557841, 0x8be0d7af,
+ 0x335cb0ca, 0xed59b63b, 0x55e5d15e, 0x47507eb0, 0xffec19d5, 0x623b216c,
+ 0xda874609, 0xc832e9e7, 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f,
+ 0x3a58313a, 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4,
+ 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, 0x982bbe78,
+ 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, 0x6a4166a5, 0xf7965e1c,
+ 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, 0x4d6b1905, 0xf5d77e60, 0xe762d18e,
+ 0x5fdeb6eb, 0xc2098e52, 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea,
+ 0x3063568f, 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36,
+ 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, 0x9210d9cd,
+ 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, 0x607a0110, 0x72cfaefe,
+ 0xca73c99b, 0x57a4f122, 0xef189647, 0xfdad39a9, 0x45115ecc, 0x764dee06,
+ 0xcef18963, 0xdc44268d, 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da,
+ 0xeb9ad6bf, 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be,
+ 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, 0x8c5d7112,
+ 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, 0xbb838120, 0xe3e09176,
+ 0x5b5cf613, 0x49e959fd, 0xf1553e98, 0x6c820621, 0xd43e6144, 0xc68bceaa,
+ 0x7e37a9cf, 0xd67f4138, 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f,
+ 0xe1a1b10a, 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c,
+ 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, 0x866616a7,
+ 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, 0xb1b8e695, 0xa30d497b,
+ 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, 0xe9dbf6c3, 0x516791a6, 0xccb0a91f,
+ 0x740cce7a, 0x66b96194, 0xde0506f1},
+
+ {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, 0xc8e08f70, 0x8f40f5a0,
+ 0xb220dc10, 0x30704bc1, 0x0d106271, 0x4ab018a1, 0x77d03111, 0xc5f0ed01,
+ 0xf890c4b1, 0xbf30be61, 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2,
+ 0x2740ed52, 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43,
+ 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, 0xdfd029e3,
+ 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, 0x866155d4, 0x344189c4,
+ 0x0921a074, 0x4e81daa4, 0x73e1f314, 0xf1b164c5, 0xccd14d75, 0x8b7137a5,
+ 0xb6111e15, 0x0431c205, 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886,
+ 0x9c419136, 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26,
+ 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, 0x64d15587,
+ 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, 0x659371f9, 0x22330b29,
+ 0x1f532299, 0xad73fe89, 0x9013d739, 0xd7b3ade9, 0xead38459, 0x68831388,
+ 0x55e33a38, 0x124340e8, 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628,
+ 0xdaa3cf98, 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b,
+ 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, 0x72a3d76a,
+ 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, 0xba43581a, 0x9932774d,
+ 0xa4525efd, 0xe3f2242d, 0xde920d9d, 0x6cb2d18d, 0x51d2f83d, 0x167282ed,
+ 0x2b12ab5d, 0xa9423c8c, 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c,
+ 0x61a2b3fc, 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af,
+ 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, 0xc9a2ab0e,
+ 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, 0x0142247e, 0x46e25eae,
+ 0x7b82771e, 0xb1e6b092, 0x8c869922, 0xcb26e3f2, 0xf646ca42, 0x44661652,
+ 0x79063fe2, 0x3ea64532, 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833,
+ 0xc6368183, 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710,
+ 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, 0x5e46d2b0,
+ 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, 0xa6d61601, 0x14f6ca11,
+ 0x2996e3a1, 0x6e369971, 0x5356b0c1, 0x70279f96, 0x4d47b626, 0x0ae7ccf6,
+ 0x3787e546, 0x85a73956, 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457,
+ 0x7d37fde7, 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7,
+ 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, 0xe547aed4,
+ 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, 0x1dd76a65, 0x5a7710b5,
+ 0x67173905, 0xd537e515, 0xe857cca5, 0xaff7b675, 0x92979fc5, 0xe915e8db,
+ 0xd475c16b, 0x93d5bbbb, 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b,
+ 0x5b3534cb, 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da,
+ 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, 0xf3352c39,
+ 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, 0x3bd5a349, 0xb9853498,
+ 0x84e51d28, 0xc34567f8, 0xfe254e48, 0x4c059258, 0x7165bbe8, 0x36c5c138,
+ 0x0ba5e888, 0x28d4c7df, 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f,
+ 0xe03448af, 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e,
+ 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, 0x4834505d,
+ 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, 0x80d4df2d, 0xc774a5fd,
+ 0xfa148c4d, 0x78441b9c, 0x4524322c, 0x028448fc, 0x3fe4614c, 0x8dc4bd5c,
+ 0xb0a494ec, 0xf704ee3c, 0xca64c78c},
+
+ {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, 0x50cd91b3, 0xd659e31d,
+ 0x1d0530b8, 0xec53826d, 0x270f51c8, 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b,
+ 0xbc9e13de, 0x3a0a6170, 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390,
+ 0x85427035, 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6,
+ 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, 0x39dc63eb,
+ 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, 0x81387798, 0x9c3d4720,
+ 0x57619485, 0xd1f5e62b, 0x1aa9358e, 0xebff875b, 0x20a354fe, 0xa6372650,
+ 0x6d6bf5f5, 0x706ec54d, 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad,
+ 0xcf26d408, 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0,
+ 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, 0x73b8c7d6,
+ 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, 0xc404d9c9, 0x4290ab67,
+ 0x89cc78c2, 0x94c9487a, 0x5f959bdf, 0xd901e971, 0x125d3ad4, 0xe30b8801,
+ 0x28575ba4, 0xaec3290a, 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c,
+ 0xfe0eb8b9, 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1,
+ 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, 0xad152b91,
+ 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, 0xfdd8ba22, 0x08f40f5a,
+ 0xc3a8dcff, 0x453cae51, 0x8e607df4, 0x93654d4c, 0x58399ee9, 0xdeadec47,
+ 0x15f13fe2, 0xe4a78d37, 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21,
+ 0xb46a1c84, 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca,
+ 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, 0xe7718fac,
+ 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, 0xb7bc1e1f, 0x31286cb1,
+ 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, 0x5378b5d3, 0x98246676, 0x852156ce,
+ 0x4e7d856b, 0xc8e9f7c5, 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be,
+ 0x7477e41b, 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643,
+ 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, 0xcb3ff55e,
+ 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, 0x77a1e680, 0x6aa4d638,
+ 0xa1f8059d, 0x276c7733, 0xec30a496, 0x191c11ee, 0xd240c24b, 0x54d4b0e5,
+ 0x9f886340, 0x828d53f8, 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383,
+ 0x3e134026, 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e,
+ 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, 0x815b5163,
+ 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, 0x3dc542bd, 0xbb513013,
+ 0x700de3b6, 0x6d08d30e, 0xa65400ab, 0x20c07205, 0xeb9ca1a0, 0x11e81eb4,
+ 0xdab4cd11, 0x5c20bfbf, 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9,
+ 0x0ced2e0c, 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf,
+ 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, 0x5ff6bd24,
+ 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, 0x0f3b2c97, 0xfe6d9e42,
+ 0x35314de7, 0xb3a53f49, 0x78f9ecec, 0x65fcdc54, 0xaea00ff1, 0x28347d5f,
+ 0xe368aefa, 0x16441b82, 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994,
+ 0x46898a31, 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4,
+ 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, 0x15921919,
+ 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, 0x455f88aa, 0xc3cbfa04,
+ 0x089729a1, 0xf9c19b74, 0x329d48d1, 0xb4093a7f, 0x7f55e9da, 0x6250d962,
+ 0xa90c0ac7, 0x2f987869, 0xe4c4abcc},
+
+ {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, 0x52382fa7, 0x63d0353a,
+ 0xc5a73e8e, 0x33ef4e67, 0x959845d3, 0xa4705f4e, 0x020754fa, 0xc7a06a74,
+ 0x61d761c0, 0x503f7b5d, 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7,
+ 0x56368653, 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9,
+ 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, 0x37e1e793,
+ 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, 0xfe552301, 0x3bf21d8f,
+ 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2,
+ 0xcdba6d66, 0x081d53e8, 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552,
+ 0x0e14aee6, 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068,
+ 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, 0x6fc3cf26,
+ 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, 0xe27c7ecd, 0xd3946450,
+ 0x75e36fe4, 0xb044516a, 0x16335ade, 0x27db4043, 0x81ac4bf7, 0x77e43b1e,
+ 0xd19330aa, 0xe07b2a37, 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24,
+ 0xb2430590, 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4,
+ 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, 0x87a5b6f9,
+ 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, 0xd59d995e, 0x8bb64ce5,
+ 0x2dc14751, 0x1c295dcc, 0xba5e5678, 0x7ff968f6, 0xd98e6342, 0xe86679df,
+ 0x4e11726b, 0xb8590282, 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691,
+ 0xea612d25, 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102,
+ 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, 0xdf879e4c,
+ 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, 0x8dbfb1eb, 0xbc57ab76,
+ 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1,
+ 0xda2ec555, 0xebc6dfc8, 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc,
+ 0x8a11be08, 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c,
+ 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, 0x8c184306,
+ 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, 0xedcf22c6, 0x28681c48,
+ 0x8e1f17fc, 0xbff70d61, 0x198006d5, 0x47abd36e, 0xe1dcd8da, 0xd034c247,
+ 0x7643c9f3, 0xb3e4f77d, 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09,
+ 0xd23396bd, 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833,
+ 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, 0xd43a6bb3,
+ 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, 0xb5ed0a73, 0x840510ee,
+ 0x22721b5a, 0xe7d525d4, 0x41a22e60, 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b,
+ 0x6a6a943f, 0x5b828ea2, 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1,
+ 0x09baa105, 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff,
+ 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, 0x3c5c126c,
+ 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, 0x6e643dcb, 0x982c4d22,
+ 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, 0x6c636931, 0xca146285, 0xfbfc7818,
+ 0x5d8b73ac, 0x03a0a617, 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204,
+ 0x519889b0, 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959,
+ 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, 0x647e3ad9,
+ 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, 0x3646157e, 0x07ae0fe3,
+ 0xa1d90457, 0x579174be, 0xf1e67f0a, 0xc00e6597, 0x66796e23, 0xa3de50ad,
+ 0x05a95b19, 0x34414184, 0x92364a30},
+
+ {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, 0x48e00e64, 0xc66f0987,
+ 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, 0x91c01cc8, 0x5d6a1c56, 0x57af154f,
+ 0x9b0515d1, 0x158a1232, 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656,
+ 0xf23436c8, 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e,
+ 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, 0x69312319,
+ 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, 0x77f965b5, 0x7d3c6cac,
+ 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, 0x2a9379e3, 0xe639797d, 0x68b67e9e,
+ 0xa41c7e00, 0xaed97719, 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d,
+ 0x496753e3, 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa,
+ 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, 0xd2624632,
+ 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, 0xe537c273, 0x6bb8c590,
+ 0xa712c50e, 0xadd7cc17, 0x617dcc89, 0xeff2cb6a, 0x2358cbf4, 0xfa78d958,
+ 0x36d2d9c6, 0xb85dde25, 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df,
+ 0xf0bdd041, 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c,
+ 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, 0xc4e6ef0e,
+ 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, 0x8c06e16a, 0xd0eba0bb,
+ 0x1c41a025, 0x92cea7c6, 0x5e64a758, 0x54a1ae41, 0x980baedf, 0x1684a93c,
+ 0xda2ea9a2, 0x030ebb0e, 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4,
+ 0x4beeb56a, 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed,
+ 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, 0x7fb58a25,
+ 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, 0x37558441, 0xb9da83a2,
+ 0x7570833c, 0x533b85da, 0x9f918544, 0x111e82a7, 0xddb48239, 0xd7718b20,
+ 0x1bdb8bbe, 0x95548c5d, 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912,
+ 0x0e51998c, 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1,
+ 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, 0xe9efbd76,
+ 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, 0x72eaa8a7, 0x782fa1be,
+ 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, 0xaa4de78c, 0x66e7e712, 0xe868e0f1,
+ 0x24c2e06f, 0x2e07e976, 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39,
+ 0xb502fca7, 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be,
+ 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, 0x52bcd85d,
+ 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, 0xc9b9cd8c, 0x4736ca6f,
+ 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, 0xc37cc495, 0x0fd6c40b, 0x7aa64737,
+ 0xb60c47a9, 0x3883404a, 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0,
+ 0x70634e2e, 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278,
+ 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, 0x44387161,
+ 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, 0x0cd87f05, 0xd5f86da9,
+ 0x19526d37, 0x97dd6ad4, 0x5b776a4a, 0x51b26353, 0x9d1863cd, 0x1397642e,
+ 0xdf3d64b0, 0x83d02561, 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b,
+ 0xcb302b05, 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9,
+ 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, 0xff6b144a,
+ 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, 0xb78b1a2e, 0x39041dcd,
+ 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, 0x6eab0882, 0xa201081c, 0xa8c40105,
+ 0x646e019b, 0xeae10678, 0x264b06e6}}
+
+type dm_build_725 interface {
+ dm_build_726()
+ dm_build_727() error
+ dm_build_728()
+ dm_build_729(imsg dm_build_725) error
+ dm_build_730() error
+ dm_build_731() (interface{}, error)
+ dm_build_732()
+ dm_build_733(imsg dm_build_725) (interface{}, error)
+ dm_build_734()
+ dm_build_735() error
+ dm_build_736() byte
+ dm_build_737(buffer *Dm_build_0, startOff int32, endOff int32) uint32
+ dm_build_738() int32
+ dm_build_739(length int32)
+ dm_build_740() int16
+}
+
+type dm_build_741 struct {
+ dm_build_742 *dm_build_332
+
+ dm_build_743 int16
+
+ dm_build_744 int32
+
+ dm_build_745 *DmStatement
+}
+
+func (dm_build_747 *dm_build_741) dm_build_746(dm_build_748 *dm_build_332, dm_build_749 int16) *dm_build_741 {
+ dm_build_747.dm_build_742 = dm_build_748
+ dm_build_747.dm_build_743 = dm_build_749
+ return dm_build_747
+}
+
+func (dm_build_751 *dm_build_741) dm_build_750(dm_build_752 *dm_build_332, dm_build_753 int16, dm_build_754 *DmStatement) *dm_build_741 {
+ dm_build_751.dm_build_746(dm_build_752, dm_build_753).dm_build_745 = dm_build_754
+ return dm_build_751
+}
+
+func dm_build_755(dm_build_756 *dm_build_332, dm_build_757 int16) *dm_build_741 {
+ return new(dm_build_741).dm_build_746(dm_build_756, dm_build_757)
+}
+
+func dm_build_758(dm_build_759 *dm_build_332, dm_build_760 int16, dm_build_761 *DmStatement) *dm_build_741 {
+ return new(dm_build_741).dm_build_750(dm_build_759, dm_build_760, dm_build_761)
+}
+
+func (dm_build_763 *dm_build_741) dm_build_726() {
+ dm_build_763.dm_build_742.dm_build_335.Dm_build_14(0)
+ dm_build_763.dm_build_742.dm_build_335.Dm_build_25(Dm_build_633, true, true)
+}
+
+func (dm_build_765 *dm_build_741) dm_build_727() error {
+ return nil
+}
+
+func (dm_build_767 *dm_build_741) dm_build_728() {
+ if dm_build_767.dm_build_745 == nil {
+ dm_build_767.dm_build_742.dm_build_335.Dm_build_191(Dm_build_635, 0)
+ } else {
+ dm_build_767.dm_build_742.dm_build_335.Dm_build_191(Dm_build_635, dm_build_767.dm_build_745.id)
+ }
+
+ dm_build_767.dm_build_742.dm_build_335.Dm_build_187(Dm_build_636, dm_build_767.dm_build_743)
+ dm_build_767.dm_build_742.dm_build_335.Dm_build_191(Dm_build_637, int32(dm_build_767.dm_build_742.dm_build_335.Dm_build_12()-Dm_build_633))
+}
+
+func (dm_build_769 *dm_build_741) dm_build_730() error {
+ dm_build_769.dm_build_742.dm_build_335.Dm_build_17(0)
+ dm_build_769.dm_build_742.dm_build_335.Dm_build_25(Dm_build_633, false, true)
+ return dm_build_769.dm_build_774()
+}
+
+func (dm_build_771 *dm_build_741) dm_build_731() (interface{}, error) {
+ return nil, nil
+}
+
+func (dm_build_773 *dm_build_741) dm_build_732() {
+}
+
+func (dm_build_775 *dm_build_741) dm_build_774() error {
+ dm_build_775.dm_build_744 = dm_build_775.dm_build_742.dm_build_335.Dm_build_269(Dm_build_638)
+ if dm_build_775.dm_build_744 < 0 && dm_build_775.dm_build_744 != EC_RN_EXCEED_ROWSET_SIZE.ErrCode {
+ return (&DmError{dm_build_775.dm_build_744, dm_build_775.dm_build_776(), nil, ""}).throw()
+ } else if dm_build_775.dm_build_744 > 0 {
+
+ } else if dm_build_775.dm_build_743 == Dm_build_632 || dm_build_775.dm_build_743 == Dm_build_606 {
+ dm_build_775.dm_build_776()
+ }
+
+ return nil
+}
+
+func (dm_build_777 *dm_build_741) dm_build_776() string {
+
+ dm_build_778 := dm_build_777.dm_build_742.dm_build_336.getServerEncoding()
+
+ if dm_build_778 != "" && dm_build_778 == ENCODING_EUCKR && Locale != LANGUAGE_EN {
+ dm_build_778 = ENCODING_GB18030
+ }
+
+ dm_build_777.dm_build_742.dm_build_335.Dm_build_25(int(dm_build_777.dm_build_742.dm_build_335.Dm_build_125()), false, true)
+
+ dm_build_777.dm_build_742.dm_build_335.Dm_build_25(int(dm_build_777.dm_build_742.dm_build_335.Dm_build_125()), false, true)
+
+ dm_build_777.dm_build_742.dm_build_335.Dm_build_25(int(dm_build_777.dm_build_742.dm_build_335.Dm_build_125()), false, true)
+
+ return dm_build_777.dm_build_742.dm_build_335.Dm_build_167(dm_build_778, dm_build_777.dm_build_742.dm_build_336)
+}
+
+func (dm_build_780 *dm_build_741) dm_build_729(dm_build_781 dm_build_725) (dm_build_782 error) {
+ dm_build_781.dm_build_726()
+ if dm_build_782 = dm_build_781.dm_build_727(); dm_build_782 != nil {
+ return dm_build_782
+ }
+ dm_build_781.dm_build_728()
+ return nil
+}
+
+func (dm_build_784 *dm_build_741) dm_build_733(dm_build_785 dm_build_725) (dm_build_786 interface{}, dm_build_787 error) {
+ dm_build_787 = dm_build_785.dm_build_730()
+ if dm_build_787 != nil {
+ return nil, dm_build_787
+ }
+ dm_build_786, dm_build_787 = dm_build_785.dm_build_731()
+ if dm_build_787 != nil {
+ return nil, dm_build_787
+ }
+ dm_build_785.dm_build_732()
+ return dm_build_786, nil
+}
+
+func (dm_build_789 *dm_build_741) dm_build_734() {
+ if dm_build_789.dm_build_742.dm_build_341 {
+
+ var orgLen = dm_build_789.dm_build_738()
+
+ dm_build_789.dm_build_739(orgLen + Dm_build_723)
+ var crc = dm_build_789.dm_build_737(dm_build_789.dm_build_742.dm_build_335, 0, Dm_build_633+orgLen)
+ dm_build_789.dm_build_742.dm_build_335.Dm_build_63(crc)
+ } else {
+ dm_build_789.dm_build_742.dm_build_335.Dm_build_183(Dm_build_641, dm_build_789.dm_build_736())
+ }
+}
+
+func (dm_build_791 *dm_build_741) dm_build_735() error {
+ if dm_build_791.dm_build_742.dm_build_341 {
+
+ var bodyLen = dm_build_791.dm_build_738() - Dm_build_723
+ var msgLen = Dm_build_633 + bodyLen
+ var recv = dm_build_791.dm_build_742.dm_build_335.Dm_build_287(int(msgLen))
+ var calc = dm_build_791.dm_build_737(dm_build_791.dm_build_742.dm_build_335, 0, msgLen)
+ if recv != calc {
+ return ECGO_MSG_CHECK_ERROR.throw()
+ }
+
+ dm_build_791.dm_build_739(bodyLen)
+ dm_build_791.dm_build_742.dm_build_335.Dm_build_14(int(msgLen))
+ return nil
+ } else {
+ var recv = dm_build_791.dm_build_742.dm_build_335.Dm_build_263(Dm_build_641)
+ var calc = dm_build_791.dm_build_736()
+ if recv != calc {
+ return ECGO_MSG_CHECK_ERROR.throw()
+ }
+ return nil
+ }
+}
+
+func (dm_build_793 *dm_build_741) dm_build_736() byte {
+ dm_build_794 := dm_build_793.dm_build_742.dm_build_335.Dm_build_263(0)
+
+ for i := 1; i < Dm_build_641; i++ {
+ dm_build_794 ^= dm_build_793.dm_build_742.dm_build_335.Dm_build_263(i)
+ }
+
+ return dm_build_794
+}
+
+func (dm_build_796 *dm_build_741) dm_build_737(dm_build_797 *Dm_build_0, dm_build_798 int32, dm_build_799 int32) uint32 {
+
+ var dm_build_800 uint32 = 0xFFFFFFFF
+ var dm_build_801 = dm_build_798
+ var dm_build_802 = dm_build_799 - dm_build_798
+ var dm_build_803, dm_build_804 uint32
+
+ for dm_build_802 >= 8 {
+ dm_build_803 = dm_build_797.Dm_build_287(int(dm_build_801)) ^ dm_build_800
+ dm_build_801 += ULINT_SIZE
+
+ dm_build_804 = dm_build_797.Dm_build_287(int(dm_build_801))
+ dm_build_801 += ULINT_SIZE
+
+ dm_build_800 = Dm_build_724[7][dm_build_803&0xFF] ^ Dm_build_724[6][(dm_build_803>>8)&0xFF] ^
+ Dm_build_724[5][(dm_build_803>>16)&0xFF] ^ Dm_build_724[4][(dm_build_803>>24)&0xFF] ^
+ Dm_build_724[3][dm_build_804&0xFF] ^ Dm_build_724[2][(dm_build_804>>8)&0xFF] ^
+ Dm_build_724[1][(dm_build_804>>16)&0xFF] ^ Dm_build_724[0][(dm_build_804>>24)&0xFF]
+ dm_build_802 -= 8
+ }
+
+ for dm_build_802 > 0 {
+ dm_build_800 = ((dm_build_800 >> 8) & 0x00FFFFFF) ^ Dm_build_724[0][(dm_build_800&0xFF)^uint32(dm_build_797.Dm_build_281(int(dm_build_801)))]
+ dm_build_801++
+ dm_build_802--
+ }
+ return ^dm_build_800
+}
+
+func (dm_build_806 *dm_build_741) dm_build_738() int32 {
+ return dm_build_806.dm_build_742.dm_build_335.Dm_build_269(Dm_build_637)
+}
+
+func (dm_build_808 *dm_build_741) dm_build_739(dm_build_809 int32) {
+ dm_build_808.dm_build_742.dm_build_335.Dm_build_191(Dm_build_637, dm_build_809)
+}
+
+func (dm_build_811 *dm_build_741) dm_build_740() int16 {
+ return dm_build_811.dm_build_743
+}
+
+type dm_build_812 struct {
+ dm_build_741
+}
+
+func dm_build_813(dm_build_814 *dm_build_332) *dm_build_812 {
+ dm_build_815 := new(dm_build_812)
+ dm_build_815.dm_build_746(dm_build_814, Dm_build_613)
+ return dm_build_815
+}
+
+type dm_build_816 struct {
+ dm_build_741
+ dm_build_817 string
+}
+
+func dm_build_818(dm_build_819 *dm_build_332, dm_build_820 *DmStatement, dm_build_821 string) *dm_build_816 {
+ dm_build_822 := new(dm_build_816)
+ dm_build_822.dm_build_750(dm_build_819, Dm_build_621, dm_build_820)
+ dm_build_822.dm_build_817 = dm_build_821
+ dm_build_822.dm_build_745.cursorName = dm_build_821
+ return dm_build_822
+}
+
+func (dm_build_824 *dm_build_816) dm_build_727() error {
+ dm_build_824.dm_build_742.dm_build_335.Dm_build_113(dm_build_824.dm_build_817, dm_build_824.dm_build_742.dm_build_336.getServerEncoding(), dm_build_824.dm_build_742.dm_build_336)
+ dm_build_824.dm_build_742.dm_build_335.Dm_build_51(1)
+ return nil
+}
+
+type Dm_build_825 struct {
+ dm_build_841
+ dm_build_826 []OptParameter
+}
+
+func dm_build_827(dm_build_828 *dm_build_332, dm_build_829 *DmStatement, dm_build_830 []OptParameter) *Dm_build_825 {
+ dm_build_831 := new(Dm_build_825)
+ dm_build_831.dm_build_750(dm_build_828, Dm_build_631, dm_build_829)
+ dm_build_831.dm_build_826 = dm_build_830
+ return dm_build_831
+}
+
+func (dm_build_833 *Dm_build_825) dm_build_727() error {
+ dm_build_834 := len(dm_build_833.dm_build_826)
+
+ dm_build_833.dm_build_855(int32(dm_build_834), 1)
+
+ dm_build_833.dm_build_742.dm_build_335.Dm_build_113(dm_build_833.dm_build_745.nativeSql, dm_build_833.dm_build_745.dmConn.getServerEncoding(), dm_build_833.dm_build_745.dmConn)
+
+ for _, param := range dm_build_833.dm_build_826 {
+ dm_build_833.dm_build_742.dm_build_335.Dm_build_43(param.ioType)
+ dm_build_833.dm_build_742.dm_build_335.Dm_build_51(int32(param.tp))
+ dm_build_833.dm_build_742.dm_build_335.Dm_build_51(int32(param.prec))
+ dm_build_833.dm_build_742.dm_build_335.Dm_build_51(int32(param.scale))
+ }
+
+ for _, param := range dm_build_833.dm_build_826 {
+ if param.bytes == nil {
+ dm_build_833.dm_build_742.dm_build_335.Dm_build_59(Dm_build_650)
+ } else {
+ dm_build_833.dm_build_742.dm_build_335.Dm_build_89(param.bytes[:len(param.bytes)])
+ }
+ }
+ return nil
+}
+
+func (dm_build_836 *Dm_build_825) dm_build_731() (interface{}, error) {
+ return dm_build_836.dm_build_841.dm_build_731()
+}
+
+const (
+ Dm_build_837 int = 0x01
+
+ Dm_build_838 int = 0x02
+
+ Dm_build_839 int = 0x04
+
+ Dm_build_840 int = 0x08
+)
+
+type dm_build_841 struct {
+ dm_build_741
+ dm_build_842 [][]interface{}
+ dm_build_843 []parameter
+ dm_build_844 bool
+}
+
+func dm_build_845(dm_build_846 *dm_build_332, dm_build_847 int16, dm_build_848 *DmStatement) *dm_build_841 {
+ dm_build_849 := new(dm_build_841)
+ dm_build_849.dm_build_750(dm_build_846, dm_build_847, dm_build_848)
+ dm_build_849.dm_build_844 = true
+ return dm_build_849
+}
+
+func dm_build_850(dm_build_851 *dm_build_332, dm_build_852 *DmStatement, dm_build_853 [][]interface{}) *dm_build_841 {
+ dm_build_854 := new(dm_build_841)
+
+ if dm_build_851.dm_build_336.Execute2 {
+ dm_build_854.dm_build_750(dm_build_851, Dm_build_615, dm_build_852)
+ } else {
+ dm_build_854.dm_build_750(dm_build_851, Dm_build_611, dm_build_852)
+ }
+
+ dm_build_854.dm_build_843 = dm_build_852.params
+ dm_build_854.dm_build_842 = dm_build_853
+ dm_build_854.dm_build_844 = true
+ return dm_build_854
+}
+
+func (dm_build_856 *dm_build_841) dm_build_855(dm_build_857 int32, dm_build_858 int64) {
+
+ dm_build_859 := Dm_build_634
+
+ if dm_build_856.dm_build_742.dm_build_336.autoCommit {
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_183(dm_build_859, 1)
+ } else {
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_183(dm_build_859, 0)
+ }
+
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_211(dm_build_859, uint16(dm_build_857))
+
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_183(dm_build_859, 1)
+
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_195(dm_build_859, dm_build_858)
+
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_195(dm_build_859, dm_build_856.dm_build_745.cursorUpdateRow)
+
+ if dm_build_856.dm_build_745.maxRows <= 0 || dm_build_856.dm_build_745.dmConn.dmConnector.enRsCache {
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_195(dm_build_859, INT64_MAX)
+ } else {
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_195(dm_build_859, dm_build_856.dm_build_745.maxRows)
+ }
+
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_183(dm_build_859, 1)
+
+ if dm_build_856.dm_build_742.dm_build_336.dmConnector.continueBatchOnError {
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_183(dm_build_859, 1)
+ } else {
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_183(dm_build_859, 0)
+ }
+
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_183(dm_build_859, 0)
+
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_183(dm_build_859, 0)
+
+ if dm_build_856.dm_build_745.queryTimeout == 0 {
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_191(dm_build_859, -1)
+ } else {
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_191(dm_build_859, dm_build_856.dm_build_745.queryTimeout)
+ }
+
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_191(dm_build_859, dm_build_856.dm_build_742.dm_build_336.dmConnector.batchAllowMaxErrors)
+
+ if dm_build_856.dm_build_745.innerExec {
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_183(dm_build_859, 1)
+ } else {
+ dm_build_859 += dm_build_856.dm_build_742.dm_build_335.Dm_build_183(dm_build_859, 0)
+ }
+}
+
+func (dm_build_861 *dm_build_841) dm_build_727() error {
+ var dm_build_862 int32
+ var dm_build_863 int64
+
+ if dm_build_861.dm_build_843 != nil {
+ dm_build_862 = int32(len(dm_build_861.dm_build_843))
+ } else {
+ dm_build_862 = 0
+ }
+
+ if dm_build_861.dm_build_842 != nil {
+ dm_build_863 = int64(len(dm_build_861.dm_build_842))
+ } else {
+ dm_build_863 = 0
+ }
+
+ dm_build_861.dm_build_855(dm_build_862, dm_build_863)
+
+ if dm_build_862 > 0 {
+ err := dm_build_861.dm_build_864(dm_build_861.dm_build_843)
+ if err != nil {
+ return err
+ }
+ if dm_build_861.dm_build_842 != nil && len(dm_build_861.dm_build_842) > 0 {
+ for _, paramObject := range dm_build_861.dm_build_842 {
+ if err := dm_build_861.dm_build_867(paramObject); err != nil {
+ return err
+ }
+ }
+ }
+ }
+
+ return nil
+}
+
+func (dm_build_865 *dm_build_841) dm_build_864(dm_build_866 []parameter) error {
+ for _, param := range dm_build_866 {
+
+ if param.colType == CURSOR && param.ioType == IO_TYPE_OUT {
+ dm_build_865.dm_build_742.dm_build_335.Dm_build_43(IO_TYPE_INOUT)
+ } else {
+ dm_build_865.dm_build_742.dm_build_335.Dm_build_43(param.ioType)
+ }
+
+ dm_build_865.dm_build_742.dm_build_335.Dm_build_51(param.colType)
+
+ lprec := param.prec
+ lscale := param.scale
+ typeDesc := param.typeDescriptor
+ switch param.colType {
+ case ARRAY, SARRAY:
+ tmp, err := getPackArraySize(typeDesc)
+ if err != nil {
+ return err
+ }
+ lprec = int32(tmp)
+ case PLTYPE_RECORD:
+ tmp, err := getPackRecordSize(typeDesc)
+ if err != nil {
+ return err
+ }
+ lprec = int32(tmp)
+ case CLASS:
+ tmp, err := getPackClassSize(typeDesc)
+ if err != nil {
+ return err
+ }
+ lprec = int32(tmp)
+ case BLOB:
+ if isComplexType(int(param.colType), int(param.scale)) {
+ lprec = int32(typeDesc.getObjId())
+ if lprec == 4 {
+ lprec = int32(typeDesc.getOuterId())
+ }
+ }
+ }
+
+ dm_build_865.dm_build_742.dm_build_335.Dm_build_51(lprec)
+
+ dm_build_865.dm_build_742.dm_build_335.Dm_build_51(lscale)
+
+ switch param.colType {
+ case ARRAY, SARRAY:
+ err := packArray(typeDesc, dm_build_865.dm_build_742.dm_build_335)
+ if err != nil {
+ return err
+ }
+
+ case PLTYPE_RECORD:
+ err := packRecord(typeDesc, dm_build_865.dm_build_742.dm_build_335)
+ if err != nil {
+ return err
+ }
+
+ case CLASS:
+ err := packClass(typeDesc, dm_build_865.dm_build_742.dm_build_335)
+ if err != nil {
+ return err
+ }
+
+ }
+ }
+
+ return nil
+}
+
+func (dm_build_868 *dm_build_841) dm_build_867(dm_build_869 []interface{}) error {
+ for i := 0; i < len(dm_build_868.dm_build_843); i++ {
+
+ if dm_build_868.dm_build_843[i].colType == CURSOR {
+ dm_build_868.dm_build_742.dm_build_335.Dm_build_47(ULINT_SIZE)
+ dm_build_868.dm_build_742.dm_build_335.Dm_build_51(dm_build_868.dm_build_843[i].cursorStmt.id)
+ continue
+ }
+
+ if dm_build_868.dm_build_843[i].ioType == IO_TYPE_OUT {
+ continue
+ }
+
+ switch dm_build_869[i].(type) {
+ case []byte:
+ if dataBytes, ok := dm_build_869[i].([]byte); ok {
+ if len(dataBytes) > Dm_build_644 {
+ return ECGO_DATA_TOO_LONG.throw()
+ }
+ dm_build_868.dm_build_742.dm_build_335.Dm_build_89(dataBytes)
+ }
+ case int:
+ if dm_build_869[i] == ParamDataEnum_Null {
+ dm_build_868.dm_build_742.dm_build_335.Dm_build_59(Dm_build_650)
+ } else if dm_build_869[i] == ParamDataEnum_OFF_ROW {
+ dm_build_868.dm_build_742.dm_build_335.Dm_build_47(0)
+ }
+ case lobCtl:
+ dm_build_868.dm_build_742.dm_build_335.Dm_build_59(uint16(Dm_build_649))
+ dm_build_868.dm_build_742.dm_build_335.Dm_build_79(dm_build_869[i].(lobCtl).value)
+ default:
+ panic("Bind param data failed by invalid param data type: ")
+ }
+ }
+
+ return nil
+}
+
+func (dm_build_871 *dm_build_841) dm_build_731() (interface{}, error) {
+ dm_build_872 := execRetInfo{}
+ dm_build_873 := dm_build_871.dm_build_745.dmConn
+
+ dm_build_874 := Dm_build_634
+
+ dm_build_872.retSqlType = dm_build_871.dm_build_742.dm_build_335.Dm_build_266(dm_build_874)
+ dm_build_874 += USINT_SIZE
+
+ dm_build_875 := dm_build_871.dm_build_742.dm_build_335.Dm_build_266(dm_build_874)
+ dm_build_874 += USINT_SIZE
+
+ dm_build_872.updateCount = dm_build_871.dm_build_742.dm_build_335.Dm_build_272(dm_build_874)
+ dm_build_874 += DDWORD_SIZE
+
+ dm_build_876 := dm_build_871.dm_build_742.dm_build_335.Dm_build_284(dm_build_874)
+ dm_build_874 += USINT_SIZE
+
+ dm_build_872.rsUpdatable = dm_build_871.dm_build_742.dm_build_335.Dm_build_263(dm_build_874) != 0
+ dm_build_874 += BYTE_SIZE
+
+ dm_build_877 := dm_build_871.dm_build_742.dm_build_335.Dm_build_266(dm_build_874)
+ dm_build_874 += ULINT_SIZE
+
+ dm_build_872.printLen = dm_build_871.dm_build_742.dm_build_335.Dm_build_269(dm_build_874)
+ dm_build_874 += ULINT_SIZE
+
+ var dm_build_878 int16 = -1
+ if dm_build_872.retSqlType == Dm_build_700 || dm_build_872.retSqlType == Dm_build_701 {
+ dm_build_872.rowid = 0
+
+ dm_build_872.rsBdta = dm_build_871.dm_build_742.dm_build_335.Dm_build_263(dm_build_874) == Dm_build_713
+ dm_build_874 += BYTE_SIZE
+
+ dm_build_878 = dm_build_871.dm_build_742.dm_build_335.Dm_build_266(dm_build_874)
+ dm_build_874 += USINT_SIZE
+ dm_build_874 += 5
+ } else {
+ dm_build_872.rowid = dm_build_871.dm_build_742.dm_build_335.Dm_build_272(dm_build_874)
+ dm_build_874 += DDWORD_SIZE
+ }
+
+ dm_build_872.execId = dm_build_871.dm_build_742.dm_build_335.Dm_build_269(dm_build_874)
+ dm_build_874 += ULINT_SIZE
+
+ dm_build_872.rsCacheOffset = dm_build_871.dm_build_742.dm_build_335.Dm_build_269(dm_build_874)
+ dm_build_874 += ULINT_SIZE
+
+ dm_build_879 := dm_build_871.dm_build_742.dm_build_335.Dm_build_263(dm_build_874)
+ dm_build_874 += BYTE_SIZE
+ dm_build_880 := (dm_build_879 & 0x01) == 0x01
+ dm_build_881 := (dm_build_879 & 0x02) == 0x02
+
+ dm_build_873.TrxStatus = dm_build_871.dm_build_742.dm_build_335.Dm_build_269(dm_build_874)
+ dm_build_873.setTrxFinish(dm_build_873.TrxStatus)
+ dm_build_874 += ULINT_SIZE
+
+ if dm_build_872.printLen > 0 {
+ bytes := dm_build_871.dm_build_742.dm_build_335.Dm_build_146(int(dm_build_872.printLen))
+ dm_build_872.printMsg = Dm_build_1220.Dm_build_1377(bytes, 0, len(bytes), dm_build_873.getServerEncoding(), dm_build_873)
+ }
+
+ if dm_build_876 > 0 {
+ dm_build_872.outParamDatas = dm_build_871.dm_build_882(int(dm_build_876))
+ }
+
+ switch dm_build_872.retSqlType {
+ case Dm_build_702:
+ dm_build_873.dmConnector.localTimezone = dm_build_871.dm_build_742.dm_build_335.Dm_build_122()
+ case Dm_build_700:
+ dm_build_872.hasResultSet = true
+ if dm_build_875 > 0 {
+ dm_build_871.dm_build_745.columns = dm_build_871.dm_build_891(int(dm_build_875), dm_build_872.rsBdta)
+ }
+ dm_build_871.dm_build_901(&dm_build_872, len(dm_build_871.dm_build_745.columns), int(dm_build_877), int(dm_build_878))
+ case Dm_build_701:
+ if dm_build_875 > 0 || dm_build_877 > 0 {
+ dm_build_872.hasResultSet = true
+ }
+ if dm_build_875 > 0 {
+ dm_build_871.dm_build_745.columns = dm_build_871.dm_build_891(int(dm_build_875), dm_build_872.rsBdta)
+ }
+ dm_build_871.dm_build_901(&dm_build_872, len(dm_build_871.dm_build_745.columns), int(dm_build_877), int(dm_build_878))
+ case Dm_build_703:
+ dm_build_873.IsoLevel = int32(dm_build_871.dm_build_742.dm_build_335.Dm_build_122())
+ dm_build_873.ReadOnly = dm_build_871.dm_build_742.dm_build_335.Dm_build_119() == 1
+ case Dm_build_696:
+ dm_build_873.Schema = dm_build_871.dm_build_742.dm_build_335.Dm_build_167(dm_build_873.getServerEncoding(), dm_build_873)
+ case Dm_build_693:
+ dm_build_872.explain = dm_build_871.dm_build_742.dm_build_335.Dm_build_167(dm_build_873.getServerEncoding(), dm_build_873)
+
+ case Dm_build_697, Dm_build_699, Dm_build_698:
+ if dm_build_880 {
+
+ counts := dm_build_871.dm_build_742.dm_build_335.Dm_build_125()
+ rowCounts := make([]int64, counts)
+ for i := 0; i < int(counts); i++ {
+ rowCounts[i] = dm_build_871.dm_build_742.dm_build_335.Dm_build_128()
+ }
+ dm_build_872.updateCounts = rowCounts
+ }
+
+ if dm_build_881 {
+ rows := dm_build_871.dm_build_742.dm_build_335.Dm_build_125()
+
+ var lastInsertId int64
+ for i := 0; i < int(rows); i++ {
+ lastInsertId = dm_build_871.dm_build_742.dm_build_335.Dm_build_128()
+ }
+ dm_build_872.lastInsertId = lastInsertId
+
+ } else if dm_build_872.updateCount == 1 {
+ dm_build_872.lastInsertId = dm_build_872.rowid
+ }
+
+ if dm_build_871.dm_build_744 == EC_BP_WITH_ERROR.ErrCode {
+ dm_build_871.dm_build_907(dm_build_872.updateCounts)
+ }
+ case Dm_build_706:
+ len := dm_build_871.dm_build_742.dm_build_335.Dm_build_137()
+ dm_build_873.FormatDate = dm_build_871.dm_build_742.dm_build_335.Dm_build_162(int(len), dm_build_873.getServerEncoding(), dm_build_873)
+ case Dm_build_708:
+
+ len := dm_build_871.dm_build_742.dm_build_335.Dm_build_137()
+ dm_build_873.FormatTimestamp = dm_build_871.dm_build_742.dm_build_335.Dm_build_162(int(len), dm_build_873.getServerEncoding(), dm_build_873)
+ case Dm_build_709:
+
+ len := dm_build_871.dm_build_742.dm_build_335.Dm_build_137()
+ dm_build_873.FormatTimestampTZ = dm_build_871.dm_build_742.dm_build_335.Dm_build_162(int(len), dm_build_873.getServerEncoding(), dm_build_873)
+ case Dm_build_707:
+ len := dm_build_871.dm_build_742.dm_build_335.Dm_build_137()
+ dm_build_873.FormatTime = dm_build_871.dm_build_742.dm_build_335.Dm_build_162(int(len), dm_build_873.getServerEncoding(), dm_build_873)
+ case Dm_build_710:
+ len := dm_build_871.dm_build_742.dm_build_335.Dm_build_137()
+ dm_build_873.FormatTimeTZ = dm_build_871.dm_build_742.dm_build_335.Dm_build_162(int(len), dm_build_873.getServerEncoding(), dm_build_873)
+ case Dm_build_711:
+ dm_build_873.OracleDateLanguage = dm_build_871.dm_build_742.dm_build_335.Dm_build_137()
+ }
+
+ return &dm_build_872, nil
+}
+
+func (dm_build_883 *dm_build_841) dm_build_882(dm_build_884 int) [][]byte {
+ dm_build_885 := make([]int, dm_build_884)
+
+ dm_build_886 := 0
+ for i := 0; i < len(dm_build_883.dm_build_843); i++ {
+ if dm_build_883.dm_build_843[i].ioType == IO_TYPE_INOUT || dm_build_883.dm_build_843[i].ioType == IO_TYPE_OUT {
+ dm_build_885[dm_build_886] = i
+ dm_build_886++
+ }
+ }
+
+ dm_build_887 := make([][]byte, len(dm_build_883.dm_build_843))
+ var dm_build_888 int32
+ var dm_build_889 bool
+ var dm_build_890 []byte = nil
+ for i := 0; i < dm_build_884; i++ {
+ dm_build_889 = false
+ dm_build_888 = int32(dm_build_883.dm_build_742.dm_build_335.Dm_build_140())
+
+ if dm_build_888 == int32(Dm_build_650) {
+ dm_build_888 = 0
+ dm_build_889 = true
+ } else if dm_build_888 == int32(Dm_build_651) {
+ dm_build_888 = dm_build_883.dm_build_742.dm_build_335.Dm_build_125()
+ }
+
+ if dm_build_889 {
+ dm_build_887[dm_build_885[i]] = nil
+ } else {
+ dm_build_890 = dm_build_883.dm_build_742.dm_build_335.Dm_build_146(int(dm_build_888))
+ dm_build_887[dm_build_885[i]] = dm_build_890
+ }
+ }
+
+ return dm_build_887
+}
+
+func (dm_build_892 *dm_build_841) dm_build_891(dm_build_893 int, dm_build_894 bool) []column {
+ dm_build_895 := dm_build_892.dm_build_742.dm_build_336.getServerEncoding()
+ var dm_build_896, dm_build_897, dm_build_898, dm_build_899 int16
+ dm_build_900 := make([]column, dm_build_893)
+ for i := 0; i < dm_build_893; i++ {
+ dm_build_900[i].InitColumn()
+
+ dm_build_900[i].colType = dm_build_892.dm_build_742.dm_build_335.Dm_build_125()
+
+ dm_build_900[i].prec = dm_build_892.dm_build_742.dm_build_335.Dm_build_125()
+
+ dm_build_900[i].scale = dm_build_892.dm_build_742.dm_build_335.Dm_build_125()
+
+ dm_build_900[i].nullable = dm_build_892.dm_build_742.dm_build_335.Dm_build_125() != 0
+
+ itemFlag := dm_build_892.dm_build_742.dm_build_335.Dm_build_122()
+ dm_build_900[i].lob = int(itemFlag)&Dm_build_838 != 0
+ dm_build_900[i].identity = int(itemFlag)&Dm_build_837 != 0
+ dm_build_900[i].readonly = int(itemFlag)&Dm_build_839 != 0
+
+ dm_build_892.dm_build_742.dm_build_335.Dm_build_25(4, false, true)
+
+ dm_build_892.dm_build_742.dm_build_335.Dm_build_25(2, false, true)
+
+ dm_build_896 = dm_build_892.dm_build_742.dm_build_335.Dm_build_122()
+
+ dm_build_897 = dm_build_892.dm_build_742.dm_build_335.Dm_build_122()
+
+ dm_build_898 = dm_build_892.dm_build_742.dm_build_335.Dm_build_122()
+
+ dm_build_899 = dm_build_892.dm_build_742.dm_build_335.Dm_build_122()
+ dm_build_900[i].name = dm_build_892.dm_build_742.dm_build_335.Dm_build_162(int(dm_build_896), dm_build_895, dm_build_892.dm_build_742.dm_build_336)
+ dm_build_900[i].typeName = dm_build_892.dm_build_742.dm_build_335.Dm_build_162(int(dm_build_897), dm_build_895, dm_build_892.dm_build_742.dm_build_336)
+ dm_build_900[i].tableName = dm_build_892.dm_build_742.dm_build_335.Dm_build_162(int(dm_build_898), dm_build_895, dm_build_892.dm_build_742.dm_build_336)
+ dm_build_900[i].schemaName = dm_build_892.dm_build_742.dm_build_335.Dm_build_162(int(dm_build_899), dm_build_895, dm_build_892.dm_build_742.dm_build_336)
+
+ if dm_build_892.dm_build_745.readBaseColName {
+ dm_build_900[i].baseName = dm_build_892.dm_build_742.dm_build_335.Dm_build_175(dm_build_895, dm_build_892.dm_build_742.dm_build_336)
+ }
+
+ if dm_build_900[i].lob {
+ dm_build_900[i].lobTabId = dm_build_892.dm_build_742.dm_build_335.Dm_build_125()
+ dm_build_900[i].lobColId = dm_build_892.dm_build_742.dm_build_335.Dm_build_122()
+ }
+
+ }
+
+ for i := 0; i < dm_build_893; i++ {
+
+ if isComplexType(int(dm_build_900[i].colType), int(dm_build_900[i].scale)) {
+ strDesc := newTypeDescriptor(dm_build_892.dm_build_742.dm_build_336)
+ strDesc.unpack(dm_build_892.dm_build_742.dm_build_335)
+ dm_build_900[i].typeDescriptor = strDesc
+ }
+ }
+
+ return dm_build_900
+}
+
+func (dm_build_902 *dm_build_841) dm_build_901(dm_build_903 *execRetInfo, dm_build_904 int, dm_build_905 int, dm_build_906 int) {
+ if dm_build_905 > 0 {
+ startOffset := dm_build_902.dm_build_742.dm_build_335.Dm_build_20()
+ if dm_build_903.rsBdta {
+ dm_build_903.rsDatas = dm_build_902.dm_build_920(dm_build_902.dm_build_745.columns, dm_build_906)
+ } else {
+ datas := make([][][]byte, dm_build_905)
+
+ for i := 0; i < dm_build_905; i++ {
+
+ datas[i] = make([][]byte, dm_build_904+1)
+
+ dm_build_902.dm_build_742.dm_build_335.Dm_build_25(2, false, true)
+
+ datas[i][0] = dm_build_902.dm_build_742.dm_build_335.Dm_build_146(LINT64_SIZE)
+
+ dm_build_902.dm_build_742.dm_build_335.Dm_build_25(2*dm_build_904, false, true)
+
+ for j := 1; j < dm_build_904+1; j++ {
+
+ colLen := dm_build_902.dm_build_742.dm_build_335.Dm_build_140()
+ if colLen == Dm_build_654 {
+ datas[i][j] = nil
+ } else if colLen != Dm_build_655 {
+ datas[i][j] = dm_build_902.dm_build_742.dm_build_335.Dm_build_146(int(colLen))
+ } else {
+ datas[i][j] = dm_build_902.dm_build_742.dm_build_335.Dm_build_150()
+ }
+ }
+ }
+
+ dm_build_903.rsDatas = datas
+ }
+ dm_build_903.rsSizeof = dm_build_902.dm_build_742.dm_build_335.Dm_build_20() - startOffset
+ }
+
+ if dm_build_903.rsCacheOffset > 0 {
+ tbCount := dm_build_902.dm_build_742.dm_build_335.Dm_build_122()
+
+ ids := make([]int32, tbCount)
+ tss := make([]int64, tbCount)
+
+ for i := 0; i < int(tbCount); i++ {
+ ids[i] = dm_build_902.dm_build_742.dm_build_335.Dm_build_125()
+ tss[i] = dm_build_902.dm_build_742.dm_build_335.Dm_build_128()
+ }
+
+ dm_build_903.tbIds = ids[:]
+ dm_build_903.tbTss = tss[:]
+ }
+}
+
+func (dm_build_908 *dm_build_841) dm_build_907(dm_build_909 []int64) error {
+
+ dm_build_908.dm_build_742.dm_build_335.Dm_build_25(4, false, true)
+
+ dm_build_910 := dm_build_908.dm_build_742.dm_build_335.Dm_build_125()
+
+ dm_build_911 := make([]string, 0, 8)
+ for i := 0; i < int(dm_build_910); i++ {
+ irow := dm_build_908.dm_build_742.dm_build_335.Dm_build_125()
+
+ dm_build_909[irow] = -3
+
+ code := dm_build_908.dm_build_742.dm_build_335.Dm_build_125()
+
+ errStr := dm_build_908.dm_build_742.dm_build_335.Dm_build_175(dm_build_908.dm_build_742.dm_build_336.getServerEncoding(), dm_build_908.dm_build_742.dm_build_336)
+
+ dm_build_911 = append(dm_build_911, "row["+strconv.Itoa(int(irow))+"]:"+strconv.Itoa(int(code))+", "+errStr)
+ }
+
+ if len(dm_build_911) > 0 {
+ builder := &strings.Builder{}
+ for _, str := range dm_build_911 {
+ builder.WriteString(util.LINE_SEPARATOR)
+ builder.WriteString(str)
+ }
+ EC_BP_WITH_ERROR.ErrText += builder.String()
+ return EC_BP_WITH_ERROR.throw()
+ }
+ return nil
+}
+
+const (
+ Dm_build_912 = 0
+
+ Dm_build_913 = Dm_build_912 + ULINT_SIZE
+
+ Dm_build_914 = Dm_build_913 + USINT_SIZE
+
+ Dm_build_915 = Dm_build_914 + ULINT_SIZE
+
+ Dm_build_916 = Dm_build_915 + ULINT_SIZE
+
+ Dm_build_917 = Dm_build_916 + BYTE_SIZE
+
+ Dm_build_918 = -2
+
+ Dm_build_919 = -3
+)
+
+func (dm_build_921 *dm_build_841) dm_build_920(dm_build_922 []column, dm_build_923 int) [][][]byte {
+
+ dm_build_924 := dm_build_921.dm_build_742.dm_build_335.Dm_build_143()
+
+ dm_build_925 := dm_build_921.dm_build_742.dm_build_335.Dm_build_140()
+
+ var dm_build_926 bool
+
+ if dm_build_923 >= 0 && int(dm_build_925) == len(dm_build_922)+1 {
+ dm_build_926 = true
+ } else {
+ dm_build_926 = false
+ }
+
+ dm_build_921.dm_build_742.dm_build_335.Dm_build_25(ULINT_SIZE, false, true)
+
+ dm_build_921.dm_build_742.dm_build_335.Dm_build_25(ULINT_SIZE, false, true)
+
+ dm_build_921.dm_build_742.dm_build_335.Dm_build_25(BYTE_SIZE, false, true)
+
+ dm_build_927 := make([]uint16, dm_build_925)
+ for icol := 0; icol < int(dm_build_925); icol++ {
+ dm_build_927[icol] = dm_build_921.dm_build_742.dm_build_335.Dm_build_140()
+ }
+
+ dm_build_928 := make([]uint32, dm_build_925)
+ dm_build_929 := make([][][]byte, dm_build_924)
+
+ for i := uint32(0); i < dm_build_924; i++ {
+ dm_build_929[i] = make([][]byte, len(dm_build_922)+1)
+ }
+
+ for icol := 0; icol < int(dm_build_925); icol++ {
+ dm_build_928[icol] = dm_build_921.dm_build_742.dm_build_335.Dm_build_143()
+ }
+
+ for icol := 0; icol < int(dm_build_925); icol++ {
+
+ dataCol := icol + 1
+ if dm_build_926 && icol == dm_build_923 {
+ dataCol = 0
+ } else if dm_build_926 && icol > dm_build_923 {
+ dataCol = icol
+ }
+
+ allNotNull := dm_build_921.dm_build_742.dm_build_335.Dm_build_125() == 1
+ var isNull []bool = nil
+ if !allNotNull {
+ isNull = make([]bool, dm_build_924)
+ for irow := uint32(0); irow < dm_build_924; irow++ {
+ isNull[irow] = dm_build_921.dm_build_742.dm_build_335.Dm_build_119() == 0
+ }
+ }
+
+ for irow := uint32(0); irow < dm_build_924; irow++ {
+ if allNotNull || !isNull[irow] {
+ dm_build_929[irow][dataCol] = dm_build_921.dm_build_930(int(dm_build_927[icol]))
+ }
+ }
+ }
+
+ if !dm_build_926 && dm_build_923 >= 0 {
+ for irow := uint32(0); irow < dm_build_924; irow++ {
+ dm_build_929[irow][0] = dm_build_929[irow][dm_build_923+1]
+ }
+ }
+
+ return dm_build_929
+}
+
+func (dm_build_931 *dm_build_841) dm_build_930(dm_build_932 int) []byte {
+
+ dm_build_933 := dm_build_931.dm_build_936(dm_build_932)
+
+ dm_build_934 := int32(0)
+ if dm_build_933 == Dm_build_918 {
+ dm_build_934 = dm_build_931.dm_build_742.dm_build_335.Dm_build_125()
+ dm_build_933 = int(dm_build_931.dm_build_742.dm_build_335.Dm_build_125())
+ } else if dm_build_933 == Dm_build_919 {
+ dm_build_933 = int(dm_build_931.dm_build_742.dm_build_335.Dm_build_125())
+ }
+
+ dm_build_935 := dm_build_931.dm_build_742.dm_build_335.Dm_build_146(dm_build_933 + int(dm_build_934))
+ if dm_build_934 == 0 {
+ return dm_build_935
+ }
+
+ for i := dm_build_933; i < len(dm_build_935); i++ {
+ dm_build_935[i] = ' '
+ }
+ return dm_build_935
+}
+
+func (dm_build_937 *dm_build_841) dm_build_936(dm_build_938 int) int {
+
+ dm_build_939 := 0
+ switch dm_build_938 {
+ case INT:
+ case BIT:
+ case TINYINT:
+ case SMALLINT:
+ case BOOLEAN:
+ case NULL:
+ dm_build_939 = 4
+
+ case BIGINT:
+
+ dm_build_939 = 8
+
+ case CHAR:
+ case VARCHAR2:
+ case VARCHAR:
+ case BINARY:
+ case VARBINARY:
+ case BLOB:
+ case CLOB:
+ dm_build_939 = Dm_build_918
+
+ case DECIMAL:
+ dm_build_939 = Dm_build_919
+
+ case REAL:
+ dm_build_939 = 4
+
+ case DOUBLE:
+ dm_build_939 = 8
+
+ case DATE:
+ case TIME:
+ case DATETIME:
+ case TIME_TZ:
+ case DATETIME_TZ:
+ dm_build_939 = 12
+
+ case INTERVAL_YM:
+ dm_build_939 = 12
+
+ case INTERVAL_DT:
+ dm_build_939 = 24
+
+ default:
+ panic(ECGO_INVALID_COLUMN_TYPE)
+ }
+ return dm_build_939
+}
+
+const (
+ Dm_build_940 = Dm_build_634
+
+ Dm_build_941 = Dm_build_940 + DDWORD_SIZE
+
+ Dm_build_942 = Dm_build_941 + LINT64_SIZE
+
+ Dm_build_943 = Dm_build_942 + USINT_SIZE
+
+ Dm_build_944 = Dm_build_634
+
+ Dm_build_945 = Dm_build_944 + DDWORD_SIZE
+)
+
+type dm_build_946 struct {
+ dm_build_841
+ dm_build_947 *innerRows
+ dm_build_948 int64
+ dm_build_949 int64
+}
+
+func dm_build_950(dm_build_951 *dm_build_332, dm_build_952 *innerRows, dm_build_953 int64, dm_build_954 int64) *dm_build_946 {
+ dm_build_955 := new(dm_build_946)
+ dm_build_955.dm_build_750(dm_build_951, Dm_build_612, dm_build_952.dmStmt)
+ dm_build_955.dm_build_947 = dm_build_952
+ dm_build_955.dm_build_948 = dm_build_953
+ dm_build_955.dm_build_949 = dm_build_954
+ return dm_build_955
+}
+
+func (dm_build_957 *dm_build_946) dm_build_727() error {
+
+ dm_build_957.dm_build_742.dm_build_335.Dm_build_195(Dm_build_940, dm_build_957.dm_build_948)
+
+ dm_build_957.dm_build_742.dm_build_335.Dm_build_195(Dm_build_941, dm_build_957.dm_build_949)
+
+ dm_build_957.dm_build_742.dm_build_335.Dm_build_187(Dm_build_942, dm_build_957.dm_build_947.id)
+
+ dm_build_958 := dm_build_957.dm_build_947.dmStmt.dmConn.dmConnector.bufPrefetch
+ var dm_build_959 int32
+ if dm_build_957.dm_build_947.sizeOfRow != 0 && dm_build_957.dm_build_947.fetchSize != 0 {
+ if dm_build_957.dm_build_947.sizeOfRow*dm_build_957.dm_build_947.fetchSize > int(INT32_MAX) {
+ dm_build_959 = INT32_MAX
+ } else {
+ dm_build_959 = int32(dm_build_957.dm_build_947.sizeOfRow * dm_build_957.dm_build_947.fetchSize)
+ }
+
+ if dm_build_959 < Dm_build_666 {
+ dm_build_958 = int(Dm_build_666)
+ } else if dm_build_959 > Dm_build_667 {
+ dm_build_958 = int(Dm_build_667)
+ } else {
+ dm_build_958 = int(dm_build_959)
+ }
+
+ dm_build_957.dm_build_742.dm_build_335.Dm_build_191(Dm_build_943, int32(dm_build_958))
+ }
+
+ return nil
+}
+
+func (dm_build_961 *dm_build_946) dm_build_731() (interface{}, error) {
+ dm_build_962 := execRetInfo{}
+ dm_build_962.rsBdta = dm_build_961.dm_build_947.isBdta
+
+ dm_build_962.updateCount = dm_build_961.dm_build_742.dm_build_335.Dm_build_272(Dm_build_944)
+ dm_build_963 := dm_build_961.dm_build_742.dm_build_335.Dm_build_269(Dm_build_945)
+
+ dm_build_961.dm_build_901(&dm_build_962, len(dm_build_961.dm_build_947.columns), int(dm_build_963), -1)
+
+ return &dm_build_962, nil
+}
+
+type dm_build_964 struct {
+ dm_build_741
+ dm_build_965 *lob
+ dm_build_966 int
+ dm_build_967 int
+}
+
+func dm_build_968(dm_build_969 *dm_build_332, dm_build_970 *lob, dm_build_971 int, dm_build_972 int) *dm_build_964 {
+ dm_build_973 := new(dm_build_964)
+ dm_build_973.dm_build_746(dm_build_969, Dm_build_625)
+ dm_build_973.dm_build_965 = dm_build_970
+ dm_build_973.dm_build_966 = dm_build_971
+ dm_build_973.dm_build_967 = dm_build_972
+ return dm_build_973
+}
+
+func (dm_build_975 *dm_build_964) dm_build_727() error {
+
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_43(byte(dm_build_975.dm_build_965.lobFlag))
+
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_51(dm_build_975.dm_build_965.tabId)
+
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_47(dm_build_975.dm_build_965.colId)
+
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_67(uint64(dm_build_975.dm_build_965.blobId))
+
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_47(dm_build_975.dm_build_965.groupId)
+
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_47(dm_build_975.dm_build_965.fileId)
+
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_51(dm_build_975.dm_build_965.pageNo)
+
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_47(dm_build_975.dm_build_965.curFileId)
+
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_51(dm_build_975.dm_build_965.curPageNo)
+
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_51(dm_build_975.dm_build_965.totalOffset)
+
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_51(int32(dm_build_975.dm_build_966))
+
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_51(int32(dm_build_975.dm_build_967))
+
+ if dm_build_975.dm_build_742.dm_build_336.NewLobFlag {
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_67(uint64(dm_build_975.dm_build_965.rowId))
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_47(dm_build_975.dm_build_965.exGroupId)
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_47(dm_build_975.dm_build_965.exFileId)
+ dm_build_975.dm_build_742.dm_build_335.Dm_build_51(dm_build_975.dm_build_965.exPageNo)
+ }
+
+ return nil
+}
+
+func (dm_build_977 *dm_build_964) dm_build_731() (interface{}, error) {
+
+ dm_build_977.dm_build_965.readOver = dm_build_977.dm_build_742.dm_build_335.Dm_build_119() == 1
+ var dm_build_978 = dm_build_977.dm_build_742.dm_build_335.Dm_build_143()
+ if dm_build_978 <= 0 {
+ return []byte(nil), nil
+ }
+ dm_build_977.dm_build_965.curFileId = dm_build_977.dm_build_742.dm_build_335.Dm_build_122()
+ dm_build_977.dm_build_965.curPageNo = dm_build_977.dm_build_742.dm_build_335.Dm_build_125()
+ dm_build_977.dm_build_965.totalOffset = dm_build_977.dm_build_742.dm_build_335.Dm_build_125()
+
+ return dm_build_977.dm_build_742.dm_build_335.Dm_build_156(int(dm_build_978)), nil
+}
+
+type dm_build_979 struct {
+ dm_build_741
+ dm_build_980 *lob
+}
+
+func dm_build_981(dm_build_982 *dm_build_332, dm_build_983 *lob) *dm_build_979 {
+ dm_build_984 := new(dm_build_979)
+ dm_build_984.dm_build_746(dm_build_982, Dm_build_622)
+ dm_build_984.dm_build_980 = dm_build_983
+ return dm_build_984
+}
+
+func (dm_build_986 *dm_build_979) dm_build_727() error {
+
+ dm_build_986.dm_build_742.dm_build_335.Dm_build_43(byte(dm_build_986.dm_build_980.lobFlag))
+
+ dm_build_986.dm_build_742.dm_build_335.Dm_build_67(uint64(dm_build_986.dm_build_980.blobId))
+
+ dm_build_986.dm_build_742.dm_build_335.Dm_build_47(dm_build_986.dm_build_980.groupId)
+
+ dm_build_986.dm_build_742.dm_build_335.Dm_build_47(dm_build_986.dm_build_980.fileId)
+
+ dm_build_986.dm_build_742.dm_build_335.Dm_build_51(dm_build_986.dm_build_980.pageNo)
+
+ if dm_build_986.dm_build_742.dm_build_336.NewLobFlag {
+ dm_build_986.dm_build_742.dm_build_335.Dm_build_51(dm_build_986.dm_build_980.tabId)
+ dm_build_986.dm_build_742.dm_build_335.Dm_build_47(dm_build_986.dm_build_980.colId)
+ dm_build_986.dm_build_742.dm_build_335.Dm_build_67(uint64(dm_build_986.dm_build_980.rowId))
+
+ dm_build_986.dm_build_742.dm_build_335.Dm_build_47(dm_build_986.dm_build_980.exGroupId)
+ dm_build_986.dm_build_742.dm_build_335.Dm_build_47(dm_build_986.dm_build_980.exFileId)
+ dm_build_986.dm_build_742.dm_build_335.Dm_build_51(dm_build_986.dm_build_980.exPageNo)
+ }
+
+ return nil
+}
+
+func (dm_build_988 *dm_build_979) dm_build_731() (interface{}, error) {
+
+ if dm_build_988.dm_build_742.dm_build_335.Dm_build_22(false) == 8 {
+ return dm_build_988.dm_build_742.dm_build_335.Dm_build_128(), nil
+ } else {
+ return int64(dm_build_988.dm_build_742.dm_build_335.Dm_build_143()), nil
+ }
+}
+
+type dm_build_989 struct {
+ dm_build_741
+ dm_build_990 *lob
+ dm_build_991 int
+}
+
+func dm_build_992(dm_build_993 *dm_build_332, dm_build_994 *lob, dm_build_995 int) *dm_build_989 {
+ dm_build_996 := new(dm_build_989)
+ dm_build_996.dm_build_746(dm_build_993, Dm_build_624)
+ dm_build_996.dm_build_990 = dm_build_994
+ dm_build_996.dm_build_991 = dm_build_995
+ return dm_build_996
+}
+
+func (dm_build_998 *dm_build_989) dm_build_727() error {
+
+ dm_build_998.dm_build_742.dm_build_335.Dm_build_43(byte(dm_build_998.dm_build_990.lobFlag))
+
+ dm_build_998.dm_build_742.dm_build_335.Dm_build_67(uint64(dm_build_998.dm_build_990.blobId))
+
+ dm_build_998.dm_build_742.dm_build_335.Dm_build_47(dm_build_998.dm_build_990.groupId)
+
+ dm_build_998.dm_build_742.dm_build_335.Dm_build_47(dm_build_998.dm_build_990.fileId)
+
+ dm_build_998.dm_build_742.dm_build_335.Dm_build_51(dm_build_998.dm_build_990.pageNo)
+
+ dm_build_998.dm_build_742.dm_build_335.Dm_build_51(dm_build_998.dm_build_990.tabId)
+ dm_build_998.dm_build_742.dm_build_335.Dm_build_47(dm_build_998.dm_build_990.colId)
+ dm_build_998.dm_build_742.dm_build_335.Dm_build_67(uint64(dm_build_998.dm_build_990.rowId))
+ dm_build_998.dm_build_742.dm_build_335.Dm_build_79(Dm_build_1220.Dm_build_1422(uint32(dm_build_998.dm_build_991)))
+
+ if dm_build_998.dm_build_742.dm_build_336.NewLobFlag {
+ dm_build_998.dm_build_742.dm_build_335.Dm_build_47(dm_build_998.dm_build_990.exGroupId)
+ dm_build_998.dm_build_742.dm_build_335.Dm_build_47(dm_build_998.dm_build_990.exFileId)
+ dm_build_998.dm_build_742.dm_build_335.Dm_build_51(dm_build_998.dm_build_990.exPageNo)
+ }
+ return nil
+}
+
+func (dm_build_1000 *dm_build_989) dm_build_731() (interface{}, error) {
+
+ dm_build_1001 := dm_build_1000.dm_build_742.dm_build_335.Dm_build_143()
+ dm_build_1000.dm_build_990.blobId = dm_build_1000.dm_build_742.dm_build_335.Dm_build_128()
+ dm_build_1000.dm_build_990.resetCurrentInfo()
+ return int64(dm_build_1001), nil
+}
+
+const (
+ Dm_build_1002 = Dm_build_634
+
+ Dm_build_1003 = Dm_build_1002 + ULINT_SIZE
+
+ Dm_build_1004 = Dm_build_1003 + ULINT_SIZE
+
+ Dm_build_1005 = Dm_build_1004 + ULINT_SIZE
+
+ Dm_build_1006 = Dm_build_1005 + BYTE_SIZE
+
+ Dm_build_1007 = Dm_build_1006 + USINT_SIZE
+
+ Dm_build_1008 = Dm_build_1007 + ULINT_SIZE
+
+ Dm_build_1009 = Dm_build_1008 + BYTE_SIZE
+
+ Dm_build_1010 = Dm_build_1009 + BYTE_SIZE
+
+ Dm_build_1011 = Dm_build_1010 + BYTE_SIZE
+
+ Dm_build_1012 = Dm_build_634
+
+ Dm_build_1013 = Dm_build_1012 + ULINT_SIZE
+
+ Dm_build_1014 = Dm_build_1013 + ULINT_SIZE
+
+ Dm_build_1015 = Dm_build_1014 + BYTE_SIZE
+
+ Dm_build_1016 = Dm_build_1015 + ULINT_SIZE
+
+ Dm_build_1017 = Dm_build_1016 + BYTE_SIZE
+
+ Dm_build_1018 = Dm_build_1017 + BYTE_SIZE
+
+ Dm_build_1019 = Dm_build_1018 + USINT_SIZE
+
+ Dm_build_1020 = Dm_build_1019 + USINT_SIZE
+
+ Dm_build_1021 = Dm_build_1020 + BYTE_SIZE
+
+ Dm_build_1022 = Dm_build_1021 + USINT_SIZE
+
+ Dm_build_1023 = Dm_build_1022 + BYTE_SIZE
+
+ Dm_build_1024 = Dm_build_1023 + BYTE_SIZE
+
+ Dm_build_1025 = Dm_build_1024 + ULINT_SIZE
+
+ Dm_build_1026 = Dm_build_1025 + USINT_SIZE
+)
+
+type dm_build_1027 struct {
+ dm_build_741
+
+ dm_build_1028 *DmConnection
+
+ dm_build_1029 bool
+}
+
+func dm_build_1030(dm_build_1031 *dm_build_332) *dm_build_1027 {
+ dm_build_1032 := new(dm_build_1027)
+ dm_build_1032.dm_build_746(dm_build_1031, Dm_build_606)
+ dm_build_1032.dm_build_1028 = dm_build_1031.dm_build_336
+ return dm_build_1032
+}
+
+func (dm_build_1034 *dm_build_1027) dm_build_727() error {
+
+ if dm_build_1034.dm_build_1028.dmConnector.newClientType {
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_191(Dm_build_1002, Dm_build_646)
+ } else {
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_191(Dm_build_1002, Dm_build_645)
+ }
+
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_191(Dm_build_1003, g2dbIsoLevel(dm_build_1034.dm_build_1028.IsoLevel))
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_191(Dm_build_1004, int32(Locale))
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_187(Dm_build_1006, dm_build_1034.dm_build_1028.dmConnector.localTimezone)
+
+ if dm_build_1034.dm_build_1028.ReadOnly {
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1005, Dm_build_669)
+ } else {
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1005, Dm_build_668)
+ }
+
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_191(Dm_build_1007, int32(dm_build_1034.dm_build_1028.dmConnector.sessionTimeout))
+
+ if dm_build_1034.dm_build_1028.dmConnector.mppLocal {
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1008, 1)
+ } else {
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1008, 0)
+ }
+
+ if dm_build_1034.dm_build_1028.dmConnector.rwSeparate {
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1009, 1)
+ } else {
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1009, 0)
+ }
+
+ if dm_build_1034.dm_build_1028.NewLobFlag {
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1010, 1)
+ } else {
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1010, 0)
+ }
+
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1011, dm_build_1034.dm_build_1028.dmConnector.osAuthType)
+
+ dm_build_1035 := dm_build_1034.dm_build_1028.getServerEncoding()
+
+ if dm_build_1034.dm_build_742.dm_build_342 != "" {
+
+ }
+
+ dm_build_1036 := Dm_build_1220.Dm_build_1433(dm_build_1034.dm_build_1028.dmConnector.user, dm_build_1035, dm_build_1034.dm_build_742.dm_build_336)
+ dm_build_1037 := Dm_build_1220.Dm_build_1433(dm_build_1034.dm_build_1028.dmConnector.password, dm_build_1035, dm_build_1034.dm_build_742.dm_build_336)
+ if len(dm_build_1036) > Dm_build_642 {
+ return ECGO_USERNAME_TOO_LONG.throw()
+ }
+ if len(dm_build_1037) > Dm_build_642 {
+ return ECGO_PASSWORD_TOO_LONG.throw()
+ }
+
+ if dm_build_1034.dm_build_742.dm_build_338 && dm_build_1034.dm_build_1028.dmConnector.loginCertificate != "" {
+
+ } else if dm_build_1034.dm_build_742.dm_build_338 {
+ dm_build_1036 = dm_build_1034.dm_build_742.dm_build_337.Encrypt(dm_build_1036, false)
+ dm_build_1037 = dm_build_1034.dm_build_742.dm_build_337.Encrypt(dm_build_1037, false)
+ }
+
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_83(dm_build_1036)
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_83(dm_build_1037)
+
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_95(dm_build_1034.dm_build_1028.dmConnector.appName, dm_build_1035, dm_build_1034.dm_build_742.dm_build_336)
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_95(dm_build_1034.dm_build_1028.dmConnector.osName, dm_build_1035, dm_build_1034.dm_build_742.dm_build_336)
+
+ if hostName, err := os.Hostname(); err != nil {
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_95(hostName, dm_build_1035, dm_build_1034.dm_build_742.dm_build_336)
+ } else {
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_95("", dm_build_1035, dm_build_1034.dm_build_742.dm_build_336)
+ }
+
+ if dm_build_1034.dm_build_1028.dmConnector.rwStandby {
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_43(1)
+ } else {
+ dm_build_1034.dm_build_742.dm_build_335.Dm_build_43(0)
+ }
+
+ return nil
+}
+
+func (dm_build_1039 *dm_build_1027) dm_build_731() (interface{}, error) {
+
+ dm_build_1039.dm_build_1028.MaxRowSize = dm_build_1039.dm_build_742.dm_build_335.Dm_build_269(Dm_build_1012)
+ dm_build_1039.dm_build_1028.DDLAutoCommit = dm_build_1039.dm_build_742.dm_build_335.Dm_build_263(Dm_build_1014) == 1
+ dm_build_1039.dm_build_1028.IsoLevel = dm_build_1039.dm_build_742.dm_build_335.Dm_build_269(Dm_build_1015)
+ dm_build_1039.dm_build_1028.dmConnector.caseSensitive = dm_build_1039.dm_build_742.dm_build_335.Dm_build_263(Dm_build_1016) == 1
+ dm_build_1039.dm_build_1028.BackslashEscape = dm_build_1039.dm_build_742.dm_build_335.Dm_build_263(Dm_build_1017) == 1
+ dm_build_1039.dm_build_1028.SvrStat = int32(dm_build_1039.dm_build_742.dm_build_335.Dm_build_266(Dm_build_1019))
+ dm_build_1039.dm_build_1028.SvrMode = int32(dm_build_1039.dm_build_742.dm_build_335.Dm_build_266(Dm_build_1018))
+ dm_build_1039.dm_build_1028.ConstParaOpt = dm_build_1039.dm_build_742.dm_build_335.Dm_build_263(Dm_build_1020) == 1
+ dm_build_1039.dm_build_1028.DbTimezone = dm_build_1039.dm_build_742.dm_build_335.Dm_build_266(Dm_build_1021)
+ dm_build_1039.dm_build_1028.NewLobFlag = dm_build_1039.dm_build_742.dm_build_335.Dm_build_263(Dm_build_1023) == 1
+
+ if dm_build_1039.dm_build_1028.dmConnector.bufPrefetch == 0 {
+ dm_build_1039.dm_build_1028.dmConnector.bufPrefetch = int(dm_build_1039.dm_build_742.dm_build_335.Dm_build_269(Dm_build_1024))
+ }
+
+ dm_build_1039.dm_build_1028.LifeTimeRemainder = dm_build_1039.dm_build_742.dm_build_335.Dm_build_266(Dm_build_1025)
+ dm_build_1039.dm_build_1028.dscControl = dm_build_1039.dm_build_742.dm_build_335.Dm_build_263(Dm_build_1026) == 1
+
+ dm_build_1040 := dm_build_1039.dm_build_1028.getServerEncoding()
+
+ dm_build_1039.dm_build_1028.InstanceName = dm_build_1039.dm_build_742.dm_build_335.Dm_build_167(dm_build_1040, dm_build_1039.dm_build_742.dm_build_336)
+
+ var dm_build_1041 = dm_build_1039.dm_build_742.dm_build_335.Dm_build_125()
+ if dm_build_1041 == 0 && dm_build_1039.dm_build_1028.MsgVersion > 0 {
+ dm_build_1039.dm_build_1028.Schema = strings.ToUpper(dm_build_1039.dm_build_1028.dmConnector.user)
+ } else {
+ dm_build_1039.dm_build_1028.Schema = dm_build_1039.dm_build_742.dm_build_335.Dm_build_162(int(dm_build_1041), dm_build_1040, dm_build_1039.dm_build_742.dm_build_336)
+ }
+
+ dm_build_1039.dm_build_1028.LastLoginIP = dm_build_1039.dm_build_742.dm_build_335.Dm_build_167(dm_build_1040, dm_build_1039.dm_build_742.dm_build_336)
+ dm_build_1039.dm_build_1028.LastLoginTime = dm_build_1039.dm_build_742.dm_build_335.Dm_build_167(dm_build_1040, dm_build_1039.dm_build_742.dm_build_336)
+ dm_build_1039.dm_build_1028.FailedAttempts = dm_build_1039.dm_build_742.dm_build_335.Dm_build_125()
+ dm_build_1039.dm_build_1028.LoginWarningID = dm_build_1039.dm_build_742.dm_build_335.Dm_build_125()
+ dm_build_1039.dm_build_1028.GraceTimeRemainder = dm_build_1039.dm_build_742.dm_build_335.Dm_build_125()
+ dm_build_1039.dm_build_1028.Guid = dm_build_1039.dm_build_742.dm_build_335.Dm_build_167(dm_build_1040, dm_build_1039.dm_build_742.dm_build_336)
+ dm_build_1039.dm_build_1028.DbName = dm_build_1039.dm_build_742.dm_build_335.Dm_build_167(dm_build_1040, dm_build_1039.dm_build_742.dm_build_336)
+
+ if dm_build_1039.dm_build_742.dm_build_335.Dm_build_263(Dm_build_1022) == 1 {
+ dm_build_1039.dm_build_1028.StandbyHost = dm_build_1039.dm_build_742.dm_build_335.Dm_build_167(dm_build_1040, dm_build_1039.dm_build_742.dm_build_336)
+ dm_build_1039.dm_build_1028.StandbyPort = dm_build_1039.dm_build_742.dm_build_335.Dm_build_125()
+ dm_build_1039.dm_build_1028.StandbyCount = int32(dm_build_1039.dm_build_742.dm_build_335.Dm_build_140())
+ }
+
+ if dm_build_1039.dm_build_742.dm_build_335.Dm_build_22(false) > 0 {
+ dm_build_1039.dm_build_1028.SessionID = dm_build_1039.dm_build_742.dm_build_335.Dm_build_128()
+ }
+
+ if dm_build_1039.dm_build_742.dm_build_335.Dm_build_22(false) > 0 {
+ if dm_build_1039.dm_build_742.dm_build_335.Dm_build_119() == 1 {
+
+ dm_build_1039.dm_build_1028.FormatDate = "DD-MON-YY"
+
+ dm_build_1039.dm_build_1028.FormatTime = "HH12.MI.SS.FF6 AM"
+
+ dm_build_1039.dm_build_1028.FormatTimestamp = "DD-MON-YY HH12.MI.SS.FF6 AM"
+
+ dm_build_1039.dm_build_1028.FormatTimestampTZ = "DD-MON-YY HH12.MI.SS.FF6 AM +TZH:TZM"
+
+ dm_build_1039.dm_build_1028.FormatTimeTZ = "HH12.MI.SS.FF6 AM +TZH:TZM"
+ }
+ }
+
+ if dm_build_1039.dm_build_742.dm_build_335.Dm_build_22(false) > 0 {
+
+ format := dm_build_1039.dm_build_742.dm_build_335.Dm_build_171(dm_build_1040, dm_build_1039.dm_build_742.dm_build_336)
+ if format != "" {
+ dm_build_1039.dm_build_1028.FormatDate = format
+ }
+ format = dm_build_1039.dm_build_742.dm_build_335.Dm_build_171(dm_build_1040, dm_build_1039.dm_build_742.dm_build_336)
+ if format != "" {
+ dm_build_1039.dm_build_1028.FormatTime = format
+ }
+ format = dm_build_1039.dm_build_742.dm_build_335.Dm_build_171(dm_build_1040, dm_build_1039.dm_build_742.dm_build_336)
+ if format != "" {
+ dm_build_1039.dm_build_1028.FormatTimestamp = format
+ }
+ format = dm_build_1039.dm_build_742.dm_build_335.Dm_build_171(dm_build_1040, dm_build_1039.dm_build_742.dm_build_336)
+ if format != "" {
+ dm_build_1039.dm_build_1028.FormatTimestampTZ = format
+ }
+ format = dm_build_1039.dm_build_742.dm_build_335.Dm_build_171(dm_build_1040, dm_build_1039.dm_build_742.dm_build_336)
+ if format != "" {
+ dm_build_1039.dm_build_1028.FormatTimeTZ = format
+ }
+ }
+
+ return nil, nil
+}
+
+const (
+ Dm_build_1042 = Dm_build_634
+)
+
+type dm_build_1043 struct {
+ dm_build_841
+ dm_build_1044 int16
+}
+
+func dm_build_1045(dm_build_1046 *dm_build_332, dm_build_1047 *DmStatement, dm_build_1048 int16) *dm_build_1043 {
+ dm_build_1049 := new(dm_build_1043)
+ dm_build_1049.dm_build_750(dm_build_1046, Dm_build_626, dm_build_1047)
+ dm_build_1049.dm_build_1044 = dm_build_1048
+ return dm_build_1049
+}
+
+func (dm_build_1051 *dm_build_1043) dm_build_727() error {
+ dm_build_1051.dm_build_742.dm_build_335.Dm_build_187(Dm_build_1042, dm_build_1051.dm_build_1044)
+ return nil
+}
+
+func (dm_build_1053 *dm_build_1043) dm_build_731() (interface{}, error) {
+ return dm_build_1053.dm_build_841.dm_build_731()
+}
+
+const (
+ Dm_build_1054 = Dm_build_634
+ Dm_build_1055 = Dm_build_1054 + USINT_SIZE
+)
+
+type dm_build_1056 struct {
+ dm_build_841
+ dm_build_1057 []parameter
+}
+
+func dm_build_1058(dm_build_1059 *dm_build_332, dm_build_1060 *DmStatement, dm_build_1061 []parameter) *dm_build_1056 {
+ dm_build_1062 := new(dm_build_1056)
+ dm_build_1062.dm_build_750(dm_build_1059, Dm_build_630, dm_build_1060)
+ dm_build_1062.dm_build_1057 = dm_build_1061
+ return dm_build_1062
+}
+
+func (dm_build_1064 *dm_build_1056) dm_build_727() error {
+
+ if dm_build_1064.dm_build_1057 == nil {
+ dm_build_1064.dm_build_742.dm_build_335.Dm_build_187(Dm_build_1054, 0)
+ } else {
+ dm_build_1064.dm_build_742.dm_build_335.Dm_build_187(Dm_build_1054, int16(len(dm_build_1064.dm_build_1057)))
+ }
+
+ dm_build_1064.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1055, 0)
+
+ return dm_build_1064.dm_build_864(dm_build_1064.dm_build_1057)
+}
+
+type dm_build_1065 struct {
+ dm_build_841
+ dm_build_1066 bool
+ dm_build_1067 int16
+}
+
+func dm_build_1068(dm_build_1069 *dm_build_332, dm_build_1070 *DmStatement, dm_build_1071 bool, dm_build_1072 int16) *dm_build_1065 {
+ dm_build_1073 := new(dm_build_1065)
+ dm_build_1073.dm_build_750(dm_build_1069, Dm_build_610, dm_build_1070)
+ dm_build_1073.dm_build_1066 = dm_build_1071
+ dm_build_1073.dm_build_1067 = dm_build_1072
+ return dm_build_1073
+}
+
+func (dm_build_1075 *dm_build_1065) dm_build_727() error {
+
+ dm_build_1076 := Dm_build_634
+
+ if dm_build_1075.dm_build_742.dm_build_336.autoCommit {
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_183(dm_build_1076, 1)
+ } else {
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_183(dm_build_1076, 0)
+ }
+
+ if dm_build_1075.dm_build_1066 {
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_183(dm_build_1076, 1)
+ } else {
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_183(dm_build_1076, 0)
+ }
+
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_183(dm_build_1076, 0)
+
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_183(dm_build_1076, 1)
+
+ if dm_build_1075.dm_build_742.dm_build_336.CompatibleOracle() {
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_183(dm_build_1076, 0)
+ } else {
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_183(dm_build_1076, 1)
+ }
+
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_187(dm_build_1076, dm_build_1075.dm_build_1067)
+
+ if dm_build_1075.dm_build_745.maxRows <= 0 || dm_build_1075.dm_build_742.dm_build_336.dmConnector.enRsCache {
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_195(dm_build_1076, INT64_MAX)
+ } else {
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_195(dm_build_1076, dm_build_1075.dm_build_745.maxRows)
+ }
+
+ if dm_build_1075.dm_build_742.dm_build_336.dmConnector.isBdtaRS {
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_183(dm_build_1076, Dm_build_713)
+ } else {
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_183(dm_build_1076, Dm_build_712)
+ }
+
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_187(dm_build_1076, 0)
+
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_183(dm_build_1076, 1)
+
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_183(dm_build_1076, 0)
+
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_183(dm_build_1076, 0)
+
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_191(dm_build_1076, dm_build_1075.dm_build_745.queryTimeout)
+
+ if dm_build_1075.dm_build_745.innerExec {
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_183(dm_build_1076, 1)
+ } else {
+ dm_build_1076 += dm_build_1075.dm_build_742.dm_build_335.Dm_build_183(dm_build_1076, 0)
+ }
+
+ dm_build_1075.dm_build_742.dm_build_335.Dm_build_113(dm_build_1075.dm_build_745.nativeSql, dm_build_1075.dm_build_742.dm_build_336.getServerEncoding(), dm_build_1075.dm_build_742.dm_build_336)
+
+ return nil
+}
+
+func (dm_build_1078 *dm_build_1065) dm_build_731() (interface{}, error) {
+
+ if dm_build_1078.dm_build_1066 {
+ return dm_build_1078.dm_build_841.dm_build_731()
+ }
+
+ dm_build_1079 := NewExceInfo()
+ dm_build_1080 := Dm_build_634
+
+ dm_build_1079.retSqlType = dm_build_1078.dm_build_742.dm_build_335.Dm_build_266(dm_build_1080)
+ dm_build_1080 += USINT_SIZE
+
+ dm_build_1081 := dm_build_1078.dm_build_742.dm_build_335.Dm_build_284(dm_build_1080)
+ dm_build_1080 += USINT_SIZE
+
+ dm_build_1082 := dm_build_1078.dm_build_742.dm_build_335.Dm_build_266(dm_build_1080)
+ dm_build_1080 += USINT_SIZE
+
+ dm_build_1078.dm_build_742.dm_build_335.Dm_build_272(dm_build_1080)
+ dm_build_1080 += DDWORD_SIZE
+
+ dm_build_1078.dm_build_742.dm_build_336.TrxStatus = dm_build_1078.dm_build_742.dm_build_335.Dm_build_269(dm_build_1080)
+ dm_build_1080 += ULINT_SIZE
+
+ if dm_build_1081 > 0 {
+ dm_build_1078.dm_build_745.params = dm_build_1078.dm_build_1083(int(dm_build_1081))
+ dm_build_1078.dm_build_745.paramCount = int32(dm_build_1081)
+ } else {
+ dm_build_1078.dm_build_745.params = make([]parameter, 0)
+ dm_build_1078.dm_build_745.paramCount = 0
+ }
+
+ if dm_build_1082 > 0 {
+ dm_build_1078.dm_build_745.columns = dm_build_1078.dm_build_891(int(dm_build_1082), dm_build_1079.rsBdta)
+ } else {
+ dm_build_1078.dm_build_745.columns = make([]column, 0)
+ }
+
+ return dm_build_1079, nil
+}
+
+func (dm_build_1084 *dm_build_1065) dm_build_1083(dm_build_1085 int) []parameter {
+
+ var dm_build_1086, dm_build_1087, dm_build_1088, dm_build_1089 int16
+
+ dm_build_1090 := make([]parameter, dm_build_1085)
+ for i := 0; i < dm_build_1085; i++ {
+
+ dm_build_1090[i].InitParameter()
+
+ dm_build_1090[i].colType = dm_build_1084.dm_build_742.dm_build_335.Dm_build_125()
+
+ dm_build_1090[i].prec = dm_build_1084.dm_build_742.dm_build_335.Dm_build_125()
+
+ dm_build_1090[i].scale = dm_build_1084.dm_build_742.dm_build_335.Dm_build_125()
+
+ dm_build_1090[i].nullable = dm_build_1084.dm_build_742.dm_build_335.Dm_build_125() != 0
+
+ itemFlag := dm_build_1084.dm_build_742.dm_build_335.Dm_build_122()
+
+ if int(itemFlag)&Dm_build_840 != 0 {
+ dm_build_1090[i].typeFlag = TYPE_FLAG_RECOMMEND
+ } else {
+ dm_build_1090[i].typeFlag = TYPE_FLAG_EXACT
+ }
+
+ dm_build_1090[i].lob = int(itemFlag)&Dm_build_838 != 0
+
+ dm_build_1084.dm_build_742.dm_build_335.Dm_build_125()
+
+ dm_build_1090[i].ioType = byte(dm_build_1084.dm_build_742.dm_build_335.Dm_build_122())
+
+ dm_build_1086 = dm_build_1084.dm_build_742.dm_build_335.Dm_build_122()
+
+ dm_build_1087 = dm_build_1084.dm_build_742.dm_build_335.Dm_build_122()
+
+ dm_build_1088 = dm_build_1084.dm_build_742.dm_build_335.Dm_build_122()
+
+ dm_build_1089 = dm_build_1084.dm_build_742.dm_build_335.Dm_build_122()
+ dm_build_1090[i].name = dm_build_1084.dm_build_742.dm_build_335.Dm_build_162(int(dm_build_1086), dm_build_1084.dm_build_742.dm_build_336.getServerEncoding(), dm_build_1084.dm_build_742.dm_build_336)
+ dm_build_1090[i].typeName = dm_build_1084.dm_build_742.dm_build_335.Dm_build_162(int(dm_build_1087), dm_build_1084.dm_build_742.dm_build_336.getServerEncoding(), dm_build_1084.dm_build_742.dm_build_336)
+ dm_build_1090[i].tableName = dm_build_1084.dm_build_742.dm_build_335.Dm_build_162(int(dm_build_1088), dm_build_1084.dm_build_742.dm_build_336.getServerEncoding(), dm_build_1084.dm_build_742.dm_build_336)
+ dm_build_1090[i].schemaName = dm_build_1084.dm_build_742.dm_build_335.Dm_build_162(int(dm_build_1089), dm_build_1084.dm_build_742.dm_build_336.getServerEncoding(), dm_build_1084.dm_build_742.dm_build_336)
+
+ if dm_build_1090[i].lob {
+ dm_build_1090[i].lobTabId = dm_build_1084.dm_build_742.dm_build_335.Dm_build_125()
+ dm_build_1090[i].lobColId = dm_build_1084.dm_build_742.dm_build_335.Dm_build_122()
+ }
+ }
+
+ for i := 0; i < dm_build_1085; i++ {
+
+ if isComplexType(int(dm_build_1090[i].colType), int(dm_build_1090[i].scale)) {
+
+ strDesc := newTypeDescriptor(dm_build_1084.dm_build_742.dm_build_336)
+ strDesc.unpack(dm_build_1084.dm_build_742.dm_build_335)
+ dm_build_1090[i].typeDescriptor = strDesc
+ }
+ }
+
+ return dm_build_1090
+}
+
+const (
+ Dm_build_1091 = Dm_build_634
+)
+
+type dm_build_1092 struct {
+ dm_build_741
+ dm_build_1093 int16
+ dm_build_1094 *Dm_build_1499
+ dm_build_1095 int32
+}
+
+func dm_build_1096(dm_build_1097 *dm_build_332, dm_build_1098 *DmStatement, dm_build_1099 int16, dm_build_1100 *Dm_build_1499, dm_build_1101 int32) *dm_build_1092 {
+ dm_build_1102 := new(dm_build_1092)
+ dm_build_1102.dm_build_750(dm_build_1097, Dm_build_616, dm_build_1098)
+ dm_build_1102.dm_build_1093 = dm_build_1099
+ dm_build_1102.dm_build_1094 = dm_build_1100
+ dm_build_1102.dm_build_1095 = dm_build_1101
+ return dm_build_1102
+}
+
+func (dm_build_1104 *dm_build_1092) dm_build_727() error {
+ dm_build_1104.dm_build_742.dm_build_335.Dm_build_187(Dm_build_1091, dm_build_1104.dm_build_1093)
+
+ dm_build_1104.dm_build_742.dm_build_335.Dm_build_51(dm_build_1104.dm_build_1095)
+
+ if dm_build_1104.dm_build_742.dm_build_336.NewLobFlag {
+ dm_build_1104.dm_build_742.dm_build_335.Dm_build_51(-1)
+ }
+ dm_build_1104.dm_build_1094.Dm_build_1506(dm_build_1104.dm_build_742.dm_build_335, int(dm_build_1104.dm_build_1095))
+ return nil
+}
+
+type dm_build_1105 struct {
+ dm_build_741
+}
+
+func dm_build_1106(dm_build_1107 *dm_build_332) *dm_build_1105 {
+ dm_build_1108 := new(dm_build_1105)
+ dm_build_1108.dm_build_746(dm_build_1107, Dm_build_614)
+ return dm_build_1108
+}
+
+type dm_build_1109 struct {
+ dm_build_741
+ dm_build_1110 int32
+}
+
+func dm_build_1111(dm_build_1112 *dm_build_332, dm_build_1113 int32) *dm_build_1109 {
+ dm_build_1114 := new(dm_build_1109)
+ dm_build_1114.dm_build_746(dm_build_1112, Dm_build_627)
+ dm_build_1114.dm_build_1110 = dm_build_1113
+ return dm_build_1114
+}
+
+func (dm_build_1116 *dm_build_1109) dm_build_727() error {
+
+ dm_build_1117 := Dm_build_634
+ dm_build_1117 += dm_build_1116.dm_build_742.dm_build_335.Dm_build_191(dm_build_1117, g2dbIsoLevel(dm_build_1116.dm_build_1110))
+ return nil
+}
+
+type dm_build_1118 struct {
+ dm_build_741
+ dm_build_1119 *lob
+ dm_build_1120 byte
+ dm_build_1121 int
+ dm_build_1122 []byte
+ dm_build_1123 int
+ dm_build_1124 int
+}
+
+func dm_build_1125(dm_build_1126 *dm_build_332, dm_build_1127 *lob, dm_build_1128 byte, dm_build_1129 int, dm_build_1130 []byte,
+ dm_build_1131 int, dm_build_1132 int) *dm_build_1118 {
+ dm_build_1133 := new(dm_build_1118)
+ dm_build_1133.dm_build_746(dm_build_1126, Dm_build_623)
+ dm_build_1133.dm_build_1119 = dm_build_1127
+ dm_build_1133.dm_build_1120 = dm_build_1128
+ dm_build_1133.dm_build_1121 = dm_build_1129
+ dm_build_1133.dm_build_1122 = dm_build_1130
+ dm_build_1133.dm_build_1123 = dm_build_1131
+ dm_build_1133.dm_build_1124 = dm_build_1132
+ return dm_build_1133
+}
+
+func (dm_build_1135 *dm_build_1118) dm_build_727() error {
+
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_43(byte(dm_build_1135.dm_build_1119.lobFlag))
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_43(dm_build_1135.dm_build_1120)
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_67(uint64(dm_build_1135.dm_build_1119.blobId))
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_47(dm_build_1135.dm_build_1119.groupId)
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_47(dm_build_1135.dm_build_1119.fileId)
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_51(dm_build_1135.dm_build_1119.pageNo)
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_47(dm_build_1135.dm_build_1119.curFileId)
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_51(dm_build_1135.dm_build_1119.curPageNo)
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_51(dm_build_1135.dm_build_1119.totalOffset)
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_51(dm_build_1135.dm_build_1119.tabId)
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_47(dm_build_1135.dm_build_1119.colId)
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_67(uint64(dm_build_1135.dm_build_1119.rowId))
+
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_51(int32(dm_build_1135.dm_build_1121))
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_51(int32(dm_build_1135.dm_build_1124))
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_79(dm_build_1135.dm_build_1122)
+
+ if dm_build_1135.dm_build_742.dm_build_336.NewLobFlag {
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_47(dm_build_1135.dm_build_1119.exGroupId)
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_47(dm_build_1135.dm_build_1119.exFileId)
+ dm_build_1135.dm_build_742.dm_build_335.Dm_build_51(dm_build_1135.dm_build_1119.exPageNo)
+ }
+ return nil
+}
+
+func (dm_build_1137 *dm_build_1118) dm_build_731() (interface{}, error) {
+
+ var dm_build_1138 = dm_build_1137.dm_build_742.dm_build_335.Dm_build_125()
+ dm_build_1137.dm_build_1119.blobId = dm_build_1137.dm_build_742.dm_build_335.Dm_build_128()
+ dm_build_1137.dm_build_1119.fileId = dm_build_1137.dm_build_742.dm_build_335.Dm_build_122()
+ dm_build_1137.dm_build_1119.pageNo = dm_build_1137.dm_build_742.dm_build_335.Dm_build_125()
+ dm_build_1137.dm_build_1119.curFileId = dm_build_1137.dm_build_742.dm_build_335.Dm_build_122()
+ dm_build_1137.dm_build_1119.curPageNo = dm_build_1137.dm_build_742.dm_build_335.Dm_build_125()
+ dm_build_1137.dm_build_1119.totalOffset = dm_build_1137.dm_build_742.dm_build_335.Dm_build_125()
+ return dm_build_1138, nil
+}
+
+const (
+ Dm_build_1139 = Dm_build_634
+
+ Dm_build_1140 = Dm_build_1139 + ULINT_SIZE
+
+ Dm_build_1141 = Dm_build_1140 + ULINT_SIZE
+
+ Dm_build_1142 = Dm_build_1141 + BYTE_SIZE
+
+ Dm_build_1143 = Dm_build_1142 + BYTE_SIZE
+
+ Dm_build_1144 = Dm_build_1143 + BYTE_SIZE
+
+ Dm_build_1145 = Dm_build_1144 + BYTE_SIZE
+
+ Dm_build_1146 = Dm_build_1145 + BYTE_SIZE
+
+ Dm_build_1147 = Dm_build_1146 + BYTE_SIZE
+
+ Dm_build_1148 = Dm_build_1147 + BYTE_SIZE
+
+ Dm_build_1149 = Dm_build_634
+
+ Dm_build_1150 = Dm_build_1149 + ULINT_SIZE
+
+ Dm_build_1151 = Dm_build_1150 + ULINT_SIZE
+
+ Dm_build_1152 = Dm_build_1151 + ULINT_SIZE
+
+ Dm_build_1153 = Dm_build_1152 + ULINT_SIZE
+
+ Dm_build_1154 = Dm_build_1153 + ULINT_SIZE
+
+ Dm_build_1155 = Dm_build_1154 + BYTE_SIZE
+
+ Dm_build_1156 = Dm_build_1155 + BYTE_SIZE
+
+ Dm_build_1157 = Dm_build_1156 + BYTE_SIZE
+
+ Dm_build_1158 = Dm_build_1157 + BYTE_SIZE
+
+ Dm_build_1159 = Dm_build_1158 + BYTE_SIZE
+
+ Dm_build_1160 = Dm_build_1159 + USINT_SIZE
+
+ Dm_build_1161 = Dm_build_1160 + BYTE_SIZE
+)
+
+type dm_build_1162 struct {
+ dm_build_741
+ dm_build_1163 *DmConnection
+ dm_build_1164 int
+ Dm_build_1165 int32
+ Dm_build_1166 []byte
+ dm_build_1167 byte
+}
+
+func dm_build_1168(dm_build_1169 *dm_build_332) *dm_build_1162 {
+ dm_build_1170 := new(dm_build_1162)
+ dm_build_1170.dm_build_746(dm_build_1169, Dm_build_632)
+ dm_build_1170.dm_build_1163 = dm_build_1169.dm_build_336
+ return dm_build_1170
+}
+
+func dm_build_1171(dm_build_1172 string, dm_build_1173 string) int {
+ dm_build_1174 := strings.Split(dm_build_1172, ".")
+ dm_build_1175 := strings.Split(dm_build_1173, ".")
+
+ for i, serStr := range dm_build_1174 {
+ ser, _ := strconv.ParseInt(serStr, 10, 32)
+ global, _ := strconv.ParseInt(dm_build_1175[i], 10, 32)
+ if ser < global {
+ return -1
+ } else if ser == global {
+ continue
+ } else {
+ return 1
+ }
+ }
+
+ return 0
+}
+
+func (dm_build_1177 *dm_build_1162) dm_build_727() error {
+
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_191(Dm_build_1139, int32(0))
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_191(Dm_build_1140, int32(dm_build_1177.dm_build_1163.dmConnector.compress))
+
+ if dm_build_1177.dm_build_1163.dmConnector.loginEncrypt {
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1142, 2)
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1141, 1)
+ } else {
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1142, 0)
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1141, 0)
+ }
+
+ if dm_build_1177.dm_build_1163.dmConnector.isBdtaRS {
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1143, Dm_build_713)
+ } else {
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1143, Dm_build_712)
+ }
+
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1144, byte(dm_build_1177.dm_build_1163.dmConnector.compressID))
+
+ if dm_build_1177.dm_build_1163.dmConnector.loginCertificate != "" {
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1145, 1)
+ } else {
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1145, 0)
+ }
+
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1146, 0)
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_183(Dm_build_1147, 1)
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_211(Dm_build_1148, uint16(dm_build_1177.dm_build_1163.MsgVersion))
+
+ dm_build_1178 := dm_build_1177.dm_build_1163.getServerEncoding()
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_95(Dm_build_597, dm_build_1178, dm_build_1177.dm_build_742.dm_build_336)
+
+ var dm_build_1179 byte
+ if dm_build_1177.dm_build_1163.dmConnector.uKeyName != "" {
+ dm_build_1179 = 1
+ } else {
+ dm_build_1179 = 0
+ }
+
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_43(0)
+
+ if dm_build_1179 == 1 {
+
+ }
+
+ if dm_build_1177.dm_build_1163.dmConnector.loginEncrypt {
+ clientPubKey, err := dm_build_1177.dm_build_742.dm_build_577()
+ if err != nil {
+ return err
+ }
+ dm_build_1177.dm_build_742.dm_build_335.Dm_build_83(clientPubKey)
+ }
+
+ return nil
+}
+
+func (dm_build_1181 *dm_build_1162) dm_build_730() error {
+ dm_build_1181.dm_build_742.dm_build_335.Dm_build_17(0)
+ dm_build_1181.dm_build_742.dm_build_335.Dm_build_25(Dm_build_633, false, true)
+ return nil
+}
+
+func (dm_build_1183 *dm_build_1162) dm_build_731() (interface{}, error) {
+
+ dm_build_1183.dm_build_1163.sslEncrypt = int(dm_build_1183.dm_build_742.dm_build_335.Dm_build_269(Dm_build_1149))
+ dm_build_1183.dm_build_1163.GlobalServerSeries = int(dm_build_1183.dm_build_742.dm_build_335.Dm_build_269(Dm_build_1150))
+
+ switch dm_build_1183.dm_build_742.dm_build_335.Dm_build_269(Dm_build_1151) {
+ case 1:
+ dm_build_1183.dm_build_1163.serverEncoding = ENCODING_UTF8
+ case 2:
+ dm_build_1183.dm_build_1163.serverEncoding = ENCODING_EUCKR
+ default:
+ dm_build_1183.dm_build_1163.serverEncoding = ENCODING_GB18030
+ }
+
+ dm_build_1183.dm_build_1163.dmConnector.compress = int(dm_build_1183.dm_build_742.dm_build_335.Dm_build_269(Dm_build_1152))
+ dm_build_1184 := dm_build_1183.dm_build_742.dm_build_335.Dm_build_263(Dm_build_1154)
+ dm_build_1185 := dm_build_1183.dm_build_742.dm_build_335.Dm_build_263(Dm_build_1155)
+ dm_build_1183.dm_build_1163.dmConnector.isBdtaRS = dm_build_1183.dm_build_742.dm_build_335.Dm_build_263(Dm_build_1156) > 0
+ dm_build_1183.dm_build_1163.dmConnector.compressID = int8(dm_build_1183.dm_build_742.dm_build_335.Dm_build_263(Dm_build_1157))
+
+ dm_build_1183.dm_build_742.dm_build_341 = dm_build_1183.dm_build_742.dm_build_335.Dm_build_263(Dm_build_1159) == 1
+ dm_build_1183.dm_build_1163.dmConnector.newClientType = dm_build_1183.dm_build_742.dm_build_335.Dm_build_263(Dm_build_1160) == 1
+ dm_build_1183.dm_build_1163.MsgVersion = int32(dm_build_1183.dm_build_742.dm_build_335.Dm_build_284(Dm_build_1161))
+
+ dm_build_1186 := dm_build_1183.dm_build_774()
+ if dm_build_1186 != nil {
+ return nil, dm_build_1186
+ }
+
+ dm_build_1187 := dm_build_1183.dm_build_742.dm_build_335.Dm_build_167(dm_build_1183.dm_build_1163.getServerEncoding(), dm_build_1183.dm_build_742.dm_build_336)
+ if dm_build_1171(dm_build_1187, Dm_build_598) < 0 {
+ return nil, ECGO_ERROR_SERVER_VERSION.throw()
+ }
+
+ dm_build_1183.dm_build_1163.ServerVersion = dm_build_1187
+ dm_build_1183.dm_build_1163.Malini2 = dm_build_1171(dm_build_1187, Dm_build_599) > 0
+ dm_build_1183.dm_build_1163.Execute2 = dm_build_1171(dm_build_1187, Dm_build_600) > 0
+ dm_build_1183.dm_build_1163.LobEmptyCompOrcl = dm_build_1171(dm_build_1187, Dm_build_601) > 0
+
+ if dm_build_1183.dm_build_742.dm_build_336.dmConnector.uKeyName != "" {
+ dm_build_1183.dm_build_1167 = 1
+ } else {
+ dm_build_1183.dm_build_1167 = 0
+ }
+
+ if dm_build_1183.dm_build_1167 == 1 {
+ dm_build_1183.dm_build_742.dm_build_342 = dm_build_1183.dm_build_742.dm_build_335.Dm_build_162(16, dm_build_1183.dm_build_1163.getServerEncoding(), dm_build_1183.dm_build_742.dm_build_336)
+ }
+
+ dm_build_1183.dm_build_1164 = -1
+ dm_build_1188 := false
+ dm_build_1189 := false
+ dm_build_1183.Dm_build_1165 = -1
+ if dm_build_1185 > 0 {
+ dm_build_1183.dm_build_1164 = int(dm_build_1183.dm_build_742.dm_build_335.Dm_build_125())
+ }
+
+ if dm_build_1184 > 0 {
+
+ if dm_build_1183.dm_build_1164 == -1 {
+ dm_build_1188 = true
+ } else {
+ dm_build_1189 = true
+ }
+
+ dm_build_1183.Dm_build_1166 = dm_build_1183.dm_build_742.dm_build_335.Dm_build_150()
+ }
+
+ if dm_build_1185 == 2 {
+ dm_build_1183.Dm_build_1165 = dm_build_1183.dm_build_742.dm_build_335.Dm_build_125()
+ }
+ dm_build_1183.dm_build_742.dm_build_338 = dm_build_1188
+ dm_build_1183.dm_build_742.dm_build_339 = dm_build_1189
+
+ return nil, nil
+}
+
+type dm_build_1190 struct {
+ dm_build_741
+}
+
+func dm_build_1191(dm_build_1192 *dm_build_332, dm_build_1193 *DmStatement) *dm_build_1190 {
+ dm_build_1194 := new(dm_build_1190)
+ dm_build_1194.dm_build_750(dm_build_1192, Dm_build_608, dm_build_1193)
+ return dm_build_1194
+}
+
+func (dm_build_1196 *dm_build_1190) dm_build_727() error {
+
+ dm_build_1196.dm_build_742.dm_build_335.Dm_build_183(Dm_build_634, 1)
+ return nil
+}
+
+func (dm_build_1198 *dm_build_1190) dm_build_731() (interface{}, error) {
+
+ dm_build_1198.dm_build_745.id = dm_build_1198.dm_build_742.dm_build_335.Dm_build_269(Dm_build_635)
+
+ dm_build_1198.dm_build_745.readBaseColName = dm_build_1198.dm_build_742.dm_build_335.Dm_build_263(Dm_build_634) == 1
+ return nil, nil
+}
+
+type dm_build_1199 struct {
+ dm_build_741
+ dm_build_1200 int32
+}
+
+func dm_build_1201(dm_build_1202 *dm_build_332, dm_build_1203 int32) *dm_build_1199 {
+ dm_build_1204 := new(dm_build_1199)
+ dm_build_1204.dm_build_746(dm_build_1202, Dm_build_609)
+ dm_build_1204.dm_build_1200 = dm_build_1203
+ return dm_build_1204
+}
+
+func (dm_build_1206 *dm_build_1199) dm_build_728() {
+ dm_build_1206.dm_build_741.dm_build_728()
+ dm_build_1206.dm_build_742.dm_build_335.Dm_build_191(Dm_build_635, dm_build_1206.dm_build_1200)
+}
+
+type dm_build_1207 struct {
+ dm_build_741
+ dm_build_1208 []uint32
+}
+
+func dm_build_1209(dm_build_1210 *dm_build_332, dm_build_1211 []uint32) *dm_build_1207 {
+ dm_build_1212 := new(dm_build_1207)
+ dm_build_1212.dm_build_746(dm_build_1210, Dm_build_629)
+ dm_build_1212.dm_build_1208 = dm_build_1211
+ return dm_build_1212
+}
+
+func (dm_build_1214 *dm_build_1207) dm_build_727() error {
+
+ dm_build_1214.dm_build_742.dm_build_335.Dm_build_211(Dm_build_634, uint16(len(dm_build_1214.dm_build_1208)))
+
+ for _, tableID := range dm_build_1214.dm_build_1208 {
+ dm_build_1214.dm_build_742.dm_build_335.Dm_build_63(uint32(tableID))
+ }
+
+ return nil
+}
+
+func (dm_build_1216 *dm_build_1207) dm_build_731() (interface{}, error) {
+ dm_build_1217 := dm_build_1216.dm_build_742.dm_build_335.Dm_build_284(Dm_build_634)
+ if dm_build_1217 <= 0 {
+ return nil, nil
+ }
+
+ dm_build_1218 := make([]int64, dm_build_1217)
+ for i := 0; i < int(dm_build_1217); i++ {
+ dm_build_1218[i] = dm_build_1216.dm_build_742.dm_build_335.Dm_build_128()
+ }
+
+ return dm_build_1218, nil
+}
diff --git a/dmr/zr.go b/dmr/zr.go
new file mode 100644
index 0000000..2dccf4e
--- /dev/null
+++ b/dmr/zr.go
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "io"
+)
+
+const (
+ READ_LEN = Dm_build_717
+)
+
+type iOffRowBinder interface {
+ read(buf *Dm_build_1499)
+ isReadOver() bool
+ getObj() interface{}
+}
+
+type offRowBinder struct {
+ obj interface{}
+ encoding string
+ readOver bool
+ buffer *Dm_build_1499
+ position int32
+ offRow bool
+ targetLength int64
+}
+
+func newOffRowBinder(obj interface{}, encoding string, targetLength int64) *offRowBinder {
+ return &offRowBinder{
+ obj: obj,
+ encoding: encoding,
+ targetLength: targetLength,
+ readOver: false,
+ buffer: Dm_build_1503(),
+ position: 0,
+ }
+}
+
+type offRowBytesBinder struct {
+ *offRowBinder
+}
+
+func newOffRowBytesBinder(obj []byte, encoding string) *offRowBytesBinder {
+ var binder = &offRowBytesBinder{
+ newOffRowBinder(obj, encoding, int64(IGNORE_TARGET_LENGTH)),
+ }
+ binder.read(binder.buffer)
+ binder.offRow = binder.buffer.Dm_build_1504() > Dm_build_714
+ return binder
+}
+
+func (b *offRowBytesBinder) read(buf *Dm_build_1499) {
+ if b.buffer.Dm_build_1504() > 0 {
+ buf.Dm_build_1536(b.buffer)
+ } else if !b.readOver {
+ var obj = b.obj.([]byte)
+ buf.Dm_build_1525(obj, 0, len(obj))
+ b.readOver = true
+ }
+}
+
+func (b *offRowBytesBinder) isReadOver() bool {
+ return b.readOver
+}
+
+func (b *offRowBytesBinder) getObj() interface{} {
+ return b.obj
+}
+
+type offRowBlobBinder struct {
+ *offRowBinder
+}
+
+func newOffRowBlobBinder(blob DmBlob, encoding string) *offRowBlobBinder {
+ var binder = &offRowBlobBinder{
+ newOffRowBinder(blob, encoding, int64(IGNORE_TARGET_LENGTH)),
+ }
+ binder.read(binder.buffer)
+ binder.offRow = binder.buffer.Dm_build_1504() > Dm_build_714
+ return binder
+}
+
+func (b *offRowBlobBinder) read(buf *Dm_build_1499) {
+ if b.buffer.Dm_build_1504() > 0 {
+ buf.Dm_build_1536(b.buffer)
+ } else if !b.readOver {
+ var obj = b.obj.(DmBlob)
+ var totalLen, _ = obj.GetLength()
+ var leaveLen = totalLen - int64(b.position)
+ var readLen = int32(leaveLen)
+ if leaveLen > READ_LEN {
+ readLen = READ_LEN
+ }
+ var bytes, _ = obj.getBytes(int64(b.position)+1, readLen)
+ b.position += readLen
+ if b.position == int32(totalLen) {
+ b.readOver = true
+ }
+ buf.Dm_build_1525(bytes, 0, len(bytes))
+ }
+}
+
+func (b *offRowBlobBinder) isReadOver() bool {
+ return b.readOver
+}
+
+func (b *offRowBlobBinder) getObj() interface{} {
+ return b.obj
+}
+
+type offRowClobBinder struct {
+ *offRowBinder
+}
+
+func newOffRowClobBinder(clob DmClob, encoding string) *offRowClobBinder {
+ var binder = &offRowClobBinder{
+ newOffRowBinder(clob, encoding, int64(IGNORE_TARGET_LENGTH)),
+ }
+ binder.read(binder.buffer)
+ binder.offRow = binder.buffer.Dm_build_1504() > Dm_build_714
+ return binder
+}
+
+func (b *offRowClobBinder) read(buf *Dm_build_1499) {
+ if b.buffer.Dm_build_1504() > 0 {
+ buf.Dm_build_1536(b.buffer)
+ } else if !b.readOver {
+ var obj = b.obj.(DmClob)
+ var totalLen, _ = obj.GetLength()
+ var leaveLen = totalLen - int64(b.position)
+ var readLen = int32(leaveLen)
+ if leaveLen > READ_LEN {
+ readLen = READ_LEN
+ }
+ var str, _ = obj.getSubString(int64(b.position)+1, readLen)
+ var bytes = Dm_build_1220.Dm_build_1433(str, b.encoding, nil)
+ b.position += readLen
+ if b.position == int32(totalLen) {
+ b.readOver = true
+ }
+ buf.Dm_build_1525(bytes, 0, len(bytes))
+ }
+}
+
+func (b *offRowClobBinder) isReadOver() bool {
+ return b.readOver
+}
+
+func (b *offRowClobBinder) getObj() interface{} {
+ return b.obj
+}
+
+type offRowReaderBinder struct {
+ *offRowBinder
+}
+
+func newOffRowReaderBinder(reader io.Reader, encoding string) *offRowReaderBinder {
+ var binder = &offRowReaderBinder{
+ newOffRowBinder(reader, encoding, int64(IGNORE_TARGET_LENGTH)),
+ }
+ binder.read(binder.buffer)
+ binder.offRow = binder.buffer.Dm_build_1504() > Dm_build_714
+ return binder
+}
+
+func (b *offRowReaderBinder) read(buf *Dm_build_1499) {
+ if b.buffer.Dm_build_1504() > 0 {
+ buf.Dm_build_1536(b.buffer)
+ } else if !b.readOver {
+ var err error
+ var readLen = READ_LEN
+ var reader = b.obj.(io.Reader)
+ var bytes = make([]byte, readLen)
+ readLen, err = reader.Read(bytes)
+ if err == io.EOF {
+ b.readOver = true
+ return
+ }
+ b.position += int32(readLen)
+ if readLen < len(bytes) || b.targetLength != int64(IGNORE_TARGET_LENGTH) && int64(b.position) == b.targetLength {
+ b.readOver = true
+ }
+ buf.Dm_build_1525(bytes[0:readLen], 0, readLen)
+ }
+}
+
+func (b *offRowReaderBinder) readAll() []byte {
+ var byteArray = Dm_build_1503()
+ b.read(byteArray)
+ for !b.readOver {
+ b.read(byteArray)
+ }
+ return byteArray.Dm_build_1546()
+}
+
+func (b *offRowReaderBinder) isReadOver() bool {
+ return b.readOver
+}
+
+func (b *offRowReaderBinder) getObj() interface{} {
+ return b.obj
+}
diff --git a/dmr/zs.go b/dmr/zs.go
new file mode 100644
index 0000000..4dd2e71
--- /dev/null
+++ b/dmr/zs.go
@@ -0,0 +1,868 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import (
+ "fmt"
+ "math"
+ "strconv"
+ "strings"
+ "time"
+ "unicode"
+ "unicode/utf8"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+type oracleDateFormat struct {
+ PM bool
+ TZNegative bool
+ pattern string
+ language int
+ FormatElementList []interface{}
+ YearElement yearElement
+ MonthElement monthElement
+ MonElement monElement
+ MMElement mmElement
+ DDElement ddElement
+ HH24Element hh24Element
+ HH12Element hh12Element
+ MIElement miElement
+ SSElement ssElement
+ FElement fElement
+ TZHElement tzhElement
+ TZMElement tzmElement
+ AMElement amElement
+}
+
+type element interface {
+ /**
+ * 从字符串中解析出对应的值,
+ * @param str 完整的字符串
+ * @param offset 当前偏移
+ * @return 解析后的offset
+ */
+ parse(str string, offset int, dt []int) (int, error)
+
+ /**
+ * 将时间值value格式化成字符串
+ */
+ format(dt []int) string
+}
+
+type yearElement struct {
+ OracleDateFormat *oracleDateFormat
+ len int
+}
+
+func (YearElement yearElement) parse(str string, offset int, dt []int) (int, error) {
+ strLen := 0
+ for i := offset; i < offset+YearElement.len && i < len(str); i++ {
+ if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
+ break
+ }
+ strLen++
+ }
+ str = str[offset : offset+strLen]
+ if YearElement.len < 4 {
+ today := strconv.FormatInt(int64(dt[OFFSET_YEAR]), 10)
+ i, err := strconv.ParseInt(today[:4-YearElement.len]+str, 10, 32)
+ if err != nil {
+ return 0, err
+ }
+ dt[OFFSET_YEAR] = int(i)
+ } else {
+ i, err := strconv.ParseInt(str, 10, 32)
+ if err != nil {
+ return 0, err
+ }
+ dt[OFFSET_YEAR] = int(i)
+ }
+
+ return offset + strLen, nil
+}
+
+func (YearElement yearElement) format(dt []int) string {
+ return YearElement.OracleDateFormat.formatInt(dt[OFFSET_YEAR], YearElement.len)
+}
+
+type monthElement struct {
+ OracleDateFormat *oracleDateFormat
+ upperCase bool
+ lowerCase bool
+}
+
+var monthNameList = []string{"", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
+
+func (MonthElement monthElement) parse(str string, offset int, dt []int) (int, error) {
+
+ if MonthElement.OracleDateFormat.language == LANGUAGE_CN {
+ index := strings.IndexRune(str[offset:], '月')
+ if index == -1 {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ index += offset
+
+ mon, err := strconv.ParseInt(str[offset:index], 10, 32)
+ if err != nil {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+
+ if mon > 12 || mon < 1 {
+ return -1, ECGO_INVALID_DATETIME_VALUE.throw()
+ }
+ dt[OFFSET_MONTH] = int(mon)
+ return index + utf8.RuneLen('月'), nil
+ } else {
+ str = str[offset:]
+ mon := 0
+ for i := 1; i < len(monthNameList); i++ {
+ if util.StringUtil.StartWithIgnoreCase(str, monthNameList[i]) {
+ mon = i
+ break
+ }
+ }
+ if mon == 0 {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ dt[OFFSET_MONTH] = mon
+ return offset + len(monthNameList[mon]), nil
+ }
+}
+
+func (MonthElement monthElement) format(dt []int) string {
+ value := dt[OFFSET_MONTH]
+
+ if MonthElement.OracleDateFormat.language == LANGUAGE_CN {
+ return strconv.FormatInt(int64(value), 10) + "月"
+ }
+
+ if MonthElement.upperCase {
+ return strings.ToUpper(monthNameList[value])
+ } else if MonthElement.lowerCase {
+ return strings.ToLower(monthNameList[value])
+ } else {
+ return monthNameList[value]
+ }
+
+}
+
+type monElement struct {
+ OracleDateFormat *oracleDateFormat
+ upperCase bool
+ lowerCase bool
+}
+
+var monNameList []string = []string{"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
+
+func (MonElement monElement) parse(str string, offset int, dt []int) (int, error) {
+
+ if MonElement.OracleDateFormat.language == LANGUAGE_CN {
+ index := strings.IndexRune(str[offset:], '月') + offset
+ if index == -1+offset {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+
+ mon, err := strconv.ParseInt(str[offset:index], 10, 32)
+ if err != nil {
+ return -1, err
+ }
+
+ if mon > 12 || mon < 1 {
+ return -1, ECGO_INVALID_DATETIME_VALUE.throw()
+ }
+ dt[OFFSET_MONTH] = int(mon)
+ return index + utf8.RuneLen('月'), nil
+ } else {
+ str = str[offset : offset+3]
+ mon := 0
+ for i := 1; i < len(monNameList); i++ {
+ if util.StringUtil.EqualsIgnoreCase(str, monNameList[i]) {
+ mon = i
+ break
+ }
+ }
+ if mon == 0 {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ dt[OFFSET_MONTH] = mon
+ return offset + 3, nil
+ }
+
+}
+
+func (MonElement monElement) format(dt []int) string {
+ value := dt[OFFSET_MONTH]
+ language := int(0)
+ if language == LANGUAGE_CN {
+ return strconv.FormatInt(int64(value), 10) + "月"
+ }
+
+ if MonElement.upperCase {
+ return strings.ToUpper(monNameList[value])
+ } else if MonElement.lowerCase {
+ return strings.ToLower(monNameList[value])
+ } else {
+ return monNameList[value]
+ }
+}
+
+type mmElement struct {
+ OracleDateFormat *oracleDateFormat
+}
+
+func (MMElement mmElement) parse(str string, offset int, dt []int) (int, error) {
+ strLen := 0
+ for i := offset; i < offset+2 && i < len(str); i++ {
+ if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
+ break
+ }
+ strLen++
+ }
+ str = str[offset : offset+strLen]
+ month, err := strconv.ParseInt(str, 10, 32)
+ if err != nil {
+ return -1, ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+
+ if month > 12 || month < 1 {
+ return -1, ECGO_INVALID_DATETIME_VALUE.throw()
+ }
+ dt[OFFSET_MONTH] = int(month)
+ return offset + strLen, nil
+}
+
+func (MMElement mmElement) format(dt []int) string {
+ return MMElement.OracleDateFormat.formatInt(dt[OFFSET_MONTH], 2)
+}
+
+type ddElement struct {
+ OracleDateFormat *oracleDateFormat
+}
+
+func (DDElement ddElement) parse(str string, offset int, dt []int) (int, error) {
+ strLen := 0
+ for i := offset; i < offset+2 && i < len(str); i++ {
+ if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
+ break
+ }
+ strLen++
+ }
+ str = str[offset : offset+strLen]
+ day, err := strconv.ParseInt(str, 10, 32)
+ if err != nil {
+ return -1, err
+ }
+
+ if day > 31 || day < 1 {
+ return -1, ECGO_INVALID_DATETIME_VALUE.throw()
+ }
+ dt[OFFSET_DAY] = int(day)
+ return offset + strLen, nil
+}
+
+func (DDElement ddElement) format(dt []int) string {
+ return DDElement.OracleDateFormat.formatInt(dt[OFFSET_DAY], 2)
+}
+
+type hh24Element struct {
+ OracleDateFormat *oracleDateFormat
+}
+
+func (HH24Element hh24Element) parse(str string, offset int, dt []int) (int, error) {
+ strLen := 0
+ for i := offset; i < offset+2 && i < len(str); i++ {
+ if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
+ break
+ }
+ strLen++
+ }
+ str = str[offset : offset+strLen]
+ hour, err := strconv.ParseInt(str, 10, 32)
+ if err != nil {
+ return -1, err
+ }
+
+ if hour > 23 || hour < 0 {
+ return -1, ECGO_INVALID_DATETIME_VALUE.throw()
+ }
+ dt[OFFSET_HOUR] = int(hour) // 0-23
+ return offset + strLen, nil
+}
+
+func (HH24Element hh24Element) format(dt []int) string {
+ return HH24Element.OracleDateFormat.formatInt(dt[OFFSET_HOUR], 2) // 0-23
+}
+
+type hh12Element struct {
+ OracleDateFormat *oracleDateFormat
+}
+
+func (HH12Element hh12Element) parse(str string, offset int, dt []int) (int, error) {
+ strLen := 0
+ for i := offset; i < offset+2 && i < len(str); i++ {
+ if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
+ break
+ }
+ strLen++
+ }
+ str = str[offset : offset+strLen]
+ hour, err := strconv.ParseInt(str, 10, 32)
+ if err != nil {
+ return -1, err
+ }
+
+ if hour > 12 || hour < 1 {
+ return -1, ECGO_INVALID_DATETIME_VALUE.throw()
+ }
+ dt[OFFSET_HOUR] = int(hour)
+ return offset + strLen, nil
+}
+
+func (HH12Element hh12Element) format(dt []int) string {
+ var ret string
+ value := dt[OFFSET_HOUR]
+ if value > 12 || value == 0 {
+ ret = HH12Element.OracleDateFormat.formatInt(int(math.Abs(float64(value-12))), 2) // 1-12
+ } else {
+ ret = HH12Element.OracleDateFormat.formatInt(value, 2)
+ }
+ return ret
+}
+
+type miElement struct {
+ OracleDateFormat *oracleDateFormat
+}
+
+func (MIElement miElement) parse(str string, offset int, dt []int) (int, error) {
+ strLen := 0
+ for i := offset; i < offset+2 && i < len(str); i++ {
+ if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
+ break
+ }
+ strLen++
+ }
+ str = str[offset : offset+strLen]
+ minute, err := strconv.ParseInt(str, 10, 32)
+ if err != nil {
+ return -1, err
+ }
+
+ if minute > 59 || minute < 0 {
+ return -1, ECGO_INVALID_DATETIME_VALUE.throw()
+ }
+ dt[OFFSET_MINUTE] = int(minute) // 0-59
+ return offset + strLen, nil
+}
+
+func (MIElement miElement) format(dt []int) string {
+ return MIElement.OracleDateFormat.formatInt(dt[OFFSET_MINUTE], 2) // 0-59
+}
+
+type ssElement struct {
+ OracleDateFormat *oracleDateFormat
+}
+
+func (SSElement ssElement) parse(str string, offset int, dt []int) (int, error) {
+ strLen := 0
+ for i := offset; i < offset+2 && i < len(str); i++ {
+ if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
+ break
+ }
+ strLen++
+ }
+ str = str[offset : offset+strLen]
+ second, err := strconv.ParseInt(str, 10, 32)
+ if err != nil {
+ return -1, err
+ }
+
+ if second > 59 || second < 0 {
+ return -1, ECGO_INVALID_DATETIME_VALUE.throw()
+ }
+ dt[OFFSET_SECOND] = int(second) // 0-59
+ return offset + strLen, nil
+}
+
+func (SSElement ssElement) format(dt []int) string {
+ return SSElement.OracleDateFormat.formatInt(dt[OFFSET_SECOND], 2) // 0-59
+}
+
+type fElement struct {
+ OracleDateFormat *oracleDateFormat
+ len int
+}
+
+func (FElement fElement) parse(str string, offset int, dt []int) (int, error) {
+ strLen := 0
+ for i := offset; i < offset+FElement.len && i < len(str); i++ {
+ if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
+ break
+ }
+ strLen++
+ }
+ str = str[offset : offset+strLen]
+ ms, err := strconv.ParseInt(str, 10, 32)
+ if err != nil {
+ return -1, err
+ }
+
+ if strLen < 6 {
+ ms *= int64(math.Pow10(6 - strLen))
+ } else {
+ ms /= int64(math.Pow10(strLen - 6))
+ }
+
+ dt[OFFSET_MILLISECOND] = int(ms)
+ return offset + strLen, nil
+}
+
+func (FElement fElement) format(dt []int) string {
+ return FElement.OracleDateFormat.formatMilliSecond(dt[OFFSET_MILLISECOND], FElement.len)
+}
+
+type tzhElement struct {
+ OracleDateFormat *oracleDateFormat
+}
+
+func (TZHElement tzhElement) parse(str string, offset int, dt []int) (int, error) {
+ if str[offset] == '+' {
+ offset += 1
+ } else if str[offset] == '-' {
+ offset += 1
+ TZHElement.OracleDateFormat.TZNegative = true
+ }
+
+ strLen := 0
+ for i := offset; i < offset+2 && i < len(str); i++ {
+ if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
+ break
+ }
+ strLen++
+ }
+ str = str[offset : offset+strLen]
+
+ tzh, err := strconv.ParseInt(str, 10, 32)
+ if err != nil {
+ return -1, err
+ }
+
+ if tzh > 23 || tzh < 0 {
+ return -1, ECGO_INVALID_DATETIME_VALUE.throw()
+ }
+
+ tzh *= 60
+ if dt[OFFSET_TIMEZONE] == int(INVALID_VALUE) {
+ dt[OFFSET_TIMEZONE] = int(tzh)
+ } else {
+ dt[OFFSET_TIMEZONE] += int(tzh)
+ }
+
+ return offset + strLen, nil
+}
+
+func (TZHElement tzhElement) format(dt []int) string {
+ var value int
+ if dt[OFFSET_TIMEZONE] != int(INVALID_VALUE) {
+ value = int(math.Abs(float64(dt[OFFSET_TIMEZONE]))) / 60
+ } else {
+ value = 0
+ }
+
+ return TZHElement.OracleDateFormat.formatInt(value, 2)
+}
+
+type tzmElement struct {
+ OracleDateFormat *oracleDateFormat
+}
+
+func (TZMElement tzmElement) parse(str string, offset int, dt []int) (int, error) {
+ if str[offset] == '+' {
+ offset += 1
+ } else if str[offset] == '-' {
+ offset += 1
+ TZMElement.OracleDateFormat.TZNegative = true
+ }
+
+ strLen := 0
+ for i := offset; i < offset+2 && i < len(str); i++ {
+ if !unicode.IsLetter(rune(str[i])) && !unicode.IsDigit(rune(str[i])) {
+ break
+ }
+ strLen++
+ }
+ str = str[offset : offset+strLen]
+
+ tzm, err := strconv.ParseInt(str, 10, 32)
+ if err != nil {
+ return -1, err
+ }
+ if tzm > 59 || tzm < 0 {
+ return -1, ECGO_INVALID_DATETIME_VALUE.throw()
+ }
+
+ if dt[OFFSET_TIMEZONE] == INVALID_VALUE {
+ dt[OFFSET_TIMEZONE] = int(tzm)
+ } else {
+ dt[OFFSET_TIMEZONE] += int(tzm)
+ }
+ return offset + strLen, nil
+}
+
+func (TZMElement tzmElement) format(dt []int) string {
+ var value int
+ if dt[OFFSET_TIMEZONE] != int(INVALID_VALUE) {
+ value = int(math.Abs(float64(dt[OFFSET_TIMEZONE]))) % 60
+ } else {
+ value = 0
+ }
+
+ return TZMElement.OracleDateFormat.formatInt(value, 2)
+}
+
+type amElement struct {
+ OracleDateFormat *oracleDateFormat
+}
+
+func (AMElement amElement) parse(str string, offset int, dt []int) (int, error) {
+ runeStr := ([]rune(str))[offset : offset+2]
+
+ if AMElement.OracleDateFormat.language == LANGUAGE_CN {
+ if util.StringUtil.EqualsIgnoreCase("下午", string(runeStr)) {
+ AMElement.OracleDateFormat.PM = true
+ return offset + utf8.RuneLen('下') + utf8.RuneLen('午'), nil
+ } else {
+ AMElement.OracleDateFormat.PM = false
+ return offset + utf8.RuneLen('上') + utf8.RuneLen('午'), nil
+ }
+
+ } else if util.StringUtil.EqualsIgnoreCase("PM", string(runeStr)) {
+ AMElement.OracleDateFormat.PM = true
+ } else {
+ AMElement.OracleDateFormat.PM = false
+ }
+
+ return offset + 2, nil
+}
+
+func (AMElement amElement) format(dt []int) string {
+ hour := dt[OFFSET_HOUR]
+ language := int(0)
+ if language == LANGUAGE_CN {
+ if hour > 12 {
+ return "下午"
+ } else {
+ return "上午"
+ }
+ }
+
+ if hour > 12 {
+ return "PM"
+ } else {
+ return "AM"
+ }
+}
+
+/**
+ * 将int值格式化成指定长度,长度不足前面补0,长度超过的取末尾指定长度
+ */
+func (OracleDateFormat *oracleDateFormat) formatInt(value int, len int) string {
+ pow := int(math.Pow10(len))
+ if value >= pow {
+ value %= pow
+ }
+ value += pow
+ return strconv.FormatInt(int64(value), 10)[1:]
+}
+
+/**
+ * 格式化毫秒值
+ * @param ms
+ * @param len <= 6
+ */
+func (OracleDateFormat *oracleDateFormat) formatMilliSecond(ms int, len int) string {
+ var ret string
+ if ms < 10 {
+ ret = "00000" + strconv.FormatInt(int64(ms), 10)
+ } else if ms < 100 {
+ ret = "0000" + strconv.FormatInt(int64(ms), 10)
+ } else if ms < 1000 {
+ ret = "000" + strconv.FormatInt(int64(ms), 10)
+ } else if ms < 10000 {
+ ret = "00" + strconv.FormatInt(int64(ms), 10)
+ } else if ms < 100000 {
+ ret = "0" + strconv.FormatInt(int64(ms), 10)
+ } else {
+ ret = strconv.FormatInt(int64(ms), 10)
+ }
+
+ if len < 6 {
+ ret = ret[:len]
+ }
+ return ret
+}
+
+func getFormat() *oracleDateFormat {
+ format := new(oracleDateFormat)
+ format.PM = false
+ format.TZNegative = false
+ format.YearElement = yearElement{format, 4}
+ format.MonthElement = monthElement{format, false, false}
+ format.MonElement = monElement{format, false, false}
+ format.MMElement = mmElement{format}
+ format.DDElement = ddElement{format}
+ format.HH24Element = hh24Element{format}
+ format.HH12Element = hh12Element{format}
+ format.MIElement = miElement{format}
+ format.SSElement = ssElement{format}
+ format.FElement = fElement{format, 6}
+ format.TZHElement = tzhElement{format}
+ format.TZMElement = tzmElement{format}
+ format.AMElement = amElement{format}
+
+ return format
+}
+
+func (OracleDateFormat *oracleDateFormat) parse(str string) (ret []int, err error) {
+ defer func() {
+ if p := recover(); p != nil {
+ err = ECGO_INVALID_DATETIME_FORMAT.throw()
+ }
+ }()
+ OracleDateFormat.TZNegative = false
+ OracleDateFormat.PM = false
+ dt := make([]int, DT_LEN)
+ // oracle默认年月日为 当前时间
+ today := time.Now()
+ dt[OFFSET_YEAR] = today.Year()
+ dt[OFFSET_MONTH] = int(today.Month())
+ dt[OFFSET_DAY] = today.Day()
+ dt[OFFSET_TIMEZONE] = INVALID_VALUE
+ offset := 0
+ str = strings.TrimSpace(str)
+ for _, obj := range OracleDateFormat.FormatElementList {
+ // 跳过空格
+ for str[offset] == ' ' && fmt.Sprintf("%+v", obj) != " " {
+ offset++
+ }
+ if e, ok := obj.(element); ok {
+ offset, err = e.parse(str, offset, dt)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ offset += len(obj.(string))
+ }
+ }
+ if offset < len(str) {
+ //[6103]:文字与格式字符串不匹配.
+ return nil, ECGO_INVALID_DATETIME_VALUE.throw()
+ }
+
+ // 12小时制时间转换
+ if OracleDateFormat.PM {
+ dt[OFFSET_HOUR] = (dt[OFFSET_HOUR] + 12) % 24
+ }
+
+ // 时区符号保留
+ if OracleDateFormat.TZNegative {
+ dt[OFFSET_TIMEZONE] = -dt[OFFSET_TIMEZONE]
+ }
+
+ // check day
+ if dt[OFFSET_DAY] > getDaysOfMonth(dt[OFFSET_YEAR], dt[OFFSET_MONTH]) || dt[OFFSET_DAY] < 1 {
+ return nil, ECGO_INVALID_DATETIME_VALUE.throw()
+ }
+ // check timezone 兼容oracle
+ if dt[OFFSET_TIMEZONE] != INVALID_VALUE && (dt[OFFSET_TIMEZONE] > 14*60 || dt[OFFSET_TIMEZONE] <= -13*60) {
+ return nil, ECGO_INVALID_DATETIME_VALUE.throw()
+ }
+ return dt, nil
+}
+
+func parse(str string, pattern string, language int) ([]int, error) {
+ f := getFormat()
+ f.setPattern(pattern)
+ f.language = language
+ return f.parse(str)
+}
+
+func (OracleDateFormat *oracleDateFormat) setPattern(pattern string) {
+ if pattern != OracleDateFormat.pattern {
+ OracleDateFormat.pattern = pattern
+ OracleDateFormat.FormatElementList = OracleDateFormat.FormatElementList[:0]
+ OracleDateFormat.analysePattern(pattern)
+ }
+}
+
+func format(dt []int, pattern string, language int) string {
+ f := getFormat()
+ f.setPattern(pattern)
+ f.language = language
+ ret := f.format(dt)
+ return ret
+}
+
+func (OracleDateFormat *oracleDateFormat) format(dt []int) string {
+ sf := strings.Builder{}
+ tzStart := false
+ for _, obj := range OracleDateFormat.FormatElementList {
+ _, ok1 := obj.(tzhElement)
+ _, ok2 := obj.(tzmElement)
+ if !tzStart && (ok1 || ok2) {
+ tzStart = true
+ if dt[OFFSET_TIMEZONE] < 0 {
+ sf.WriteString("-")
+ } else {
+ sf.WriteString("+")
+ }
+ }
+
+ if e, ok := obj.(element); ok {
+ sf.WriteString(e.format(dt))
+ } else {
+ sf.WriteString(obj.(string))
+ }
+ }
+ return sf.String()
+}
+
+/**
+ * 解析格式串
+ */
+func (OracleDateFormat *oracleDateFormat) analysePattern(pattern string) ([]interface{}, error) {
+
+ // 按分隔符split
+ pattern = strings.TrimSpace(pattern)
+ l := len(pattern)
+ var splitPatterns []string
+ starti := 0
+ var curChar rune
+ for i := 0; i < l; i++ {
+ curChar = rune(pattern[i])
+ if !unicode.IsDigit(curChar) && !unicode.IsLetter(curChar) {
+ if i > starti {
+ splitPatterns = append(splitPatterns, pattern[starti:i])
+ }
+
+ splitPatterns = append(splitPatterns, string(curChar))
+ starti = i + 1
+ } else if i == l-1 {
+ splitPatterns = append(splitPatterns, pattern[starti:i+1])
+ }
+ }
+
+ // 每个串按照从完整串,然后依次去掉一个末尾字符 来进行尝试规约
+ for _, subPattern := range splitPatterns {
+ if len(subPattern) != 1 || unicode.IsDigit(rune(subPattern[0])) || unicode.IsLetter(rune(subPattern[0])) {
+ fmtWord := subPattern
+ for subPattern != "" {
+ i := len(subPattern)
+ for ; i > 0; i-- {
+ fmtWord = subPattern[0:i]
+ element, err := OracleDateFormat.getFormatElement(fmtWord)
+ if err != nil {
+ return nil, err
+ }
+ if element != nil {
+ // 忽略时区前面的+-号
+ if element == OracleDateFormat.TZHElement || element == OracleDateFormat.TZMElement {
+ var lastFormatElement string = OracleDateFormat.FormatElementList[len(OracleDateFormat.FormatElementList)-1].(string)
+ if util.StringUtil.Equals("+", lastFormatElement) || util.StringUtil.Equals("-", lastFormatElement) {
+ OracleDateFormat.FormatElementList = OracleDateFormat.FormatElementList[:len(OracleDateFormat.FormatElementList)-2]
+ }
+ }
+ OracleDateFormat.FormatElementList = append(OracleDateFormat.FormatElementList, element)
+ if i == len(subPattern) {
+ subPattern = ""
+ } else {
+ subPattern = subPattern[i:len(subPattern)]
+ }
+ break
+ }
+ }
+
+ if i == 0 {
+ // 非标识符串
+ OracleDateFormat.FormatElementList = append(OracleDateFormat.FormatElementList, subPattern)
+ break
+ }
+ }
+
+ } else {
+ OracleDateFormat.FormatElementList = append(OracleDateFormat.FormatElementList, subPattern)
+ }
+ }
+ return OracleDateFormat.FormatElementList, nil
+}
+
+func (OracleDateFormat *oracleDateFormat) getFormatElement(word string) (element, error) {
+ if util.StringUtil.EqualsIgnoreCase("HH", word) || util.StringUtil.EqualsIgnoreCase("HH12", word) {
+ return OracleDateFormat.HH12Element, nil
+ } else if util.StringUtil.EqualsIgnoreCase("HH24", word) {
+ return OracleDateFormat.HH24Element, nil
+ } else if util.StringUtil.EqualsIgnoreCase("MI", word) {
+ return OracleDateFormat.MIElement, nil
+ } else if util.StringUtil.EqualsIgnoreCase("SS", word) {
+ return OracleDateFormat.SSElement, nil
+ } else if util.StringUtil.EqualsIgnoreCase("AM", word) || util.StringUtil.EqualsIgnoreCase("A.M.", word) || util.StringUtil.EqualsIgnoreCase("PM", word) || util.StringUtil.EqualsIgnoreCase("P.M.", word) {
+ return OracleDateFormat.AMElement, nil
+ } else if util.StringUtil.Equals("MONTH", word) {
+ OracleDateFormat.MonthElement.upperCase = true
+ OracleDateFormat.MonthElement.lowerCase = false
+ return OracleDateFormat.MonthElement, nil
+ } else if util.StringUtil.Equals("month", word) {
+ OracleDateFormat.MonthElement.upperCase = false
+ OracleDateFormat.MonthElement.lowerCase = true
+ return OracleDateFormat.MonthElement, nil
+ } else if util.StringUtil.EqualsIgnoreCase("Month", word) {
+ OracleDateFormat.MonthElement.upperCase = false
+ OracleDateFormat.MonthElement.lowerCase = false
+ return OracleDateFormat.MonthElement, nil
+ } else if util.StringUtil.Equals("MON", word) {
+ OracleDateFormat.MonElement.upperCase = true
+ OracleDateFormat.MonElement.lowerCase = false
+ return OracleDateFormat.MonElement, nil
+ } else if util.StringUtil.Equals("mon", word) {
+ OracleDateFormat.MonElement.upperCase = false
+ OracleDateFormat.MonElement.lowerCase = true
+ return OracleDateFormat.MonElement, nil
+ } else if util.StringUtil.EqualsIgnoreCase("Mon", word) {
+ OracleDateFormat.MonElement.upperCase = false
+ OracleDateFormat.MonElement.lowerCase = false
+ return OracleDateFormat.MonElement, nil
+ } else if util.StringUtil.EqualsIgnoreCase("MM", word) {
+ return OracleDateFormat.MMElement, nil
+ } else if util.StringUtil.EqualsIgnoreCase("DD", word) {
+ return OracleDateFormat.DDElement, nil
+ } else if util.StringUtil.EqualsIgnoreCase("TZH", word) {
+ return OracleDateFormat.TZHElement, nil
+ } else if util.StringUtil.EqualsIgnoreCase("TZM", word) {
+ return OracleDateFormat.TZMElement, nil
+ } else if strings.Index(word, "Y") == 0 || strings.Index(word, "y") == 0 {
+ OracleDateFormat.YearElement.len = len(word)
+ return OracleDateFormat.YearElement, nil
+ } else if strings.Index(word, "F") == 0 || strings.Index(word, "f") == 0 {
+
+ word = strings.ToUpper(word)
+ numIndex := strings.LastIndex(word, "F") + 1
+ var count int64
+ var err error
+ if numIndex < len(word) {
+ count, err = strconv.ParseInt(word[numIndex:len(word)], 10, 32)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ count = 9
+ }
+
+ OracleDateFormat.FElement.len = int(count)
+ return OracleDateFormat.FElement, nil
+ }
+
+ return nil, nil
+}
diff --git a/dmr/zv.go b/dmr/zv.go
new file mode 100644
index 0000000..9597cde
--- /dev/null
+++ b/dmr/zv.go
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import (
+ "strconv"
+ "strings"
+)
+
+type Properties struct {
+ innerProps map[string]string
+}
+
+func NewProperties() *Properties {
+ p := Properties{
+ innerProps: make(map[string]string, 50),
+ }
+ return &p
+}
+
+func (g *Properties) SetProperties(p *Properties) {
+ if p == nil {
+ return
+ }
+ for k, v := range p.innerProps {
+ g.Set(strings.ToLower(k), v)
+ }
+}
+
+func (g *Properties) Len() int {
+ return len(g.innerProps)
+}
+
+func (g *Properties) IsNil() bool {
+ return g == nil || g.innerProps == nil
+}
+
+func (g *Properties) GetString(key, def string) string {
+ v, ok := g.innerProps[strings.ToLower(key)]
+
+ if !ok || v == "" {
+ return def
+ }
+ return v
+}
+
+func (g *Properties) GetInt(key string, def int, min int, max int) int {
+ value, ok := g.innerProps[strings.ToLower(key)]
+ if !ok || value == "" {
+ return def
+ }
+
+ i, err := strconv.Atoi(value)
+ if err != nil {
+ return def
+ }
+
+ if i > max || i < min {
+ return def
+ }
+ return i
+}
+
+func (g *Properties) GetBool(key string, def bool) bool {
+ value, ok := g.innerProps[strings.ToLower(key)]
+ if !ok || value == "" {
+ return def
+ }
+ b, err := strconv.ParseBool(value)
+ if err != nil {
+ return def
+ }
+ return b
+}
+
+func (g *Properties) GetTrimString(key string, def string) string {
+ value, ok := g.innerProps[strings.ToLower(key)]
+ if !ok || value == "" {
+ return def
+ } else {
+ return strings.TrimSpace(value)
+ }
+}
+
+func (g *Properties) GetStringArray(key string, def []string) []string {
+ value, ok := g.innerProps[strings.ToLower(key)]
+ if ok || value != "" {
+ array := strings.Split(value, ",")
+ if len(array) > 0 {
+ return array
+ }
+ }
+ return def
+}
+
+//func (g *Properties) GetBool(key string) bool {
+// i, _ := strconv.ParseBool(g.innerProps[key])
+// return i
+//}
+
+func (g *Properties) Set(key, value string) {
+ g.innerProps[strings.ToLower(key)] = value
+}
+
+func (g *Properties) SetIfNotExist(key, value string) {
+ if _, ok := g.innerProps[strings.ToLower(key)]; !ok {
+ g.Set(key, value)
+ }
+}
+
+// 如果p有g没有的键值对,添加进g中
+func (g *Properties) SetDiffProperties(p *Properties) {
+ if p == nil {
+ return
+ }
+ for k, v := range p.innerProps {
+ if _, ok := g.innerProps[strings.ToLower(k)]; !ok {
+ g.innerProps[strings.ToLower(k)] = v
+ }
+ }
+}
diff --git a/dmr/zw.go b/dmr/zw.go
new file mode 100644
index 0000000..8048ed5
--- /dev/null
+++ b/dmr/zw.go
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import (
+ "math/rand"
+ "strconv"
+ "time"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+var rwMap = make(map[string]*rwCounter)
+
+type rwCounter struct {
+ ntrx_primary int64
+
+ ntrx_total int64
+
+ primaryPercent float64
+
+ standbyPercent float64
+
+ standbyNTrxMap map[string]int64
+
+ standbyIdMap map[string]int32
+
+ standbyCount int32
+
+ flag []int32
+
+ increments []int32
+}
+
+func newRWCounter(primaryPercent int32, standbyCount int32) *rwCounter {
+ rwc := new(rwCounter)
+ rwc.standbyNTrxMap = make(map[string]int64)
+ rwc.standbyIdMap = make(map[string]int32)
+ rwc.reset(primaryPercent, standbyCount)
+ return rwc
+}
+
+func (rwc *rwCounter) reset(primaryPercent int32, standbyCount int32) {
+ rwc.ntrx_primary = 0
+ rwc.ntrx_total = 0
+ rwc.standbyCount = standbyCount
+ rwc.increments = make([]int32, standbyCount+1)
+ rwc.flag = make([]int32, standbyCount+1)
+ var gcd = util.GCD(primaryPercent*standbyCount, 100-primaryPercent)
+ rwc.increments[0] = primaryPercent * standbyCount / gcd
+ for i, tmp := 1, (100-primaryPercent)/gcd; i < len(rwc.increments); i++ {
+ rwc.increments[i] = tmp
+ }
+ copy(rwc.flag, rwc.increments)
+
+ if standbyCount > 0 {
+ rwc.primaryPercent = float64(primaryPercent) / 100.0
+ rwc.standbyPercent = float64(100-primaryPercent) / 100.0 / float64(standbyCount)
+ } else {
+ rwc.primaryPercent = 1
+ rwc.standbyPercent = 0
+ }
+}
+
+// 连接创建成功后调用,需要服务器返回standbyCount
+func getRwCounterInstance(conn *DmConnection, standbyCount int32) *rwCounter {
+ key := conn.dmConnector.host + "_" + strconv.Itoa(int(conn.dmConnector.port)) + "_" + strconv.Itoa(int(conn.dmConnector.rwPercent))
+
+ rwc, ok := rwMap[key]
+ if !ok {
+ rwc = newRWCounter(conn.dmConnector.rwPercent, standbyCount)
+ rwMap[key] = rwc
+ } else if rwc.standbyCount != standbyCount {
+ rwc.reset(conn.dmConnector.rwPercent, standbyCount)
+ }
+ return rwc
+}
+
+/**
+* @return 主机;
+ */
+func (rwc *rwCounter) countPrimary() RWSiteEnum {
+ rwc.adjustNtrx()
+ rwc.increasePrimaryNtrx()
+ return PRIMARY
+}
+
+/**
+* @param dest 主机; 备机; any;
+* @return 主机; 备机
+ */
+func (rwc *rwCounter) count(dest RWSiteEnum, standby *DmConnection) RWSiteEnum {
+ rwc.adjustNtrx()
+ switch dest {
+ case ANYSITE:
+ {
+ if rwc.primaryPercent == 1 || (rwc.flag[0] > rwc.getStandbyFlag(standby) && rwc.flag[0] > util.Sum(rwc.flag[1:])) {
+ rwc.increasePrimaryNtrx()
+ dest = PRIMARY
+ } else {
+ rwc.increaseStandbyNtrx(standby)
+ dest = STANDBY
+ }
+ }
+ case STANDBY:
+ {
+ rwc.increaseStandbyNtrx(standby)
+ }
+ case PRIMARY:
+ {
+ rwc.increasePrimaryNtrx()
+ }
+ }
+ return dest
+}
+
+/**
+* 防止ntrx超出有效范围,等比调整
+ */
+func (rwc *rwCounter) adjustNtrx() {
+ if rwc.ntrx_total >= INT64_MAX {
+ var min int64
+ var i = 0
+ for _, num := range rwc.standbyNTrxMap {
+ if i == 0 || num < min {
+ min = num
+ }
+ i++
+ }
+ if rwc.ntrx_primary < min {
+ min = rwc.ntrx_primary
+ }
+ rwc.ntrx_primary /= min
+ rwc.ntrx_total /= min
+ for k, v := range rwc.standbyNTrxMap {
+ rwc.standbyNTrxMap[k] = v / min
+ }
+ }
+
+ if rwc.flag[0] <= 0 && util.Sum(rwc.flag[1:]) <= 0 {
+ // 如果主库事务数以及所有备库事务数的总和 都 <= 0, 重置事务计数,给每个库的事务计数加上初始计数值
+ for i := 0; i < len(rwc.flag); i++ {
+ rwc.flag[i] += rwc.increments[i]
+ }
+ }
+}
+
+func (rwc *rwCounter) increasePrimaryNtrx() {
+ rwc.ntrx_primary++
+ rwc.flag[0]--
+ rwc.ntrx_total++
+}
+
+//func (rwc *rwCounter) getStandbyNtrx(standby *DmConnection) int64 {
+// key := standby.dmConnector.host + ":" + strconv.Itoa(int(standby.dmConnector.port))
+// ret, ok := rwc.standbyNTrxMap[key]
+// if !ok {
+// ret = 0
+// }
+//
+// return ret
+//}
+
+func (rwc *rwCounter) getStandbyId(standby *DmConnection) int32 {
+ key := standby.dmConnector.host + ":" + strconv.Itoa(int(standby.dmConnector.port))
+ sid, ok := rwc.standbyIdMap[key]
+ if !ok {
+ sid = int32(len(rwc.standbyIdMap) + 1) // 下标0是primary
+ if sid > rwc.standbyCount {
+ // 不在有效备库中
+ return -1
+ }
+ rwc.standbyIdMap[key] = sid
+ }
+ return sid
+}
+
+func (rwc *rwCounter) getStandbyFlag(standby *DmConnection) int32 {
+ sid := rwc.getStandbyId(standby)
+ if sid > 0 && sid < int32(len(rwc.flag)) {
+ // 保证备库有效
+ return rwc.flag[sid]
+ }
+ return 0
+}
+
+func (rwc *rwCounter) increaseStandbyNtrx(standby *DmConnection) {
+ key := standby.dmConnector.host + ":" + strconv.Itoa(int(standby.dmConnector.port))
+ ret, ok := rwc.standbyNTrxMap[key]
+ if ok {
+ ret += 1
+ } else {
+ ret = 1
+ }
+ rwc.standbyNTrxMap[key] = ret
+ sid, ok := rwc.standbyIdMap[key]
+ if !ok {
+ sid = int32(len(rwc.standbyIdMap) + 1) // 下标0是primary
+ rwc.standbyIdMap[key] = sid
+ }
+ rwc.flag[sid]--
+ rwc.ntrx_total++
+}
+
+func (rwc *rwCounter) random(rowCount int32) int32 {
+ rand.Seed(time.Now().UnixNano())
+ if rowCount > rwc.standbyCount {
+ return rand.Int31n(rwc.standbyCount)
+ } else {
+ return rand.Int31n(rowCount)
+ }
+}
+
+func (rwc *rwCounter) String() string {
+ return "PERCENT(P/S) : " + strconv.FormatFloat(rwc.primaryPercent, 'f', -1, 64) + "/" + strconv.FormatFloat(rwc.standbyPercent, 'f', -1, 64) + "\nNTRX_PRIMARY : " +
+ strconv.FormatInt(rwc.ntrx_primary, 10) + "\nNTRX_TOTAL : " + strconv.FormatInt(rwc.ntrx_total, 10) + "\nNTRX_STANDBY : "
+}
diff --git a/dmr/zx.go b/dmr/zx.go
new file mode 100644
index 0000000..afe0abe
--- /dev/null
+++ b/dmr/zx.go
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "context"
+ "database/sql"
+ "database/sql/driver"
+ "errors"
+ "io"
+ "regexp"
+ "strings"
+ "time"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+const (
+ SQL_SELECT_STANDBY = "select distinct mailIni.inst_name, mailIni.INST_IP, mailIni.INST_PORT, archIni.arch_status " +
+ "from v$arch_status archIni " +
+ "left join (select * from V$DM_MAL_INI) mailIni on archIni.arch_dest = mailIni.inst_name " +
+ "left join V$MAL_LINK_STATUS on CTL_LINK_STATUS = 'CONNECTED' AND DATA_LINK_STATUS = 'CONNECTED' " +
+ "where archIni.arch_type in ('TIMELY', 'REALTIME') AND archIni.arch_status = 'VALID'"
+
+ SQL_SELECT_STANDBY2 = "select distinct " +
+ "mailIni.mal_inst_name, mailIni.mal_INST_HOST, mailIni.mal_INST_PORT, archIni.arch_status " +
+ "from v$arch_status archIni " + "left join (select * from V$DM_MAL_INI) mailIni " +
+ "on archIni.arch_dest = mailIni.mal_inst_name " + "left join V$MAL_LINK_STATUS " +
+ "on CTL_LINK_STATUS = 'CONNECTED' AND DATA_LINK_STATUS = 'CONNECTED' " +
+ "where archIni.arch_type in ('TIMELY', 'REALTIME') AND archIni.arch_status = 'VALID'"
+)
+
+type rwUtil struct {
+}
+
+var RWUtil = rwUtil{}
+
+func (RWUtil rwUtil) connect(c *DmConnector, ctx context.Context) (*DmConnection, error) {
+ c.loginMode = LOGIN_MODE_PRIMARY_ONLY
+ connection, err := c.connect(ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ connection.rwInfo.rwCounter = getRwCounterInstance(connection, connection.StandbyCount)
+ err = RWUtil.connectStandby(connection)
+
+ return connection, err
+}
+
+func (RWUtil rwUtil) reconnect(connection *DmConnection) error {
+ if connection.rwInfo == nil {
+ return nil
+ }
+
+ RWUtil.removeStandby(connection)
+
+ err := connection.reconnect()
+ if err != nil {
+ return err
+ }
+ connection.rwInfo.cleanup()
+ connection.rwInfo.rwCounter = getRwCounterInstance(connection, connection.StandbyCount)
+
+ err = RWUtil.connectStandby(connection)
+
+ return err
+}
+
+func (RWUtil rwUtil) recoverStandby(connection *DmConnection) error {
+ if connection.closed.IsSet() || RWUtil.isStandbyAlive(connection) {
+ return nil
+ }
+
+ ts := time.Now().UnixNano() / 1000000
+
+ freq := int64(connection.dmConnector.rwStandbyRecoverTime)
+ if freq <= 0 || ts-connection.rwInfo.tryRecoverTs < freq {
+ return nil
+ }
+
+ err := RWUtil.connectStandby(connection)
+ connection.rwInfo.tryRecoverTs = ts
+
+ return err
+}
+
+func (RWUtil rwUtil) connectStandby(connection *DmConnection) error {
+ var err error
+ db, err := RWUtil.chooseValidStandby(connection)
+ if err != nil {
+ return err
+ }
+ if db == nil {
+ return nil
+ }
+
+ standbyConnectorValue := *connection.dmConnector
+ standbyConnector := &standbyConnectorValue
+ standbyConnector.host = db.host
+ standbyConnector.port = db.port
+ standbyConnector.rwStandby = true
+ standbyConnector.group = nil
+ standbyConnector.loginMode = LOGIN_MODE_STANDBY_ONLY
+ standbyConnector.switchTimes = 0
+ connection.rwInfo.connStandby, err = standbyConnector.connectSingle(context.Background())
+ if err != nil {
+ return err
+ }
+
+ if connection.rwInfo.connStandby.SvrMode != SERVER_MODE_STANDBY || connection.rwInfo.connStandby.SvrStat != SERVER_STATUS_OPEN {
+ RWUtil.removeStandby(connection)
+ }
+ return nil
+}
+
+func (RWUtil rwUtil) chooseValidStandby(connection *DmConnection) (*ep, error) {
+ stmt, rs, err := connection.driverQuery(SQL_SELECT_STANDBY2)
+ if err != nil {
+ stmt, rs, err = connection.driverQuery(SQL_SELECT_STANDBY)
+ }
+ defer func() {
+ if rs != nil {
+ rs.close()
+ }
+ if stmt != nil {
+ stmt.close()
+ }
+ }()
+ if err == nil {
+ count := int32(rs.CurrentRows.getRowCount())
+ if count > 0 {
+ connection.rwInfo.rwCounter = getRwCounterInstance(connection, count)
+ i := int32(0)
+ rowIndex := connection.rwInfo.rwCounter.random(count)
+ dest := make([]driver.Value, 3)
+ for err := rs.next(dest); err != io.EOF; err = rs.next(dest) {
+ if i == rowIndex {
+ ep := newEP(dest[1].(string), dest[2].(int32))
+ return ep, nil
+ }
+ i++
+ }
+ }
+ }
+ if err != nil {
+ return nil, errors.New("choose valid standby error!" + err.Error())
+ }
+ return nil, nil
+}
+
+func (RWUtil rwUtil) afterExceptionOnStandby(connection *DmConnection, e error) {
+ if e.(*DmError).ErrCode == ECGO_COMMUNITION_ERROR.ErrCode {
+ RWUtil.removeStandby(connection)
+ }
+}
+
+func (RWUtil rwUtil) removeStandby(connection *DmConnection) {
+ if connection.rwInfo.connStandby != nil {
+ connection.rwInfo.connStandby.close()
+ connection.rwInfo.connStandby = nil
+ }
+}
+
+func (RWUtil rwUtil) isCreateStandbyStmt(stmt *DmStatement) bool {
+ return stmt != nil && stmt.rwInfo.readOnly && RWUtil.isStandbyAlive(stmt.dmConn)
+}
+
+func (RWUtil rwUtil) executeByConn(conn *DmConnection, query string, execute1 func() (interface{}, error), execute2 func(otherConn *DmConnection) (interface{}, error)) (interface{}, error) {
+
+ if err := RWUtil.recoverStandby(conn); err != nil {
+ return nil, err
+ }
+ RWUtil.distributeSqlByConn(conn, query)
+
+ turnToPrimary := false
+
+ ret, err := execute1()
+ if err != nil {
+ if conn.rwInfo.connCurrent == conn.rwInfo.connStandby {
+
+ RWUtil.afterExceptionOnStandby(conn, err)
+ turnToPrimary = true
+ } else {
+
+ return nil, err
+ }
+ }
+
+ curConn := conn.rwInfo.connCurrent
+ var otherConn *DmConnection
+ if curConn != conn {
+ otherConn = conn
+ } else {
+ otherConn = conn.rwInfo.connStandby
+ }
+
+ switch curConn.lastExecInfo.retSqlType {
+ case Dm_build_691, Dm_build_692, Dm_build_696, Dm_build_703, Dm_build_702, Dm_build_694:
+ {
+
+ if otherConn != nil {
+ execute2(otherConn)
+ }
+ }
+ case Dm_build_701:
+ {
+
+ sqlhead := regexp.MustCompile("[ (]").Split(strings.TrimSpace(query), 2)[0]
+ if util.StringUtil.EqualsIgnoreCase(sqlhead, "SP_SET_PARA_VALUE") || util.StringUtil.EqualsIgnoreCase(sqlhead, "SP_SET_SESSION_READONLY") {
+ if otherConn != nil {
+ execute2(otherConn)
+ }
+ }
+ }
+ case Dm_build_700:
+ {
+
+ if conn.dmConnector.rwHA && curConn == conn.rwInfo.connStandby &&
+ (curConn.lastExecInfo.rsDatas == nil || len(curConn.lastExecInfo.rsDatas) == 0) {
+ turnToPrimary = true
+ }
+ }
+ }
+
+ if turnToPrimary {
+ conn.rwInfo.toPrimary()
+ conn.rwInfo.connCurrent = conn
+
+ return execute2(conn)
+ }
+ return ret, nil
+}
+
+func (RWUtil rwUtil) executeByStmt(stmt *DmStatement, execute1 func() (interface{}, error), execute2 func(otherStmt *DmStatement) (interface{}, error)) (interface{}, error) {
+ orgStmt := stmt.rwInfo.stmtCurrent
+ query := stmt.nativeSql
+
+ if err := RWUtil.recoverStandby(stmt.dmConn); err != nil {
+ return nil, err
+ }
+ RWUtil.distributeSqlByStmt(stmt)
+ if orgStmt != stmt.rwInfo.stmtCurrent {
+ RWUtil.copyStatement(orgStmt, stmt.rwInfo.stmtCurrent)
+ stmt.rwInfo.stmtCurrent.nativeSql = orgStmt.nativeSql
+ }
+
+ turnToPrimary := false
+
+ ret, err := execute1()
+ if err != nil {
+
+ if stmt.rwInfo.stmtCurrent == stmt.rwInfo.stmtStandby {
+ RWUtil.afterExceptionOnStandby(stmt.dmConn, err)
+ turnToPrimary = true
+ } else {
+ return nil, err
+ }
+ }
+
+ curStmt := stmt.rwInfo.stmtCurrent
+ var otherStmt *DmStatement
+ if curStmt != stmt {
+ otherStmt = stmt
+ } else {
+ otherStmt = stmt.rwInfo.stmtStandby
+ }
+
+ switch curStmt.execInfo.retSqlType {
+ case Dm_build_691, Dm_build_692, Dm_build_696, Dm_build_703, Dm_build_702, Dm_build_694:
+ {
+
+ if otherStmt != nil {
+ RWUtil.copyStatement(curStmt, otherStmt)
+ execute2(otherStmt)
+ }
+ }
+ case Dm_build_701:
+ {
+
+ var tmpsql string
+ if query != "" {
+ tmpsql = strings.TrimSpace(query)
+ } else if stmt.nativeSql != "" {
+ tmpsql = strings.TrimSpace(stmt.nativeSql)
+ } else {
+ tmpsql = ""
+ }
+ sqlhead := regexp.MustCompile("[ (]").Split(tmpsql, 2)[0]
+ if util.StringUtil.EqualsIgnoreCase(sqlhead, "SP_SET_PARA_VALUE") || util.StringUtil.EqualsIgnoreCase(sqlhead, "SP_SET_SESSION_READONLY") {
+ if otherStmt != nil {
+ RWUtil.copyStatement(curStmt, otherStmt)
+ execute2(otherStmt)
+ }
+ }
+ }
+ case Dm_build_700:
+ {
+
+ if stmt.dmConn.dmConnector.rwHA && curStmt == stmt.rwInfo.stmtStandby &&
+ (curStmt.execInfo.rsDatas == nil || len(curStmt.execInfo.rsDatas) == 0) {
+ turnToPrimary = true
+ }
+ }
+ }
+
+ if turnToPrimary {
+ stmt.dmConn.rwInfo.toPrimary()
+ stmt.rwInfo.stmtCurrent = stmt
+
+ RWUtil.copyStatement(stmt.rwInfo.stmtStandby, stmt)
+
+ return execute2(stmt)
+ }
+ return ret, nil
+}
+
+func (RWUtil rwUtil) checkReadonlyByConn(conn *DmConnection, sql string) bool {
+ readonly := true
+
+ if sql != "" && !conn.dmConnector.rwIgnoreSql {
+ tmpsql := strings.TrimSpace(sql)
+ sqlhead := strings.SplitN(tmpsql, " ", 2)[0]
+ if util.StringUtil.EqualsIgnoreCase(sqlhead, "INSERT") ||
+ util.StringUtil.EqualsIgnoreCase(sqlhead, "UPDATE") ||
+ util.StringUtil.EqualsIgnoreCase(sqlhead, "DELETE") ||
+ util.StringUtil.EqualsIgnoreCase(sqlhead, "CREATE") ||
+ util.StringUtil.EqualsIgnoreCase(sqlhead, "TRUNCATE") ||
+ util.StringUtil.EqualsIgnoreCase(sqlhead, "DROP") ||
+ util.StringUtil.EqualsIgnoreCase(sqlhead, "ALTER") {
+ readonly = false
+ } else {
+ readonly = true
+ }
+ }
+ return readonly
+}
+
+func (RWUtil rwUtil) checkReadonlyByStmt(stmt *DmStatement) bool {
+ return RWUtil.checkReadonlyByConn(stmt.dmConn, stmt.nativeSql)
+}
+
+func (RWUtil rwUtil) distributeSqlByConn(conn *DmConnection, query string) RWSiteEnum {
+ var dest RWSiteEnum
+ if !RWUtil.isStandbyAlive(conn) {
+
+ dest = conn.rwInfo.toPrimary()
+ } else if !RWUtil.checkReadonlyByConn(conn, query) {
+
+ dest = conn.rwInfo.toPrimary()
+ } else if (conn.rwInfo.distribute == PRIMARY && !conn.trxFinish) ||
+ (conn.rwInfo.distribute == STANDBY && !conn.rwInfo.connStandby.trxFinish) {
+
+ dest = conn.rwInfo.distribute
+ } else if conn.IsoLevel != int32(sql.LevelSerializable) {
+
+ dest = conn.rwInfo.toAny()
+ } else {
+ dest = conn.rwInfo.toPrimary()
+ }
+
+ if dest == PRIMARY {
+ conn.rwInfo.connCurrent = conn
+ } else {
+ conn.rwInfo.connCurrent = conn.rwInfo.connStandby
+ }
+ return dest
+}
+
+func (RWUtil rwUtil) distributeSqlByStmt(stmt *DmStatement) RWSiteEnum {
+ var dest RWSiteEnum
+ if !RWUtil.isStandbyAlive(stmt.dmConn) {
+
+ dest = stmt.dmConn.rwInfo.toPrimary()
+ } else if !RWUtil.checkReadonlyByStmt(stmt) {
+
+ dest = stmt.dmConn.rwInfo.toPrimary()
+ } else if (stmt.dmConn.rwInfo.distribute == PRIMARY && !stmt.dmConn.trxFinish) ||
+ (stmt.dmConn.rwInfo.distribute == STANDBY && !stmt.dmConn.rwInfo.connStandby.trxFinish) {
+
+ dest = stmt.dmConn.rwInfo.distribute
+ } else if stmt.dmConn.IsoLevel != int32(sql.LevelSerializable) {
+
+ dest = stmt.dmConn.rwInfo.toAny()
+ } else {
+ dest = stmt.dmConn.rwInfo.toPrimary()
+ }
+
+ if dest == STANDBY && !RWUtil.isStandbyStatementValid(stmt) {
+
+ var err error
+ stmt.rwInfo.stmtStandby, err = stmt.dmConn.rwInfo.connStandby.prepare(stmt.nativeSql)
+ if err != nil {
+ dest = stmt.dmConn.rwInfo.toPrimary()
+ }
+ }
+
+ if dest == PRIMARY {
+ stmt.rwInfo.stmtCurrent = stmt
+ } else {
+ stmt.rwInfo.stmtCurrent = stmt.rwInfo.stmtStandby
+ }
+ return dest
+}
+
+func (RWUtil rwUtil) isStandbyAlive(connection *DmConnection) bool {
+ return connection.rwInfo.connStandby != nil && !connection.rwInfo.connStandby.closed.IsSet()
+}
+
+func (RWUtil rwUtil) isStandbyStatementValid(statement *DmStatement) bool {
+ return statement.rwInfo.stmtStandby != nil && !statement.rwInfo.stmtStandby.closed
+}
+
+func (RWUtil rwUtil) copyStatement(srcStmt *DmStatement, destStmt *DmStatement) {
+ destStmt.nativeSql = srcStmt.nativeSql
+ destStmt.params = srcStmt.params
+ destStmt.paramCount = srcStmt.paramCount
+ destStmt.curRowBindIndicator = srcStmt.curRowBindIndicator
+}
diff --git a/dmr/zzj.go b/dmr/zzj.go
new file mode 100644
index 0000000..320262f
--- /dev/null
+++ b/dmr/zzj.go
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import "database/sql/driver"
+
+var SQLName sqlName
+
+type sqlName struct {
+ m_name string // 描述对象自身名称,
+
+ // 若为内置类型,则表示数据库端定义的名称,与dType相对应
+ m_pkgName string // 所在包的名称,适用于包中类型的定义
+
+ m_schName string // 描述对象所在模式名
+
+ m_fulName string // 描述对象完全限定名, 记录用户发送的名称信息;
+
+ // 以及接受服务器响应后,拼成的名称信息
+
+ m_schId int // 保存模式id,模式名无法传出,利用模式id查找
+
+ m_packId int // 保存包的id,包名无法传出,用于查找包名
+
+ m_conn *DmConnection
+}
+
+func (SqlName *sqlName) init() {
+ SqlName.m_name = ""
+ SqlName.m_pkgName = ""
+ SqlName.m_schName = ""
+ SqlName.m_fulName = ""
+ SqlName.m_schId = -1
+ SqlName.m_packId = -1
+ SqlName.m_conn = nil
+}
+
+func newSqlNameByFulName(fulName string) *sqlName {
+ o := new(sqlName)
+ o.init()
+ o.m_fulName = fulName
+ return o
+}
+
+func newSqlNameByConn(conn *DmConnection) *sqlName {
+ o := new(sqlName)
+ o.init()
+ o.m_conn = conn
+ return o
+}
+
+func (SqlName *sqlName) getFulName() (string, error) {
+ // 说明非内嵌式数据类型名称描述信息传入或已经获取过描述信息
+ if len(SqlName.m_fulName) > 0 {
+ return SqlName.m_fulName, nil
+ }
+
+ // 内嵌式数据类型无名称描述信息返回,直接返回null
+ if SqlName.m_name == "" {
+ // DBError.throwUnsupportedSQLException();
+ return "", nil
+ }
+
+ // 其他数据名描述信息
+ if SqlName.m_packId != 0 || SqlName.m_schId != 0 {
+ sql := "SELECT NAME INTO ? FROM SYS.SYSOBJECTS WHERE ID=?"
+
+ params := make([]driver.Value, 2)
+ var v string
+ params[0] = &v
+ if SqlName.m_packId != 0 {
+ params[1] = SqlName.m_packId
+ } else {
+ params[1] = SqlName.m_schId
+ }
+
+ rs, err := SqlName.m_conn.query(sql, params)
+ if err != nil {
+ return "", err
+ }
+ rs.close()
+
+ // 说明是包中定义的对象
+ if SqlName.m_packId != 0 {
+ // pkg全名
+ SqlName.m_pkgName = v
+ SqlName.m_fulName = SqlName.m_pkgName + "." + SqlName.m_name
+ } else {
+ // 非包中定义的对象
+ // schema 名称
+ SqlName.m_schName = v
+ SqlName.m_fulName = SqlName.m_schName + "." + SqlName.m_name
+ }
+ }
+ // 将有效值返回
+ if len(SqlName.m_fulName) > 0 {
+ return SqlName.m_fulName, nil
+ } else {
+ return SqlName.m_name, nil
+ }
+
+}
diff --git a/dmr/zzk.go b/dmr/zzk.go
new file mode 100644
index 0000000..015e0f8
--- /dev/null
+++ b/dmr/zzk.go
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "bytes"
+ "strconv"
+ "strings"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/parser"
+)
+
+func (dc *DmConnection) lex(sql string) ([]*parser.LVal, error) {
+ if dc.lexer == nil {
+ dc.lexer = parser.NewLexer(strings.NewReader(sql), false)
+ } else {
+ dc.lexer.Reset(strings.NewReader(sql))
+ }
+
+ lexer := dc.lexer
+ var lval *parser.LVal
+ var err error
+ lvalList := make([]*parser.LVal, 0, 64)
+ lval, err = lexer.Yylex()
+ if err != nil {
+ return nil, err
+ }
+
+ for lval != nil {
+ lvalList = append(lvalList, lval)
+ lval.Position = len(lvalList)
+ lval, err = lexer.Yylex()
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return lvalList, nil
+}
+
+func lexSkipWhitespace(sql string, n int) ([]*parser.LVal, error) {
+ lexer := parser.NewLexer(strings.NewReader(sql), false)
+
+ var lval *parser.LVal
+ var err error
+ lvalList := make([]*parser.LVal, 0, 64)
+ lval, err = lexer.Yylex()
+ if err != nil {
+ return nil, err
+ }
+
+ for lval != nil && n > 0 {
+ lval.Position = len(lvalList)
+ if lval.Tp == parser.WHITESPACE_OR_COMMENT {
+ continue
+ }
+
+ lvalList = append(lvalList, lval)
+ n--
+ lval, err = lexer.Yylex()
+ if err != nil {
+ return nil, err
+ }
+
+ }
+
+ return lvalList, nil
+}
+
+func (dc *DmConnection) escape(sql string, keywords []string) (string, error) {
+
+ if (keywords == nil || len(keywords) == 0) && strings.Index(sql, "{") == -1 {
+ return sql, nil
+ }
+ var keywordMap map[string]interface{}
+ if keywords != nil && len(keywords) > 0 {
+ keywordMap = make(map[string]interface{}, len(keywords))
+ for _, keyword := range keywords {
+ keywordMap[strings.ToUpper(keyword)] = nil
+ }
+ }
+ nsql := bytes.NewBufferString("")
+ stack := make([]bool, 0, 64)
+ lvalList, err := dc.lex(sql)
+ if err != nil {
+ return "", err
+ }
+
+ for i := 0; i < len(lvalList); i++ {
+ lval0 := lvalList[i]
+ if lval0.Tp == parser.NORMAL {
+ if lval0.Value == "{" {
+ lval1 := next(lvalList, i+1)
+ if lval1 == nil || lval1.Tp != parser.NORMAL {
+ stack = append(stack, false)
+ nsql.WriteString(lval0.Value)
+ } else if util.StringUtil.EqualsIgnoreCase(lval1.Value, "escape") || util.StringUtil.EqualsIgnoreCase(lval1.Value, "call") {
+ stack = append(stack, true)
+ } else if util.StringUtil.EqualsIgnoreCase(lval1.Value, "oj") {
+ stack = append(stack, true)
+ lval1.Value = ""
+ lval1.Tp = parser.WHITESPACE_OR_COMMENT
+ } else if util.StringUtil.EqualsIgnoreCase(lval1.Value, "d") {
+ stack = append(stack, true)
+ lval1.Value = "date"
+ } else if util.StringUtil.EqualsIgnoreCase(lval1.Value, "t") {
+ stack = append(stack, true)
+ lval1.Value = "time"
+ } else if util.StringUtil.EqualsIgnoreCase(lval1.Value, "ts") {
+ stack = append(stack, true)
+ lval1.Value = "datetime"
+ } else if util.StringUtil.EqualsIgnoreCase(lval1.Value, "fn") {
+ stack = append(stack, true)
+ lval1.Value = ""
+ lval1.Tp = parser.WHITESPACE_OR_COMMENT
+ lval2 := next(lvalList, lval1.Position+1)
+ if lval2 != nil && lval2.Tp == parser.NORMAL && util.StringUtil.EqualsIgnoreCase(lval2.Value, "database") {
+ lval2.Value = "cur_database"
+ }
+ } else if util.StringUtil.Equals(lval1.Value, "?") {
+ lval2 := next(lvalList, lval1.Position+1)
+ if lval2 != nil && lval2.Tp == parser.NORMAL && util.StringUtil.EqualsIgnoreCase(lval2.Value, "=") {
+ lval3 := next(lvalList, lval2.Position+1)
+ if lval3 != nil && lval3.Tp == parser.NORMAL && util.StringUtil.EqualsIgnoreCase(lval3.Value, "call") {
+ stack = append(stack, true)
+ lval3.Value = ""
+ lval3.Tp = parser.WHITESPACE_OR_COMMENT
+ } else {
+ stack = append(stack, false)
+ nsql.WriteString(lval0.Value)
+ }
+ } else {
+ stack = append(stack, false)
+ nsql.WriteString(lval0.Value)
+ }
+ } else {
+ stack = append(stack, false)
+ nsql.WriteString(lval0.Value)
+ }
+ } else if util.StringUtil.Equals(lval0.Value, "}") {
+ if len(stack) != 0 && stack[len(stack)-1] {
+
+ } else {
+ nsql.WriteString(lval0.Value)
+ }
+ stack = stack[:len(stack)-1]
+ } else {
+ if keywordMap != nil {
+ _, ok := keywordMap[strings.ToUpper(lval0.Value)]
+ if ok {
+ nsql.WriteString("\"" + util.StringUtil.ProcessDoubleQuoteOfName(strings.ToUpper(lval0.Value)) + "\"")
+ } else {
+ nsql.WriteString(lval0.Value)
+ }
+ } else {
+ nsql.WriteString(lval0.Value)
+ }
+ }
+ } else if lval0.Tp == parser.STRING {
+ nsql.WriteString("'" + util.StringUtil.ProcessSingleQuoteOfName(lval0.Value) + "'")
+ } else {
+ nsql.WriteString(lval0.Value)
+ }
+ }
+
+ return nsql.String(), nil
+}
+
+func next(lvalList []*parser.LVal, start int) *parser.LVal {
+ var lval *parser.LVal
+
+ size := len(lvalList)
+ for i := start; i < size; i++ {
+ lval = lvalList[i]
+ if lval.Tp != parser.WHITESPACE_OR_COMMENT {
+ break
+ }
+ }
+ return lval
+}
+
+func (dc *DmConnection) execOpt(sql string, optParamList []OptParameter, serverEncoding string) (string, []OptParameter, error) {
+ nsql := bytes.NewBufferString("")
+
+ lvalList, err := dc.lex(sql)
+ if err != nil {
+ return "", optParamList, err
+ }
+
+ if nil == lvalList || len(lvalList) == 0 {
+ return sql, optParamList, nil
+ }
+
+ firstWord := lvalList[0].Value
+ if !(util.StringUtil.EqualsIgnoreCase(firstWord, "INSERT") || util.StringUtil.EqualsIgnoreCase(firstWord, "SELECT") ||
+ util.StringUtil.EqualsIgnoreCase(firstWord, "UPDATE") || util.StringUtil.EqualsIgnoreCase(firstWord, "DELETE")) {
+ return sql, optParamList, nil
+ }
+
+ breakIndex := 0
+ for i := 0; i < len(lvalList); i++ {
+ lval := lvalList[i]
+ switch lval.Tp {
+ case parser.NULL:
+ {
+ nsql.WriteString("?")
+ optParamList = append(optParamList, newOptParameter(nil, NULL, NULL_PREC))
+ }
+ case parser.INT:
+ {
+ nsql.WriteString("?")
+ value, err := strconv.Atoi(lval.Value)
+ if err != nil {
+ return "", optParamList, err
+ }
+
+ if value <= int(INT32_MAX) && value >= int(INT32_MIN) {
+ optParamList = append(optParamList, newOptParameter(G2DB.toInt32(int32(value)), INT, INT_PREC))
+
+ } else {
+ optParamList = append(optParamList, newOptParameter(G2DB.toInt64(int64(value)), BIGINT, BIGINT_PREC))
+ }
+ }
+ case parser.DOUBLE:
+ {
+ nsql.WriteString("?")
+ f, err := strconv.ParseFloat(lval.Value, 64)
+ if err != nil {
+ return "", optParamList, err
+ }
+
+ optParamList = append(optParamList, newOptParameter(G2DB.toFloat64(f), DOUBLE, DOUBLE_PREC))
+ }
+ case parser.DECIMAL:
+ {
+ nsql.WriteString("?")
+ bytes, err := G2DB.toDecimal(lval.Value, 0, 0)
+ if err != nil {
+ return "", optParamList, err
+ }
+ optParamList = append(optParamList, newOptParameter(bytes, DECIMAL, 0))
+ }
+ case parser.STRING:
+ {
+
+ if len(lval.Value) > int(INT16_MAX) {
+
+ nsql.WriteString("'" + util.StringUtil.ProcessSingleQuoteOfName(lval.Value) + "'")
+ } else {
+ nsql.WriteString("?")
+ optParamList = append(optParamList, newOptParameter(Dm_build_1220.Dm_build_1433(lval.Value, serverEncoding, dc), VARCHAR, VARCHAR_PREC))
+ }
+ }
+ case parser.HEX_INT:
+
+ nsql.WriteString(lval.Value)
+ default:
+
+ nsql.WriteString(lval.Value)
+ }
+
+ if breakIndex > 0 {
+ break
+ }
+ }
+
+ if breakIndex > 0 {
+ for i := breakIndex + 1; i < len(lvalList); i++ {
+ nsql.WriteString(lvalList[i].Value)
+ }
+ }
+
+ return nsql.String(), optParamList, nil
+}
+
+func (dc *DmConnection) hasConst(sql string) (bool, error) {
+ lvalList, err := dc.lex(sql)
+ if err != nil {
+ return false, err
+ }
+
+ if nil == lvalList || len(lvalList) == 0 {
+ return false, nil
+ }
+
+ for i := 0; i < len(lvalList); i++ {
+ switch lvalList[i].Tp {
+ case parser.NULL, parser.INT, parser.DOUBLE, parser.DECIMAL, parser.STRING, parser.HEX_INT:
+ return true, nil
+ }
+ }
+ return false, nil
+}
+
+type OptParameter struct {
+ bytes []byte
+ ioType byte
+ tp int
+ prec int
+ scale int
+}
+
+func newOptParameter(bytes []byte, tp int, prec int) OptParameter {
+ o := new(OptParameter)
+ o.bytes = bytes
+ o.tp = tp
+ o.prec = prec
+ return *o
+}
+
+func (parameter *OptParameter) String() string {
+ if parameter.bytes == nil {
+ return ""
+ }
+ return string(parameter.bytes)
+}
diff --git a/dmr/zzl.go b/dmr/zzl.go
new file mode 100644
index 0000000..250d9cf
--- /dev/null
+++ b/dmr/zzl.go
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+type StructDescriptor struct {
+ m_typeDesc *TypeDescriptor
+}
+
+func newStructDescriptor(fulName string, conn *DmConnection) (*StructDescriptor, error) {
+ sd := new(StructDescriptor)
+ if fulName == "" {
+ return nil, ECGO_INVALID_COMPLEX_TYPE_NAME.throw()
+ }
+
+ sd.m_typeDesc = newTypeDescriptorWithFulName(fulName, conn)
+
+ err := sd.m_typeDesc.parseDescByName()
+ if err != nil {
+ return nil, err
+ }
+
+ return sd, nil
+}
+
+func newStructDescriptorByTypeDescriptor(desc *TypeDescriptor) *StructDescriptor {
+ sd := new(StructDescriptor)
+ sd.m_typeDesc = desc
+ return sd
+}
+
+func (sd *StructDescriptor) getSize() int {
+ return sd.m_typeDesc.m_size
+}
+
+func (sd *StructDescriptor) getObjId() int {
+ return sd.m_typeDesc.m_objId
+}
+
+func (sd *StructDescriptor) getItemsDesc() []TypeDescriptor {
+ return sd.m_typeDesc.m_fieldsObj
+}
diff --git a/dmr/zzm.go b/dmr/zzm.go
new file mode 100644
index 0000000..ce6b403
--- /dev/null
+++ b/dmr/zzm.go
@@ -0,0 +1,441 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+
+package dmr
+
+import (
+ "bufio"
+ "io"
+ "os"
+ "runtime"
+ "strconv"
+ "strings"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+var LogDirDef, _ = os.Getwd()
+
+var StatDirDef, _ = os.Getwd()
+
+const (
+ DEFAULT_PORT int32 = 5236
+
+ //log level
+ LOG_OFF int = 0
+
+ LOG_ERROR int = 1
+
+ LOG_WARN int = 2
+
+ LOG_SQL int = 3
+
+ LOG_INFO int = 4
+
+ LOG_DEBUG int = 5
+
+ LOG_ALL int = 9
+
+ //stat
+ STAT_SQL_REMOVE_LATEST int = 0
+
+ STAT_SQL_REMOVE_OLDEST int = 1
+
+ // 编码字符集
+ ENCODING_UTF8 string = "UTF-8"
+
+ ENCODING_EUCKR string = "EUC-KR"
+
+ ENCODING_GB18030 string = "GB18030"
+
+ DbAliveCheckFreqDef = 0
+
+ LocaleDef = 0
+
+ // log
+ LogLevelDef = LOG_OFF // 日志级别:off, error, warn, sql, info, all
+
+ LogFlushFreqDef = 10 // 日志刷盘时间s (>=0)
+
+ LogFlushQueueSizeDef = 100 //日志队列大小
+
+ LogBufferSizeDef = 32 * 1024 // 日志缓冲区大小 (>0)
+
+ // stat
+ StatEnableDef = false //
+
+ StatFlushFreqDef = 3 // 日志刷盘时间s (>=0)
+
+ StatSlowSqlCountDef = 100 // 慢sql top行数,(0-1000)
+
+ StatHighFreqSqlCountDef = 100 // 高频sql top行数, (0-1000)
+
+ StatSqlMaxCountDef = 100000 // sql 统计最大值(0-100000)
+
+ StatSqlRemoveModeDef = STAT_SQL_REMOVE_LATEST // 记录sql数超过最大值时,sql淘汰方式
+)
+
+var (
+ DbAliveCheckFreq = DbAliveCheckFreqDef
+
+ Locale = LocaleDef // 0:简体中文 1:英文 2:繁体中文
+
+ // log
+ LogLevel = LogLevelDef // 日志级别:off, error, warn, sql, info, all
+
+ LogDir = LogDirDef
+
+ LogFlushFreq = LogFlushFreqDef // 日志刷盘时间s (>=0)
+
+ LogFlushQueueSize = LogFlushQueueSizeDef
+
+ LogBufferSize = LogBufferSizeDef // 日志缓冲区大小 (>0)
+
+ // stat
+ StatEnable = StatEnableDef //
+
+ StatDir = StatDirDef // jdbc工作目录,所有生成的文件都在该目录下
+
+ StatFlushFreq = StatFlushFreqDef // 日志刷盘时间s (>=0)
+
+ StatSlowSqlCount = StatSlowSqlCountDef // 慢sql top行数,(0-1000)
+
+ StatHighFreqSqlCount = StatHighFreqSqlCountDef // 高频sql top行数, (0-1000)
+
+ StatSqlMaxCount = StatSqlMaxCountDef // sql 统计最大值(0-100000)
+
+ StatSqlRemoveMode = StatSqlRemoveModeDef // 记录sql数超过最大值时,sql淘汰方式
+
+ /*---------------------------------------------------------------*/
+ ServerGroupMap = make(map[string]*epGroup)
+
+ GlobalProperties = NewProperties()
+)
+
+// filePath: dm_svc.conf 文件路径
+func load(filePath string) {
+ if filePath == "" {
+ switch runtime.GOOS {
+ case "windows":
+ filePath = os.Getenv("SystemRoot") + "\\system32\\dm_svc.conf"
+ case "linux":
+ filePath = "/etc/dm_svc.conf"
+ default:
+ return
+ }
+ }
+ file, err := os.Open(filePath)
+ defer file.Close()
+ if err != nil {
+ return
+ }
+ fileReader := bufio.NewReader(file)
+
+ // GlobalProperties = NewProperties()
+ var groupProps *Properties
+ var line string //dm_svc.conf读取到的一行
+
+ for line, err = fileReader.ReadString('\n'); line != "" && (err == nil || err == io.EOF); line, err = fileReader.ReadString('\n') {
+ // 去除#标记的注释
+ if notesIndex := strings.IndexByte(line, '#'); notesIndex != -1 {
+ line = line[:notesIndex]
+ }
+ // 去除前后多余的空格
+ line = strings.TrimSpace(line)
+ if line == "" {
+ continue
+ }
+
+ if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
+ groupName := strings.ToLower(line[1 : len(line)-1])
+ dbGroup, ok := ServerGroupMap[groupName]
+ if groupName == "" || !ok {
+ continue
+ }
+ groupProps = dbGroup.props
+ if groupProps.IsNil() {
+ groupProps = NewProperties()
+ groupProps.SetProperties(GlobalProperties)
+ dbGroup.props = groupProps
+ }
+
+ } else {
+ cfgInfo := strings.Split(line, "=")
+ if len(cfgInfo) < 2 {
+ continue
+ }
+ key := strings.TrimSpace(cfgInfo[0])
+ value := strings.TrimSpace(cfgInfo[1])
+ if strings.HasPrefix(value, "(") && strings.HasSuffix(value, ")") {
+ value = strings.TrimSpace(value[1 : len(value)-1])
+ }
+ if key == "" || value == "" {
+ continue
+ }
+ // 区分属性是全局的还是组的
+ var success bool
+ if groupProps.IsNil() {
+ success = SetServerGroupProperties(GlobalProperties, key, value)
+ } else {
+ success = SetServerGroupProperties(groupProps, key, value)
+ }
+ if !success {
+ var serverGroup = parseServerName(key, value)
+ if serverGroup != nil {
+ serverGroup.props = NewProperties()
+ serverGroup.props.SetProperties(GlobalProperties)
+ ServerGroupMap[strings.ToLower(key)] = serverGroup
+ }
+ }
+ }
+ }
+}
+
+func SetServerGroupProperties(props *Properties, key string, value string) bool {
+ if util.StringUtil.EqualsIgnoreCase(key, "ADDRESS_REMAP") {
+ tmp := props.GetString(AddressRemapKey, "")
+ props.Set(AddressRemapKey, tmp+"("+value+")")
+ } else if util.StringUtil.EqualsIgnoreCase(key, "ALWAYS_ALLOW_COMMIT") {
+ props.Set(AlwayseAllowCommitKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "APP_NAME") {
+ props.Set(AppNameKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "AUTO_COMMIT") {
+ props.Set(AutoCommitKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "BATCH_ALLOW_MAX_ERRORS") {
+ props.Set(BatchAllowMaxErrorsKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "BATCH_CONTINUE_ON_ERROR") ||
+ util.StringUtil.EqualsIgnoreCase(key, "CONTINUE_BATCH_ON_ERROR") {
+ props.Set(ContinueBatchOnErrorKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "BATCH_NOT_ON_CALL") {
+ props.Set(BatchNotOnCallKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "BATCH_TYPE") {
+ props.Set(BatchTypeKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "BUF_PREFETCH") {
+ props.Set(BufPrefetchKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "CIPHER_PATH") {
+ props.Set(CipherPathKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "CLUSTER") {
+ props.Set(ClusterKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "COLUMN_NAME_UPPER_CASE") {
+ props.Set(ColumnNameUpperCaseKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "COLUMN_NAME_CASE") {
+ props.Set(ColumnNameCaseKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "COMPATIBLE_MODE") {
+ props.Set(CompatibleModeKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "COMPRESS") ||
+ util.StringUtil.EqualsIgnoreCase(key, "COMPRESS_MSG") {
+ props.Set(CompressKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "COMPRESS_ID") {
+ props.Set(CompressIdKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "CONNECT_TIMEOUT") {
+ props.Set(ConnectTimeoutKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "DO_SWITCH") ||
+ util.StringUtil.EqualsIgnoreCase(key, "AUTO_RECONNECT") {
+ props.Set(DoSwitchKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "ENABLE_RS_CACHE") {
+ props.Set(EnRsCacheKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "EP_SELECTION") {
+ props.Set(EpSelectorKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "ESCAPE_PROCESS") {
+ props.Set(EscapeProcessKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "IS_BDTA_RS") {
+ props.Set(IsBdtaRSKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "KEY_WORDS") ||
+ util.StringUtil.EqualsIgnoreCase(key, "KEYWORDS") {
+ props.Set(KeywordsKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "LANGUAGE") {
+ props.Set(LanguageKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "LOB_MODE") {
+ props.Set(LobModeKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "LOG_DIR") {
+ props.Set(LogDirKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "LOG_FLUSH_FREQ") {
+ props.Set(LogFlushFreqKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "LOG_LEVEL") {
+ props.Set(LogLevelKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "LOGIN_DSC_CTRL") {
+ props.Set(LoginDscCtrlKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "LOGIN_ENCRYPT") {
+ props.Set(LoginEncryptKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "LOGIN_MODE") {
+ props.Set(LoginModeKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "LOGIN_STATUS") {
+ props.Set(LoginStatusKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "MAX_ROWS") {
+ props.Set(MaxRowsKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "MPP_LOCAL") {
+ props.Set(MppLocalKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "OS_NAME") {
+ props.Set(OsNameKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "RS_CACHE_SIZE") {
+ props.Set(RsCacheSizeKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "RS_REFRESH_FREQ") {
+ props.Set(RsRefreshFreqKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "RW_HA") {
+ props.Set(RwHAKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "RW_IGNORE_SQL") {
+ props.Set(RwIgnoreSqlKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "RW_PERCENT") {
+ props.Set(RwPercentKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "RW_SEPARATE") {
+ props.Set(RwSeparateKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "RW_STANDBY_RECOVER_TIME") {
+ props.Set(RwStandbyRecoverTimeKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "SCHEMA") {
+ props.Set(SchemaKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "SESS_ENCODE") {
+ if IsSupportedCharset(value) {
+ props.Set("sessEncode", value)
+ }
+ } else if util.StringUtil.EqualsIgnoreCase(key, "SESSION_TIMEOUT") {
+ props.Set(SessionTimeoutKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "SOCKET_TIMEOUT") {
+ props.Set(SocketTimeoutKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "SSL_FILES_PATH") {
+ props.Set(SslFilesPathKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "STAT_DIR") {
+ props.Set(StatDirKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "STAT_ENABLE") {
+ props.Set(StatEnableKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "STAT_FLUSH_FREQ") {
+ props.Set(StatFlushFreqKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "STAT_HIGH_FREQ_SQL_COUNT") {
+ props.Set(StatHighFreqSqlCountKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "STAT_SLOW_SQL_COUNT") {
+ props.Set(StatSlowSqlCountKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "STAT_SQL_MAX_COUNT") {
+ props.Set(StatSqlMaxCountKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "STAT_SQL_REMOVE_MODE") {
+ props.Set(StatSqlRemoveModeKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "SWITCH_INTERVAL") {
+ props.Set(SwitchIntervalKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "SWITCH_TIME") ||
+ util.StringUtil.EqualsIgnoreCase(key, "SWITCH_TIMES") {
+ props.Set(SwitchTimesKey, value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "TIME_ZONE") {
+ props.Set(TimeZoneKey, value)
+ props.Set("localTimezone", value)
+ } else if util.StringUtil.EqualsIgnoreCase(key, "USER_REMAP") {
+ tmp := props.GetString(UserRemapKey, "")
+ props.Set(UserRemapKey, tmp+"("+value+")")
+ } else {
+ return false
+ }
+ return true
+}
+
+func parseServerName(name string, value string) *epGroup {
+ values := strings.Split(value, ",")
+
+ var tmpVals []string
+ var tmpName string
+ var tmpPort int
+ var svrList = make([]*ep, 0, len(values))
+
+ for _, v := range values {
+
+ var tmp *ep
+ // 先查找IPV6,以[]包括
+ begin := strings.IndexByte(v, '[')
+ end := -1
+ if begin != -1 {
+ end = strings.IndexByte(v[begin:], ']')
+ }
+ if end != -1 {
+ tmpName = v[begin+1 : end]
+
+ // port
+ if portIndex := strings.IndexByte(v[end:], ':'); portIndex != -1 {
+ tmpPort, _ = strconv.Atoi(strings.TrimSpace(v[portIndex+1:]))
+ } else {
+ tmpPort = int(DEFAULT_PORT)
+ }
+ tmp = newEP(tmpName, int32(tmpPort))
+ svrList = append(svrList, tmp)
+ continue
+ }
+ // IPV4
+ tmpVals = strings.Split(v, ":")
+ tmpName = strings.TrimSpace(tmpVals[0])
+ if len(tmpVals) >= 2 {
+ tmpPort, _ = strconv.Atoi(tmpVals[1])
+ } else {
+ tmpPort = int(DEFAULT_PORT)
+ }
+ tmp = newEP(tmpName, int32(tmpPort))
+ svrList = append(svrList, tmp)
+ }
+
+ if len(svrList) == 0 {
+ return nil
+ }
+ return newEPGroup(name, svrList)
+}
+
+func setDriverAttributes(props *Properties) {
+ if props == nil || props.Len() == 0 {
+ return
+ }
+
+ parseLanguage(props.GetString(LanguageKey, "cn"))
+ DbAliveCheckFreq = props.GetInt(DbAliveCheckFreqKey, DbAliveCheckFreqDef, 1, int(INT32_MAX))
+
+ //// log
+ //LogLevel = ParseLogLevel(props)
+ //LogDir = util.StringUtil.FormatDir(props.GetTrimString(LogDirKey, LogDirDef))
+ //LogBufferSize = props.GetInt(LogBufferSizeKey, LogBufferSizeDef, 1, int(INT32_MAX))
+ //LogFlushFreq = props.GetInt(LogFlushFreqKey, LogFlushFreqDef, 1, int(INT32_MAX))
+ //LogFlushQueueSize = props.GetInt(LogFlusherQueueSizeKey, LogFlushQueueSizeDef, 1, int(INT32_MAX))
+ //
+ //// stat
+ //StatEnable = props.GetBool(StatEnableKey, StatEnableDef)
+ //StatDir = util.StringUtil.FormatDir(props.GetTrimString(StatDirKey, StatDirDef))
+ //StatFlushFreq = props.GetInt(StatFlushFreqKey, StatFlushFreqDef, 1, int(INT32_MAX))
+ //StatHighFreqSqlCount = props.GetInt(StatHighFreqSqlCountKey, StatHighFreqSqlCountDef, 0, 1000)
+ //StatSlowSqlCount = props.GetInt(StatSlowSqlCountKey, StatSlowSqlCountDef, 0, 1000)
+ //StatSqlMaxCount = props.GetInt(StatSqlMaxCountKey, StatSqlMaxCountDef, 0, 100000)
+ //parseStatSqlRemoveMode(props)
+}
+
+func parseLanguage(value string) {
+ if util.StringUtil.EqualsIgnoreCase("cn", value) {
+ Locale = 0
+ } else if util.StringUtil.EqualsIgnoreCase("en", value) {
+ Locale = 1
+ }
+}
+
+func IsSupportedCharset(charset string) bool {
+ if util.StringUtil.EqualsIgnoreCase(ENCODING_UTF8, charset) || util.StringUtil.EqualsIgnoreCase(ENCODING_GB18030, charset) || util.StringUtil.EqualsIgnoreCase(ENCODING_EUCKR, charset) {
+ return true
+ }
+ return false
+}
+
+func ParseLogLevel(props *Properties) int {
+ logLevel := LOG_OFF
+ value := props.GetString(LogLevelKey, "")
+ if value != "" && !util.StringUtil.IsDigit(value) {
+ if util.StringUtil.EqualsIgnoreCase("debug", value) {
+ logLevel = LOG_DEBUG
+ } else if util.StringUtil.EqualsIgnoreCase("info", value) {
+ logLevel = LOG_INFO
+ } else if util.StringUtil.EqualsIgnoreCase("sql", value) {
+ logLevel = LOG_SQL
+ } else if util.StringUtil.EqualsIgnoreCase("warn", value) {
+ logLevel = LOG_WARN
+ } else if util.StringUtil.EqualsIgnoreCase("error", value) {
+ logLevel = LOG_ERROR
+ } else if util.StringUtil.EqualsIgnoreCase("off", value) {
+ logLevel = LOG_OFF
+ } else if util.StringUtil.EqualsIgnoreCase("all", value) {
+ logLevel = LOG_ALL
+ }
+ } else {
+ logLevel = props.GetInt(LogLevelKey, logLevel, LOG_OFF, LOG_INFO)
+ }
+
+ return logLevel
+}
diff --git a/dmr/zzn.go b/dmr/zzn.go
new file mode 100644
index 0000000..6e446cb
--- /dev/null
+++ b/dmr/zzn.go
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "database/sql"
+ "database/sql/driver"
+ "math"
+ "reflect"
+ "strings"
+ "time"
+)
+
+const (
+ INT8_MAX int8 = math.MaxInt8
+
+ INT8_MIN int8 = math.MinInt8
+
+ BYTE_MAX byte = math.MaxUint8
+
+ BYTE_MIN byte = 0
+
+ INT16_MAX int16 = math.MaxInt16
+
+ INT16_MIN int16 = math.MinInt16
+
+ UINT16_MAX uint16 = math.MaxUint16
+
+ UINT16_MIN uint16 = 0
+
+ INT32_MAX int32 = math.MaxInt32
+
+ INT32_MIN int32 = math.MinInt32
+
+ UINT32_MAX uint32 = math.MaxUint32
+
+ UINT32_MIN uint32 = 0
+
+ INT64_MAX int64 = math.MaxInt64
+
+ INT64_MIN int64 = math.MinInt64
+
+ UINT64_MAX uint64 = math.MaxUint64
+
+ UINT64_MIN uint64 = 0
+
+ FLOAT32_MAX float32 = 3.4e+38
+
+ FLOAT32_MIN float32 = -3.4e+38
+
+ BYTE_SIZE = 1
+
+ USINT_SIZE = 2
+
+ ULINT_SIZE = 4
+
+ DDWORD_SIZE = 8
+
+ LINT64_SIZE = 8
+
+ CHAR = 0
+
+ VARCHAR2 = 1
+
+ VARCHAR = 2
+
+ BIT = 3
+
+ TINYINT = 5
+
+ SMALLINT = 6
+
+ INT = 7
+
+ BIGINT = 8
+
+ DECIMAL = 9
+
+ REAL = 10
+
+ DOUBLE = 11
+
+ BLOB = 12
+
+ BOOLEAN = 13
+
+ DATE = 14
+
+ TIME = 15
+
+ DATETIME = 16
+
+ BINARY = 17
+
+ VARBINARY = 18
+
+ CLOB = 19
+
+ INTERVAL_YM = 20
+
+ INTERVAL_DT = 21
+
+ TIME_TZ = 22
+
+ DATETIME_TZ = 23
+
+ NULL = 25
+
+ ANY = 31
+
+ STAR_ALL = 32
+
+ STAR = 33
+
+ RECORD = 40
+
+ TYPE = 41
+
+ TYPE_REF = 42
+
+ UNKNOWN = 54
+
+ ARRAY = 117
+
+ CLASS = 119
+
+ CURSOR = 120
+
+ PLTYPE_RECORD = 121
+
+ SARRAY = 122
+
+ CURSOR_ORACLE = -10
+
+ BIT_PREC = BYTE_SIZE
+
+ TINYINT_PREC = BYTE_SIZE
+
+ SMALLINT_PREC = USINT_SIZE
+
+ INT_PREC = ULINT_SIZE
+
+ BIGINT_PREC = LINT64_SIZE
+
+ REAL_PREC = 4
+
+ DOUBLE_PREC = 8
+
+ DATE_PREC = 3
+
+ TIME_PREC = 5
+
+ DATETIME_PREC = 8
+
+ INTERVAL_YM_PREC = 3 * ULINT_SIZE
+
+ INTERVAL_DT_PREC = 6 * ULINT_SIZE
+
+ TIME_TZ_PREC = 12
+
+ DATETIME_TZ_PREC = 12
+
+ VARCHAR_PREC = 8188
+
+ VARBINARY_PREC = 8188
+
+ BLOB_PREC int32 = INT32_MAX
+
+ CLOB_PREC int32 = INT32_MAX
+
+ NULL_PREC = 0
+
+ LOCAL_TIME_ZONE_SCALE_MASK = 0x00001000
+
+ BFILE_PREC = 512
+
+ BFILE_SCALE = 6
+
+ COMPLEX_SCALE = 5
+
+ CURRENCY_PREC = 19
+
+ CURRENCY_SCALE = 4
+
+ FLOAT_SCALE_MASK = 0X81
+)
+
+func resetColType(stmt *DmStatement, i int, colType int32) bool {
+
+ parameter := &stmt.params[i]
+
+ if parameter.ioType == IO_TYPE_OUT {
+ stmt.curRowBindIndicator[i] |= BIND_OUT
+ return false
+ } else if parameter.ioType == IO_TYPE_IN {
+ stmt.curRowBindIndicator[i] |= BIND_IN
+ } else {
+ stmt.curRowBindIndicator[i] |= BIND_IN
+ stmt.curRowBindIndicator[i] |= BIND_OUT
+ }
+
+ if parameter.typeFlag != TYPE_FLAG_EXACT {
+
+ parameter.colType = colType
+ parameter.scale = 0
+ switch colType {
+ case CHAR, VARCHAR, VARCHAR2:
+ parameter.prec = VARCHAR_PREC
+ case CLOB:
+ parameter.prec = CLOB_PREC
+ case BINARY, VARBINARY:
+ parameter.prec = VARBINARY_PREC
+ case BLOB:
+ parameter.prec = BLOB_PREC
+ case BOOLEAN, BIT:
+ parameter.prec = BIT_PREC
+ }
+ }
+
+ return true
+}
+
+func isBFile(colType int, prec int, scale int) bool {
+ return colType == VARCHAR && prec == BFILE_PREC && scale == BFILE_SCALE
+}
+
+func isComplexType(colType int, scale int) bool {
+ return (colType == BLOB && scale == COMPLEX_SCALE) || colType == ARRAY || colType == SARRAY || colType == CLASS || colType == PLTYPE_RECORD
+}
+
+func isLocalTimeZone(colType int, scale int) bool {
+ return colType == DATETIME && (scale&LOCAL_TIME_ZONE_SCALE_MASK) != 0
+}
+
+func getLocalTimeZoneScale(colType int, scale int) int {
+ return scale & (^LOCAL_TIME_ZONE_SCALE_MASK)
+}
+
+func isFloat(colType int, scale int) bool {
+ return colType == DECIMAL && scale == FLOAT_SCALE_MASK
+}
+
+func getFloatPrec(prec int) int {
+ return int(math.Round(float64(prec)*0.30103)) + 1
+}
+
+func getFloatScale(scale int) int {
+ return scale & (^FLOAT_SCALE_MASK)
+}
+
+var (
+ scanTypeFloat32 = reflect.TypeOf(float32(0))
+ scanTypeFloat64 = reflect.TypeOf(float64(0))
+ scanTypeBool = reflect.TypeOf(false)
+ scanTypeInt8 = reflect.TypeOf(int8(0))
+ scanTypeInt16 = reflect.TypeOf(int16(0))
+ scanTypeInt32 = reflect.TypeOf(int32(0))
+ scanTypeInt64 = reflect.TypeOf(int64(0))
+ scanTypeNullBool = reflect.TypeOf(sql.NullBool{})
+ scanTypeNullFloat = reflect.TypeOf(sql.NullFloat64{})
+ scanTypeNullInt = reflect.TypeOf(sql.NullInt64{})
+ scanTypeNullString = reflect.TypeOf(sql.NullString{})
+ scanTypeNullTime = reflect.TypeOf(sql.NullTime{})
+ scanTypeRawBytes = reflect.TypeOf(sql.RawBytes{})
+ scanTypeString = reflect.TypeOf("")
+ scanTypeTime = reflect.TypeOf(time.Now())
+ scanTypeUnknown = reflect.TypeOf(new(interface{}))
+)
+
+func (column *column) ScanType() reflect.Type {
+
+ switch column.colType {
+ case BOOLEAN:
+ if column.nullable {
+ return scanTypeNullBool
+ }
+
+ return scanTypeBool
+
+ case BIT:
+ if strings.ToLower(column.typeName) == "boolean" {
+
+ if column.nullable {
+ return scanTypeNullBool
+ }
+
+ return scanTypeBool
+ } else {
+
+ if column.nullable {
+ return scanTypeNullInt
+ }
+ return scanTypeInt8
+ }
+
+ case TINYINT:
+ if column.nullable {
+ return scanTypeNullInt
+ }
+ return scanTypeInt8
+
+ case SMALLINT:
+ if column.nullable {
+ return scanTypeNullInt
+ }
+ return scanTypeInt16
+
+ case INT:
+ if column.nullable {
+ return scanTypeNullInt
+ }
+
+ return scanTypeInt32
+
+ case BIGINT:
+ if column.nullable {
+ return scanTypeNullInt
+ }
+ return scanTypeInt64
+
+ case REAL:
+ if column.nullable {
+ return scanTypeNullFloat
+ }
+
+ return scanTypeFloat32
+
+ case DOUBLE:
+
+ if strings.ToLower(column.typeName) == "float" {
+ if column.nullable {
+ return scanTypeNullFloat
+ }
+
+ return scanTypeFloat32
+ }
+
+ if column.nullable {
+ return scanTypeNullFloat
+ }
+
+ return scanTypeFloat64
+ case DATE, TIME, DATETIME:
+ if column.nullable {
+ return scanTypeNullTime
+ }
+
+ return scanTypeTime
+
+ case DECIMAL, BINARY, VARBINARY, BLOB:
+ return scanTypeRawBytes
+
+ case CHAR, VARCHAR2, VARCHAR, CLOB:
+ if column.nullable {
+ return scanTypeNullString
+ }
+ return scanTypeString
+ }
+
+ return scanTypeUnknown
+}
+
+func (column *column) Length() (length int64, ok bool) {
+
+ switch column.colType {
+ case BINARY:
+ case VARBINARY:
+ case BLOB:
+ case CHAR:
+ case VARCHAR2:
+ case VARCHAR:
+ case CLOB:
+ return int64(column.prec), true
+ }
+
+ return int64(0), false
+}
+
+func (column *column) PrecisionScale() (precision, scale int64, ok bool) {
+ switch column.colType {
+ case DECIMAL:
+ return int64(column.prec), int64(column.scale), true
+ }
+
+ return int64(0), int64(0), false
+}
+
+func (column *column) getColumnData(bytes []byte, conn *DmConnection) (driver.Value, error) {
+ if bytes == nil {
+ return nil, nil
+ }
+
+ switch column.colType {
+ case BOOLEAN:
+ return bytes[0] != 0, nil
+ case BIT:
+ if strings.ToLower(column.typeName) == "boolean" {
+ return bytes[0] != 0, nil
+ }
+
+ return int8(bytes[0]), nil
+ case TINYINT:
+ return int8(bytes[0]), nil
+ case SMALLINT:
+ return Dm_build_1220.Dm_build_1317(bytes, 0), nil
+ case INT:
+ return Dm_build_1220.Dm_build_1322(bytes, 0), nil
+ case BIGINT:
+ return Dm_build_1220.Dm_build_1327(bytes, 0), nil
+ case REAL:
+ return Dm_build_1220.Dm_build_1332(bytes, 0), nil
+ case DOUBLE:
+
+ return Dm_build_1220.Dm_build_1336(bytes, 0), nil
+ case DATE, TIME, DATETIME, TIME_TZ, DATETIME_TZ:
+ return DB2G.toTime(bytes, column, conn)
+ case INTERVAL_DT:
+ return newDmIntervalDTByBytes(bytes).String(), nil
+ case INTERVAL_YM:
+ return newDmIntervalYMByBytes(bytes).String(), nil
+ case DECIMAL:
+ tmp, err := DB2G.toDmDecimal(bytes, column, conn)
+ if err != nil {
+ return nil, err
+ }
+ return tmp.String(), nil
+
+ case BINARY, VARBINARY:
+ return bytes, nil
+ case BLOB:
+ return DB2G.toDmBlob(bytes, column, conn), nil
+ case CHAR, VARCHAR2, VARCHAR:
+ return Dm_build_1220.Dm_build_1377(bytes, 0, len(bytes), conn.getServerEncoding(), conn), nil
+ case CLOB:
+ return DB2G.toDmClob(bytes, conn, column), nil
+ }
+
+ return string(bytes), nil
+}
+
+func emptyStringToNil(t int32) bool {
+ switch t {
+ case BOOLEAN, BIT, TINYINT, SMALLINT, INT, BIGINT, REAL, DOUBLE, DECIMAL,
+ DATE, TIME, DATETIME, INTERVAL_DT, INTERVAL_YM, TIME_TZ, DATETIME_TZ:
+ return true
+ default:
+ return false
+ }
+}
diff --git a/dmr/zzo.go b/dmr/zzo.go
new file mode 100644
index 0000000..3adf1f2
--- /dev/null
+++ b/dmr/zzo.go
@@ -0,0 +1,1389 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "strconv"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr/util"
+)
+
+const (
+ ARRAY_TYPE_SHORT = 1
+
+ ARRAY_TYPE_INTEGER = 2
+
+ ARRAY_TYPE_LONG = 3
+
+ ARRAY_TYPE_FLOAT = 4
+
+ ARRAY_TYPE_DOUBLE = 5
+)
+
+var TypeDataSV TypeData
+
+type InterfaceTypeData interface {
+ toBytes(x *TypeData, typeDesc *TypeDescriptor) ([]byte, error)
+}
+
+type TypeData struct {
+ m_dumyData interface{}
+
+ m_offset int
+
+ m_bufLen int
+
+ m_dataBuf []byte
+
+ m_objBlobDescBuf []byte
+
+ m_isFromBlob bool
+
+ m_packid int
+
+ m_objRefArr []interface{}
+}
+
+func newTypeData(val interface{}, dataBuf []byte) *TypeData {
+ td := new(TypeData).initTypeData()
+ td.m_dumyData = val
+ td.m_offset = 0
+ td.m_bufLen = 0
+ td.m_dataBuf = dataBuf
+ return td
+}
+
+func (td *TypeData) initTypeData() *TypeData {
+ td.m_dumyData = nil
+
+ td.m_offset = 0
+
+ td.m_bufLen = 0
+
+ td.m_dataBuf = nil
+
+ td.m_objBlobDescBuf = nil
+
+ td.m_isFromBlob = false
+
+ td.m_packid = -1
+
+ td.m_objRefArr = make([]interface{}, 0)
+
+ return td
+}
+
+func (sv TypeData) toStruct(objArr []interface{}, desc *TypeDescriptor) ([]TypeData, error) {
+ size := desc.getStrctMemSize()
+ retData := make([]TypeData, size)
+
+ for i := 0; i < size; i++ {
+
+ if objArr[i] == nil {
+ retData[i] = *newTypeData(objArr[i], nil)
+ continue
+ }
+
+ switch objArr[i].(type) {
+ case DmStruct, DmArray:
+ retData[i] = *newTypeData(objArr[i], nil)
+ default:
+ switch desc.m_fieldsObj[i].getDType() {
+ case CLASS, PLTYPE_RECORD:
+ tdArr, err := sv.toStruct(objArr[i].([]interface{}), &desc.m_fieldsObj[i])
+ if err != nil {
+ return nil, err
+ }
+
+ retData[i] = *newTypeData(newDmStructByTypeData(tdArr, &desc.m_fieldsObj[i]), nil)
+ case ARRAY, SARRAY:
+ tdArr, err := sv.toArray(objArr[i].([]interface{}), &desc.m_fieldsObj[i])
+ if err != nil {
+ return nil, err
+ }
+
+ retData[i] = *newTypeData(newDmArrayByTypeData(tdArr, &desc.m_fieldsObj[i]), nil)
+ default:
+ tdArr, err := sv.toMemberObj(objArr[i], &desc.m_fieldsObj[i])
+ if err != nil {
+ return nil, err
+ }
+ retData[i] = *tdArr
+ }
+
+ }
+ }
+ return retData, nil
+}
+
+func (sv TypeData) toArray(objArr []interface{}, desc *TypeDescriptor) ([]TypeData, error) {
+ size := len(objArr)
+ retData := make([]TypeData, size)
+ for i := 0; i < size; i++ {
+ if objArr[i] == nil {
+ retData[i] = *newTypeData(objArr[i], nil)
+ continue
+ }
+
+ switch objArr[i].(type) {
+ case DmStruct, DmArray:
+ retData[i] = *newTypeData(objArr[i], nil)
+ default:
+ switch desc.m_arrObj.getDType() {
+ case CLASS, PLTYPE_RECORD:
+ tdArr, err := sv.toStruct(objArr[i].([]interface{}), desc.m_arrObj)
+ if err != nil {
+ return nil, err
+ }
+ retData[i] = *newTypeData(newDmStructByTypeData(tdArr, desc.m_arrObj), nil)
+ case ARRAY, SARRAY:
+
+ tmp, ok := objArr[i].([]interface{})
+
+ if !ok && desc.m_arrObj.m_arrObj != nil {
+ obj, err := sv.makeupObjToArr(tmp[i], desc.m_arrObj)
+ if err != nil {
+ return nil, err
+ }
+ objArr[i] = obj
+ }
+
+ tdArr, err := sv.toArray(objArr[i].([]interface{}), desc.m_arrObj)
+ if err != nil {
+ return nil, err
+ }
+
+ retData[i] = *newTypeData(newDmArrayByTypeData(tdArr, desc.m_arrObj), nil)
+ default:
+ tdArr, err := sv.toMemberObj(objArr[i], desc.m_arrObj)
+ if err != nil {
+ return nil, err
+ }
+ retData[i] = *tdArr
+ }
+ }
+ }
+
+ return retData, nil
+}
+
+func (sv TypeData) makeupObjToArr(obj interface{}, objDesc *TypeDescriptor) ([]interface{}, error) {
+ arrType := objDesc.getDType()
+ dynamic := true
+ arrLen := 0
+ if arrType == SARRAY {
+ dynamic = false
+ arrLen = objDesc.m_length
+ }
+
+ subType := objDesc.m_arrObj.getDType()
+ if subType == BINARY || subType == VARBINARY || subType == BIT {
+
+ strRet := ""
+ switch v := obj.(type) {
+ case int:
+ strRet = strconv.FormatInt(int64(v), 2)
+ case int32:
+ strRet = strconv.FormatInt(int64(v), 2)
+ case int64:
+ strRet = strconv.FormatInt(v, 2)
+ case string:
+ strRet = v
+ default:
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+ var prec int
+ if dynamic {
+ prec = len(strRet)
+ } else {
+ prec = arrLen
+ }
+
+ ret := make([]interface{}, prec)
+ rs := Dm_build_1220.Dm_build_1433(strRet, objDesc.getServerEncoding(), objDesc.m_conn)
+ for i := 0; i < prec; i++ {
+ ret[i] = rs[i]
+ }
+
+ return ret, nil
+ }
+
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (sv TypeData) toMemberObj(mem interface{}, desc *TypeDescriptor) (*TypeData, error) {
+ var bs []byte
+ scale := desc.getScale()
+ prec := desc.getPrec()
+ dtype := desc.getDType()
+ if mem == nil {
+ return newTypeData(nil, nil), nil
+ }
+
+ param := new(parameter).InitParameter()
+ param.colType = int32(dtype)
+ param.prec = int32(prec)
+ param.scale = int32(scale)
+
+ var err error
+ bs, err = G2DB.fromObject(mem, *param, desc.m_conn)
+ if err != nil {
+ return nil, err
+ }
+
+ return newTypeData(mem, bs), nil
+}
+
+func (sv TypeData) typeDataToBytes(data *TypeData, desc *TypeDescriptor) ([]byte, error) {
+ dType := desc.getDType()
+ var innerData []byte
+ var err error
+ if nil == data.m_dumyData {
+ innerData = sv.realocBuffer(nil, 0, 2)
+ Dm_build_1220.Dm_build_1221(innerData, 0, byte(0))
+ Dm_build_1220.Dm_build_1221(innerData, 1, byte(0))
+ return innerData, nil
+ }
+
+ var result []byte
+ var offset int
+ switch dType {
+ case ARRAY:
+
+ innerData, err = sv.arrayToBytes(data.m_dumyData.(*DmArray), desc)
+ if err != nil {
+ return nil, err
+ }
+
+ result = sv.realocBuffer(nil, 0, len(innerData)+BYTE_SIZE+BYTE_SIZE)
+
+ Dm_build_1220.Dm_build_1221(result, 0, byte(0))
+ offset = 1
+
+ Dm_build_1220.Dm_build_1221(result, offset, byte(1))
+ offset += 1
+ copy(result[offset:offset+len(innerData)], innerData[:len(innerData)])
+ return result, nil
+
+ case SARRAY:
+
+ innerData, err = sv.sarrayToBytes(data.m_dumyData.(*DmArray), desc)
+ if err != nil {
+ return nil, err
+ }
+ result = sv.realocBuffer(nil, 0, len(innerData)+BYTE_SIZE+BYTE_SIZE)
+
+ Dm_build_1220.Dm_build_1221(result, 0, byte(0))
+ offset = 1
+
+ Dm_build_1220.Dm_build_1221(result, offset, byte(1))
+ offset += 1
+
+ copy(result[offset:offset+len(innerData)], innerData[:len(innerData)])
+ return result, nil
+
+ case CLASS:
+
+ innerData, err = sv.objToBytes(data.m_dumyData, desc)
+ if err != nil {
+ return nil, err
+ }
+ result = sv.realocBuffer(nil, 0, len(innerData)+BYTE_SIZE+BYTE_SIZE)
+
+ Dm_build_1220.Dm_build_1221(result, 0, byte(0))
+ offset = 1
+
+ Dm_build_1220.Dm_build_1221(result, offset, byte(1))
+ offset += 1
+ copy(result[offset:offset+len(innerData)], innerData[:len(innerData)])
+ return result, nil
+
+ case PLTYPE_RECORD:
+
+ innerData, err = sv.recordToBytes(data.m_dumyData.(*DmStruct), desc)
+ if err != nil {
+ return nil, err
+ }
+ result = sv.realocBuffer(nil, 0, len(innerData)+BYTE_SIZE+BYTE_SIZE)
+
+ Dm_build_1220.Dm_build_1221(result, 0, byte(0))
+ offset = 1
+
+ Dm_build_1220.Dm_build_1221(result, offset, byte(1))
+ offset += 1
+
+ copy(result[offset:offset+len(innerData)], innerData[:len(innerData)])
+ return result, nil
+
+ case BLOB, CLOB:
+ innerData, err = sv.convertLobToBytes(data.m_dumyData, int(desc.column.colType), desc.getServerEncoding())
+
+ result = sv.realocBuffer(nil, 0, len(innerData)+BYTE_SIZE+BYTE_SIZE)
+
+ Dm_build_1220.Dm_build_1221(result, 0, byte(0))
+ offset = 1
+
+ Dm_build_1220.Dm_build_1221(result, offset, byte(1))
+ offset += 1
+ copy(result[offset:offset+len(innerData)], innerData[:len(innerData)])
+ return result, nil
+
+ case BOOLEAN:
+ innerData = sv.realocBuffer(nil, 0, 2)
+ Dm_build_1220.Dm_build_1221(innerData, 0, byte(0))
+ if data.m_dataBuf != nil && len(data.m_dataBuf) > 0 {
+ Dm_build_1220.Dm_build_1221(innerData, 1, data.m_dataBuf[0])
+ } else {
+ Dm_build_1220.Dm_build_1221(innerData, 1, byte(0))
+ }
+ return innerData, nil
+
+ default:
+
+ innerData = data.m_dataBuf
+ result = sv.realocBuffer(nil, 0, len(innerData)+BYTE_SIZE+BYTE_SIZE+USINT_SIZE)
+
+ Dm_build_1220.Dm_build_1221(result, 0, byte(0))
+ offset = 1
+
+ Dm_build_1220.Dm_build_1221(result, offset, byte(1))
+ offset += 1
+
+ Dm_build_1220.Dm_build_1231(result, offset, int16(len(innerData)))
+ offset += 2
+
+ copy(result[offset:offset+len(innerData)], innerData[:len(innerData)])
+
+ return result, nil
+ }
+}
+
+func (sv TypeData) convertLobToBytes(value interface{}, dtype int, serverEncoding string) ([]byte, error) {
+ var tmp []byte
+ var ret []byte
+ if dtype == BLOB {
+ lob, ok := value.(DmBlob)
+ if ok {
+ l, err := lob.GetLength()
+ if err != nil {
+ return nil, err
+ }
+ tmp, err = lob.getBytes(1, int32(l))
+ if err != nil {
+ return nil, err
+ }
+
+ ret = make([]byte, l+ULINT_SIZE)
+ Dm_build_1220.Dm_build_1236(ret, 0, int32(l))
+ copy(ret[:ULINT_SIZE:ULINT_SIZE+l], tmp[:l])
+ return ret, nil
+ }
+
+ }
+
+ if dtype == CLOB {
+ lob, ok := value.(DmClob)
+ if ok {
+ l, err := lob.GetLength()
+ if err != nil {
+ return nil, err
+ }
+
+ subString, err := lob.getSubString(1, int32(l))
+ if err != nil {
+ return nil, err
+ }
+
+ tmp = Dm_build_1220.Dm_build_1433(subString, serverEncoding, nil)
+ ret = make([]byte, len(tmp)+ULINT_SIZE)
+ Dm_build_1220.Dm_build_1236(ret, 0, int32(l))
+ copy(ret[:ULINT_SIZE:ULINT_SIZE+l], tmp[:l])
+ }
+ return ret, nil
+ }
+
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+}
+
+func (sv TypeData) sarrayToBytes(data *DmArray, desc *TypeDescriptor) ([]byte, error) {
+ realLen := len(data.m_arrData)
+ results := make([][]byte, realLen)
+ var rdata []byte
+ var err error
+
+ if desc.getObjId() == 4 {
+ return sv.ctlnToBytes(data, desc)
+ }
+
+ totalLen := 0
+ for i := 0; i < realLen; i++ {
+ results[i], err = sv.typeDataToBytes(&data.m_arrData[i], desc.m_arrObj)
+ if err != nil {
+ return nil, err
+ }
+ totalLen += len(results[i])
+ }
+
+ totalLen += (ULINT_SIZE + ULINT_SIZE)
+ rdata = sv.realocBuffer(nil, 0, totalLen)
+ off := 0
+
+ Dm_build_1220.Dm_build_1236(rdata, off, int32(totalLen))
+ off += ULINT_SIZE
+
+ Dm_build_1220.Dm_build_1236(rdata, off, int32(data.m_arrDesc.getLength()))
+ off += ULINT_SIZE
+
+ for i := 0; i < realLen; i++ {
+ copy(rdata[off:off+len(results[i])], results[i][:len(results[i])])
+ off += len(results[i])
+ }
+
+ return rdata, nil
+}
+
+func (sv TypeData) ctlnToBytes(data *DmArray, desc *TypeDescriptor) ([]byte, error) {
+ results := make([][]byte, len(data.m_arrData))
+ var rdata []byte
+ var err error
+
+ var totalLen int
+ totalLen = BYTE_SIZE + ULINT_SIZE
+
+ totalLen += USINT_SIZE + USINT_SIZE + ULINT_SIZE
+
+ for i := 0; i < len(data.m_arrData); i++ {
+ results[i], err = sv.typeDataToBytes(&data.m_arrData[i], desc.m_arrObj)
+ if err != nil {
+ return nil, err
+ }
+ totalLen += len(results[i])
+ }
+
+ rdata = sv.realocBuffer(nil, 0, totalLen)
+
+ offset := 0
+
+ Dm_build_1220.Dm_build_1221(rdata, offset, byte(0))
+ offset += BYTE_SIZE
+
+ offset += ULINT_SIZE
+
+ Dm_build_1220.Dm_build_1231(rdata, offset, int16(desc.getCltnType()))
+ offset += USINT_SIZE
+
+ Dm_build_1220.Dm_build_1231(rdata, offset, int16(desc.m_arrObj.getDType()))
+ offset += USINT_SIZE
+
+ Dm_build_1220.Dm_build_1236(rdata, offset, int32(len(data.m_arrData)))
+ offset += ULINT_SIZE
+
+ for i := 0; i < len(data.m_arrData); i++ {
+ copy(rdata[offset:offset+len(results[i])], results[i][:len(results[i])])
+ offset += len(results[i])
+ }
+
+ Dm_build_1220.Dm_build_1236(rdata, BYTE_SIZE, int32(offset))
+
+ return rdata, nil
+}
+
+func (sv TypeData) arrayToBytes(data *DmArray, desc *TypeDescriptor) ([]byte, error) {
+ results := make([][]byte, len(data.m_arrData))
+ var rdata []byte
+ var err error
+ if desc.getObjId() == 4 {
+ return sv.ctlnToBytes(data, desc)
+ }
+
+ totalLen := 0
+ for i := 0; i < len(data.m_arrData); i++ {
+ results[i], err = sv.typeDataToBytes(&data.m_arrData[i], desc.m_arrObj)
+ if err != nil {
+ return nil, err
+ }
+ totalLen += len(results[i])
+ }
+
+ totalLen += (ULINT_SIZE + ULINT_SIZE + ULINT_SIZE + ULINT_SIZE + ULINT_SIZE)
+
+ total := data.m_objCount + data.m_strCount
+ if total > 0 {
+ totalLen += USINT_SIZE * total
+ }
+
+ rdata = sv.realocBuffer(nil, 0, totalLen)
+
+ Dm_build_1220.Dm_build_1236(rdata, 0, int32(totalLen))
+ offset := ULINT_SIZE
+
+ Dm_build_1220.Dm_build_1236(rdata, offset, int32(len(data.m_arrData)))
+ offset += ULINT_SIZE
+
+ Dm_build_1220.Dm_build_1236(rdata, offset, 0)
+ offset += ULINT_SIZE
+
+ Dm_build_1220.Dm_build_1236(rdata, offset, int32(data.m_objCount))
+ offset += ULINT_SIZE
+
+ Dm_build_1220.Dm_build_1236(rdata, offset, int32(data.m_strCount))
+ offset += ULINT_SIZE
+
+ for i := 0; i < total; i++ {
+ Dm_build_1220.Dm_build_1236(rdata, offset, int32(data.m_objStrOffs[i]))
+ offset += ULINT_SIZE
+ }
+
+ for i := 0; i < len(data.m_arrData); i++ {
+ copy(rdata[offset:offset+len(results[i])], results[i][:len(results[i])])
+ offset += len(results[i])
+ }
+
+ return rdata, nil
+}
+
+func (sv TypeData) objToBytes(data interface{}, desc *TypeDescriptor) ([]byte, error) {
+
+ switch data.(type) {
+ case DmArray:
+ return sv.arrayToBytes(data.(*DmArray), desc)
+ default:
+ return sv.structToBytes(data.(*DmStruct), desc)
+ }
+}
+
+func (sv TypeData) structToBytes(data *DmStruct, desc *TypeDescriptor) ([]byte, error) {
+ size := desc.getStrctMemSize()
+ results := make([][]byte, size)
+ var rdata []byte
+ var err error
+
+ totalLen := 0
+ for i := 0; i < size; i++ {
+ results[i], err = sv.typeDataToBytes(&data.m_attribs[i], &desc.m_fieldsObj[i])
+ if err != nil {
+ return nil, err
+ }
+ totalLen += len(results[i])
+ }
+
+ totalLen += (BYTE_SIZE + ULINT_SIZE)
+
+ rdata = sv.realocBuffer(nil, 0, totalLen)
+ offset := 0
+
+ Dm_build_1220.Dm_build_1221(rdata, offset, byte(0))
+ offset += BYTE_SIZE
+
+ Dm_build_1220.Dm_build_1236(rdata, offset, int32(totalLen))
+ offset += ULINT_SIZE
+
+ for i := 0; i < size; i++ {
+ copy(rdata[offset:offset+len(results[i])], results[i][:len(results[i])])
+ offset += len(results[i])
+ }
+
+ return rdata, nil
+}
+
+func (sv TypeData) recordToBytes(data *DmStruct, desc *TypeDescriptor) ([]byte, error) {
+ size := desc.getStrctMemSize()
+ results := make([][]byte, size)
+ var rdata []byte
+ var err error
+
+ totalLen := 0
+ for i := 0; i < size; i++ {
+ results[i], err = sv.typeDataToBytes(&data.m_attribs[i], &desc.m_fieldsObj[i])
+ if err != nil {
+ return nil, err
+ }
+ totalLen += len(results[i])
+ }
+
+ totalLen += ULINT_SIZE
+ rdata = sv.realocBuffer(nil, 0, totalLen)
+ Dm_build_1220.Dm_build_1236(rdata, 0, int32(totalLen))
+
+ offset := ULINT_SIZE
+ for i := 0; i < desc.getStrctMemSize(); i++ {
+ copy(rdata[offset:offset+len(results[i])], results[i][:len(results[i])])
+ offset += len(results[i])
+ }
+
+ return rdata, nil
+}
+
+func (sv TypeData) bytesToBlob(val []byte, out *TypeData, desc *TypeDescriptor) (*TypeData, error) {
+ offset := out.m_offset
+ l := Dm_build_1220.Dm_build_1322(val, offset)
+ offset += ULINT_SIZE
+
+ tmp := Dm_build_1220.Dm_build_1371(val, offset, int(l))
+ offset += int(l)
+ out.m_offset = offset
+
+ return newTypeData(newBlobOfLocal(tmp, desc.m_conn), tmp), nil
+}
+
+func (sv TypeData) bytesToClob(val []byte, out *TypeData, desc *TypeDescriptor, serverEncoding string) (*TypeData, error) {
+ offset := out.m_offset
+ l := Dm_build_1220.Dm_build_1322(val, offset)
+ offset += ULINT_SIZE
+
+ tmp := Dm_build_1220.Dm_build_1371(val, offset, int(l))
+ offset += int(l)
+ out.m_offset = offset
+
+ return newTypeData(newClobOfLocal(Dm_build_1220.Dm_build_1377(tmp, 0, len(tmp), serverEncoding, desc.m_conn), desc.m_conn), tmp), nil
+}
+
+func (sv TypeData) bytesToTypeData(val []byte, out *TypeData, desc *TypeDescriptor) (*TypeData, error) {
+ offset := out.m_offset
+
+ offset += 1
+
+ null_flag := Dm_build_1220.Dm_build_1313(val, offset)
+ offset += 1
+
+ out.m_offset = offset
+
+ if desc.getDType() == BOOLEAN {
+ b := false
+ if null_flag != byte(0) {
+ b = true
+ }
+
+ tmp := Dm_build_1220.Dm_build_1371(val, offset-1, 1)
+ return newTypeData(b, tmp), nil
+ }
+
+ var retObj interface{}
+ var err error
+ var retDataBuf []byte
+ switch desc.getDType() {
+ case CLASS:
+ if null_flag&byte(1) != byte(0) {
+ retObj, err = sv.bytesToObj(val, out, desc)
+ if err != nil {
+ return nil, err
+ }
+
+ if out.m_offset > offset {
+ retDataBuf = Dm_build_1220.Dm_build_1371(val, offset, out.m_offset-offset)
+ }
+
+ return newTypeData(retObj, retDataBuf), nil
+ } else {
+ return newTypeData(nil, nil), nil
+ }
+
+ case ARRAY:
+ if (null_flag & byte(1)) != byte(0) {
+ retObj, err = sv.bytesToArray(val, out, desc)
+ if err != nil {
+ return nil, err
+ }
+
+ if out.m_offset > offset {
+ retDataBuf = Dm_build_1220.Dm_build_1371(val, offset, out.m_offset-offset)
+ }
+
+ return newTypeData(retObj, retDataBuf), nil
+ } else {
+ return newTypeData(nil, nil), nil
+ }
+
+ case PLTYPE_RECORD:
+ if (null_flag & byte(1)) != byte(0) {
+ retObj, err = sv.bytesToRecord(val, out, desc)
+ if err != nil {
+ return nil, err
+ }
+
+ if out.m_offset > offset {
+ retDataBuf = Dm_build_1220.Dm_build_1371(val, offset, out.m_offset-offset)
+ }
+
+ return newTypeData(retObj, retDataBuf), nil
+ } else {
+ return newTypeData(nil, nil), nil
+ }
+
+ case SARRAY:
+ if (null_flag & byte(1)) != byte(0) {
+ retObj, err = sv.bytesToSArray(val, out, desc)
+ if err != nil {
+ return nil, err
+ }
+
+ if out.m_offset > offset {
+ retDataBuf = Dm_build_1220.Dm_build_1371(val, offset, out.m_offset-offset)
+ }
+
+ return newTypeData(retObj, retDataBuf), nil
+ } else {
+ return newTypeData(nil, nil), nil
+ }
+
+ case BLOB:
+ if null_flag&byte(1) != byte(0) {
+ return sv.bytesToBlob(val, out, desc)
+ } else {
+ return newTypeData(nil, nil), nil
+ }
+
+ case CLOB:
+ if null_flag&byte(1) != byte(0) {
+ return sv.bytesToClob(val, out, desc, desc.getServerEncoding())
+ } else {
+ return newTypeData(nil, nil), nil
+ }
+
+ default:
+ if null_flag&byte(1) != byte(0) {
+ return sv.convertBytes2BaseData(val, out, desc)
+ } else {
+ return newTypeData(nil, nil), nil
+ }
+
+ }
+}
+
+func (sv TypeData) checkObjExist(val []byte, out *TypeData) bool {
+ offset := out.m_offset
+ exist_flag := Dm_build_1220.Dm_build_1313(val, offset)
+ offset += 1
+
+ out.m_offset = offset
+
+ if exist_flag == byte(1) {
+ return true
+ }
+
+ out.m_offset += ULINT_SIZE
+ return false
+}
+
+func (sv TypeData) findObjByPackId(val []byte, out *TypeData) (*DmStruct, error) {
+ offset := out.m_offset
+
+ pack_id := int(Dm_build_1220.Dm_build_1322(val, offset))
+ offset += ULINT_SIZE
+
+ out.m_offset = offset
+
+ if pack_id < 0 || pack_id > out.m_packid {
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+
+ return out.m_objRefArr[pack_id].(*DmStruct), nil
+}
+
+func (sv TypeData) addObjToRefArr(out *TypeData, objToAdd interface{}) {
+ out.m_objRefArr = append(out.m_objRefArr, objToAdd)
+ out.m_packid++
+}
+
+func (sv TypeData) checkObjClnt(desc *TypeDescriptor) bool {
+ return desc.m_objId == 4
+}
+
+func (sv TypeData) bytesToObj_EXACT(val []byte, out *TypeData, desc *TypeDescriptor) (*DmStruct, error) {
+ strOut := newDmStructByTypeData(nil, desc)
+ var sub_desc *TypeDescriptor
+ offset := out.m_offset
+
+ size := desc.getStrctMemSize()
+
+ out.m_offset = offset
+
+ strOut.m_attribs = make([]TypeData, size)
+ for i := 0; i < size; i++ {
+ sub_desc = &desc.m_fieldsObj[i]
+ tmp, err := sv.bytesToTypeData(val, out, sub_desc)
+ if err != nil {
+ return nil, err
+ }
+ strOut.m_attribs[i] = *tmp
+ }
+
+ strOut.m_dataBuf = Dm_build_1220.Dm_build_1371(val, offset, out.m_offset-offset)
+
+ return strOut, nil
+}
+
+func (sv TypeData) bytesToNestTab(val []byte, out *TypeData, desc *TypeDescriptor) (*DmArray, error) {
+ offset := out.m_offset
+
+ offset += USINT_SIZE
+
+ count := Dm_build_1220.Dm_build_1322(val, offset)
+ offset += ULINT_SIZE
+
+ out.m_offset = offset
+
+ arrOut := newDmArrayByTypeData(nil, desc)
+ arrOut.m_itemCount = int(count)
+ arrOut.m_arrData = make([]TypeData, count)
+ for i := 0; i < int(count); i++ {
+ tmp, err := sv.bytesToTypeData(val, out, desc.m_arrObj)
+ if err != nil {
+ return nil, err
+ }
+ arrOut.m_arrData[i] = *tmp
+ }
+
+ arrOut.m_dataBuf = Dm_build_1220.Dm_build_1371(val, offset, out.m_offset-offset)
+
+ return arrOut, nil
+}
+
+func (sv TypeData) bytesToClnt(val []byte, out *TypeData, desc *TypeDescriptor) (*DmArray, error) {
+ var array *DmArray
+
+ offset := out.m_offset
+
+ cltn_type := Dm_build_1220.Dm_build_1317(val, offset)
+ offset += USINT_SIZE
+
+ out.m_offset = offset
+ switch cltn_type {
+ case CLTN_TYPE_IND_TABLE:
+ return nil, ECGO_UNSUPPORTED_TYPE.throw()
+
+ case CLTN_TYPE_NST_TABLE, CLTN_TYPE_VARRAY:
+ return sv.bytesToNestTab(val, out, desc)
+ }
+
+ return array, nil
+}
+
+func (sv TypeData) bytesToObj(val []byte, out *TypeData, desc *TypeDescriptor) (interface{}, error) {
+ var retObj interface{}
+ var err error
+ if out == nil {
+ out = newTypeData(nil, nil)
+ }
+
+ if sv.checkObjExist(val, out) {
+ retObj, err = sv.findObjByPackId(val, out)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ sv.addObjToRefArr(out, retObj)
+ }
+
+ if sv.checkObjClnt(desc) {
+ retObj, err = sv.bytesToClnt(val, out, desc)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ retObj, err = sv.bytesToObj_EXACT(val, out, desc)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return retObj, nil
+}
+
+func (sv TypeData) bytesToArray(val []byte, out *TypeData, desc *TypeDescriptor) (*DmArray, error) {
+ arrOut := newDmArrayByTypeData(nil, desc)
+ if out == nil {
+ out = newTypeData(nil, nil)
+ }
+
+ offset := out.m_offset
+
+ arrOut.m_bufLen = int(Dm_build_1220.Dm_build_1322(val, offset))
+ offset += 4
+
+ arrOut.m_itemCount = int(Dm_build_1220.Dm_build_1322(val, offset))
+ offset += ULINT_SIZE
+
+ arrOut.m_itemSize = int(Dm_build_1220.Dm_build_1322(val, offset))
+ offset += ULINT_SIZE
+
+ arrOut.m_objCount = int(Dm_build_1220.Dm_build_1322(val, offset))
+ offset += ULINT_SIZE
+
+ arrOut.m_strCount = int(Dm_build_1220.Dm_build_1322(val, offset))
+ offset += ULINT_SIZE
+
+ total := arrOut.m_objCount + arrOut.m_strCount
+ arrOut.m_objStrOffs = make([]int, total)
+ for i := 0; i < total; i++ {
+ arrOut.m_objStrOffs[i] = int(Dm_build_1220.Dm_build_1322(val, offset))
+ offset += 4
+ }
+
+ out.m_offset = offset
+
+ arrOut.m_arrData = make([]TypeData, arrOut.m_itemCount)
+ for i := 0; i < arrOut.m_itemCount; i++ {
+ tmp, err := sv.bytesToTypeData(val, out, desc.m_arrObj)
+ if err != nil {
+ return nil, err
+ }
+ arrOut.m_arrData[i] = *tmp
+ }
+
+ arrOut.m_dataBuf = Dm_build_1220.Dm_build_1371(val, offset, out.m_offset-offset)
+
+ return arrOut, nil
+}
+
+func (sv TypeData) bytesToSArray(val []byte, out *TypeData, desc *TypeDescriptor) (*DmArray, error) {
+ if out == nil {
+ out = newTypeData(nil, nil)
+ }
+
+ offset := out.m_offset
+
+ arrOut := newDmArrayByTypeData(nil, desc)
+ arrOut.m_bufLen = int(Dm_build_1220.Dm_build_1322(val, offset))
+ offset += ULINT_SIZE
+
+ arrOut.m_itemCount = int(Dm_build_1220.Dm_build_1322(val, offset))
+ offset += ULINT_SIZE
+
+ out.m_offset = offset
+
+ arrOut.m_arrData = make([]TypeData, arrOut.m_itemCount)
+ for i := 0; i < arrOut.m_itemCount; i++ {
+ tmp, err := sv.bytesToTypeData(val, out, desc.m_arrObj)
+ if err != nil {
+ return nil, err
+ }
+ arrOut.m_arrData[i] = *tmp
+ }
+
+ arrOut.m_dataBuf = Dm_build_1220.Dm_build_1371(val, offset, out.m_offset-offset)
+
+ return arrOut, nil
+}
+
+func (sv TypeData) bytesToRecord(val []byte, out *TypeData, desc *TypeDescriptor) (*DmStruct, error) {
+ if out == nil {
+ out = newTypeData(nil, nil)
+ }
+
+ offset := out.m_offset
+
+ strOut := newDmStructByTypeData(nil, desc)
+ strOut.m_bufLen = int(Dm_build_1220.Dm_build_1322(val, offset))
+ offset += ULINT_SIZE
+
+ out.m_offset = offset
+
+ strOut.m_attribs = make([]TypeData, desc.getStrctMemSize())
+ for i := 0; i < desc.getStrctMemSize(); i++ {
+ tmp, err := sv.bytesToTypeData(val, out, desc.m_arrObj)
+ if err != nil {
+ return nil, err
+ }
+ strOut.m_attribs[i] = *tmp
+ }
+
+ strOut.m_dataBuf = Dm_build_1220.Dm_build_1371(val, offset, out.m_offset-offset)
+
+ return strOut, nil
+}
+
+func (sv TypeData) objBlob_GetChkBuf(buf []byte, typeData *TypeData) {
+
+ offset := 4
+
+ l := int(Dm_build_1220.Dm_build_1322(buf, offset))
+ offset += ULINT_SIZE
+
+ typeData.m_objBlobDescBuf = Dm_build_1220.Dm_build_1371(buf, offset, l)
+ offset += l
+
+ typeData.m_isFromBlob = true
+
+ typeData.m_offset = offset
+}
+
+func (sv TypeData) objBlobToObj(lob *DmBlob, desc *TypeDescriptor) (interface{}, error) {
+ typeData := newTypeData(nil, nil)
+ loblen, err := lob.GetLength()
+ if err != nil {
+ return nil, err
+ }
+
+ buf, err := lob.getBytes(1, int32(loblen))
+ if err != nil {
+ return nil, err
+ }
+
+ sv.objBlob_GetChkBuf(buf, typeData)
+
+ return sv.bytesToObj(buf, typeData, desc)
+}
+
+func (sv TypeData) objBlobToBytes(lobBuf []byte, desc *TypeDescriptor) ([]byte, error) {
+ l := len(lobBuf)
+ offset := 0
+
+ magic := Dm_build_1220.Dm_build_1322(lobBuf, offset)
+ offset += ULINT_SIZE
+
+ if OBJ_BLOB_MAGIC != magic {
+ return nil, ECGO_INVALID_OBJ_BLOB.throw()
+ }
+
+ descLen := int(Dm_build_1220.Dm_build_1322(lobBuf, offset))
+ offset += ULINT_SIZE
+ descBuf := Dm_build_1220.Dm_build_1371(lobBuf, offset, descLen)
+ tmp, err := desc.getClassDescChkInfo()
+ if err != nil {
+ return nil, err
+ }
+ if !util.SliceEquals(descBuf, tmp) {
+ return nil, ECGO_INVALID_OBJ_BLOB.throw()
+ }
+ offset += descLen
+
+ ret := make([]byte, l-offset)
+ copy(ret[:len(ret)], lobBuf[offset:offset+len(ret)])
+ return ret, nil
+}
+
+func (sv TypeData) realocBuffer(oldBuf []byte, offset int, needLen int) []byte {
+ var retBuf []byte
+
+ if oldBuf == nil {
+ return make([]byte, needLen)
+ } else if needLen+offset > len(oldBuf) {
+ retBuf = make([]byte, len(oldBuf)+needLen)
+ copy(retBuf[:offset], oldBuf[:offset])
+ } else {
+ retBuf = oldBuf
+ }
+
+ return retBuf
+}
+
+func (sv TypeData) convertBytes2BaseData(val []byte, out *TypeData, desc *TypeDescriptor) (*TypeData, error) {
+ offset := out.m_offset
+ isNull := false
+ valueLen := int(Dm_build_1220.Dm_build_1344(val, offset))
+ offset += USINT_SIZE
+
+ if valueLen == int(Dm_build_650) {
+ valueLen = 0
+ isNull = true
+ }
+
+ if -1 == valueLen {
+ valueLen = int(Dm_build_1220.Dm_build_1322(val, offset))
+ offset += ULINT_SIZE
+ }
+
+ if isNull {
+ out.m_offset = offset
+ return newTypeData(nil, nil), nil
+ }
+
+ var tmpObj interface{}
+ var err error
+ temp := Dm_build_1220.Dm_build_1371(val, offset, valueLen)
+ offset += valueLen
+ out.m_offset = offset
+
+ tmpObj, err = DB2G.toObject(temp, desc.column, desc.m_conn)
+ if err != nil {
+ return nil, err
+ }
+ return newTypeData(tmpObj, temp), nil
+}
+
+func (td *TypeData) toJavaArray(arr *DmArray, index int64, l int, dType int) (interface{}, error) {
+ if arr.m_objArray != nil {
+ return arr.m_objArray, nil
+ }
+
+ var nr = make([]interface{}, l)
+ var tempData *TypeData
+ switch dType {
+ case CHAR, VARCHAR, VARCHAR2:
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil && tempData.m_dumyData != nil {
+ nr[i] = tempData.m_dumyData
+ }
+ }
+ case BIT, TINYINT:
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil && tempData.m_dumyData != nil {
+ nr[i] = tempData.m_dumyData
+ } else {
+ nr[i] = nil
+ }
+ }
+
+ case BINARY, VARBINARY:
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil && tempData.m_dumyData != nil {
+ nr[i] = tempData.m_dumyData
+ }
+ }
+
+ case BOOLEAN:
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil && tempData.m_dumyData != nil {
+ nr[i] = tempData.m_dumyData
+ } else {
+ nr[i] = nil
+ }
+ }
+
+ case SMALLINT:
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil && tempData.m_dumyData != nil {
+ nr[i] = tempData.m_dumyData
+ } else {
+ nr[i] = nil
+ }
+ }
+
+ case INT:
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil && tempData.m_dumyData != nil {
+ nr[i] = tempData.m_dumyData
+ } else {
+ nr[i] = nil
+ }
+ }
+
+ case BIGINT:
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil && tempData.m_dumyData != nil {
+ nr[i] = tempData.m_dumyData
+ } else {
+ nr[i] = nil
+ }
+ }
+
+ case DECIMAL:
+
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil && tempData.m_dumyData != nil {
+ nr[i] = tempData.m_dumyData
+ }
+ }
+ case REAL:
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil && tempData.m_dumyData != nil {
+ nr[i] = tempData.m_dumyData
+ } else {
+ nr[i] = nil
+ }
+ }
+
+ case DOUBLE:
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil && tempData.m_dumyData != nil {
+ nr[i] = tempData.m_dumyData
+ } else {
+ nr[i] = nil
+ }
+ }
+
+ case DATE, TIME, DATETIME, TIME_TZ, DATETIME_TZ:
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil && tempData.m_dumyData != nil {
+ nr[i] = tempData.m_dumyData
+ }
+ }
+
+ case INTERVAL_YM:
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil && tempData.m_dumyData != nil {
+ nr[i] = tempData.m_dumyData
+ }
+ }
+
+ case INTERVAL_DT:
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil && tempData.m_dumyData != nil {
+ nr[i] = tempData.m_dumyData
+ }
+ }
+
+ case PLTYPE_RECORD, CLASS, ARRAY, SARRAY:
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil {
+ nr[i] = tempData.m_dumyData
+ }
+ }
+
+ case BLOB:
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil && tempData.m_dumyData != nil {
+ nr[i] = tempData.m_dumyData
+ }
+ }
+
+ case CLOB:
+ for i := 0; i < l; i++ {
+ tempData = &arr.m_arrData[index+int64(i)]
+ if tempData != nil && tempData.m_dumyData != nil {
+ nr[i] = tempData.m_dumyData
+ }
+ }
+
+ default:
+ return nil, ECGO_UNSUPPORTED_TYPE.throw()
+ }
+
+ return nr, nil
+}
+
+func (td *TypeData) toNumericArray(arr *DmArray, index int64, l int, flag int) (interface{}, error) {
+ if nil == arr.m_objArray {
+ return nil, nil
+ }
+
+ var retObj interface{}
+ switch arr.m_objArray.(type) {
+ case []int16:
+ if flag == ARRAY_TYPE_SHORT {
+ ret := make([]int16, l)
+ copy(ret[:l], arr.m_objArray.([]int16)[index:index+int64(l)])
+ retObj = ret
+ }
+ case []int:
+ if flag == ARRAY_TYPE_INTEGER {
+ ret := make([]int, l)
+ copy(ret[:l], arr.m_objArray.([]int)[index:index+int64(l)])
+ retObj = ret
+ }
+ case []int64:
+ if flag == ARRAY_TYPE_LONG {
+ ret := make([]int64, l)
+ copy(ret[:l], arr.m_objArray.([]int64)[index:index+int64(l)])
+ retObj = ret
+ }
+ case []float32:
+ if flag == ARRAY_TYPE_FLOAT {
+ ret := make([]float32, l)
+ copy(ret[:l], arr.m_objArray.([]float32)[index:index+int64(l)])
+ retObj = ret
+ }
+ case []float64:
+ if flag == ARRAY_TYPE_DOUBLE {
+ ret := make([]float64, l)
+ copy(ret[:l], arr.m_objArray.([]float64)[index:index+int64(l)])
+ retObj = ret
+ }
+ default:
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ }
+
+ return retObj, nil
+}
+
+func (td *TypeData) toJavaArrayByDmStruct(st *DmStruct) ([]interface{}, error) {
+ attrsData := st.getAttribsTypeData()
+ if nil == st.getAttribsTypeData() || len(st.getAttribsTypeData()) <= 0 {
+ return nil, nil
+ }
+
+ fields := st.m_strctDesc.getItemsDesc()
+ if len(attrsData) != len(fields) {
+ return nil, ECGO_STRUCT_MEM_NOT_MATCH.throw()
+ }
+
+ out := make([]interface{}, len(fields))
+ for i := 0; i < len(fields); i++ {
+ out[i] = attrsData[i].m_dumyData
+ }
+
+ return out, nil
+}
+
+func (td *TypeData) toBytesFromDmArray(x *DmArray, typeDesc *TypeDescriptor) ([]byte, error) {
+ var err error
+ desc, err := typeDesc.getClassDescChkInfo()
+ if err != nil {
+ return nil, err
+ }
+ var data []byte
+ switch typeDesc.getDType() {
+ case ARRAY:
+ data, err = TypeDataSV.arrayToBytes(x, typeDesc)
+ if err != nil {
+ return nil, err
+ }
+ case SARRAY:
+ data, err = TypeDataSV.sarrayToBytes(x, typeDesc)
+ if err != nil {
+ return nil, err
+ }
+ case PLTYPE_RECORD:
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ case CLASS:
+ data, err = TypeDataSV.objToBytes(x, typeDesc)
+ if err != nil {
+ return nil, err
+ }
+ }
+ ret := make([]byte, ULINT_SIZE+ULINT_SIZE+len(desc)+len(data))
+ Dm_build_1220.Dm_build_1236(ret, 0, OBJ_BLOB_MAGIC)
+ Dm_build_1220.Dm_build_1236(ret, ULINT_SIZE, int32(len(desc)))
+ copy(ret[ULINT_SIZE+ULINT_SIZE:ULINT_SIZE+ULINT_SIZE+len(desc)], desc[:len(desc)])
+ copy(ret[ULINT_SIZE+ULINT_SIZE:ULINT_SIZE+ULINT_SIZE+len(desc)+len(data)], desc[:len(data)])
+ return ret, nil
+}
+
+func (td *TypeData) toBytesFromDmStruct(x *DmStruct, typeDesc *TypeDescriptor) ([]byte, error) {
+ var err error
+ desc, err := typeDesc.getClassDescChkInfo()
+ if err != nil {
+ return nil, err
+ }
+ var data []byte
+ switch typeDesc.getDType() {
+ case ARRAY:
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ case SARRAY:
+ return nil, ECGO_DATA_CONVERTION_ERROR.throw()
+ case PLTYPE_RECORD:
+ data, err = TypeDataSV.recordToBytes(x, typeDesc)
+ if err != nil {
+ return nil, err
+ }
+ case CLASS:
+ data, err = TypeDataSV.objToBytes(x, typeDesc)
+ if err != nil {
+ return nil, err
+ }
+ }
+ ret := make([]byte, ULINT_SIZE+ULINT_SIZE+len(desc)+len(data))
+ Dm_build_1220.Dm_build_1236(ret, 0, OBJ_BLOB_MAGIC)
+ Dm_build_1220.Dm_build_1236(ret, ULINT_SIZE, int32(len(desc)))
+ copy(ret[ULINT_SIZE+ULINT_SIZE:ULINT_SIZE+ULINT_SIZE+len(desc)], desc[:len(desc)])
+ copy(ret[ULINT_SIZE+ULINT_SIZE:ULINT_SIZE+ULINT_SIZE+len(desc)+len(data)], desc[:len(data)])
+ return ret, nil
+}
diff --git a/dmr/zzp.go b/dmr/zzp.go
new file mode 100644
index 0000000..6dc4a8c
--- /dev/null
+++ b/dmr/zzp.go
@@ -0,0 +1,763 @@
+/*
+ * Copyright (c) 2000-2018, 达梦数据库有限公司.
+ * All rights reserved.
+ */
+package dmr
+
+import (
+ "database/sql/driver"
+)
+
+const (
+ OBJ_BLOB_MAGIC = 78111999
+
+ CLTN_TYPE_IND_TABLE = 3
+
+ CLTN_TYPE_NST_TABLE = 2
+
+ CLTN_TYPE_VARRAY = 1
+)
+
+type TypeDescriptor struct {
+ column *column
+
+ m_sqlName *sqlName
+
+ m_objId int
+
+ m_objVersion int
+
+ m_outerId int
+
+ m_outerVer int
+
+ m_subId int
+
+ m_cltnType int
+
+ m_maxCnt int
+
+ m_length int
+
+ m_size int
+
+ m_conn *DmConnection
+
+ m_serverEncoding string
+
+ m_arrObj *TypeDescriptor
+
+ m_fieldsObj []TypeDescriptor
+
+ m_descBuf []byte
+}
+
+func newTypeDescriptorWithFulName(fulName string, conn *DmConnection) *TypeDescriptor {
+ td := new(TypeDescriptor)
+ td.init()
+ td.m_sqlName = newSqlNameByFulName(fulName)
+ td.m_conn = conn
+ return td
+}
+
+func newTypeDescriptor(conn *DmConnection) *TypeDescriptor {
+ td := new(TypeDescriptor)
+ td.init()
+ td.m_sqlName = newSqlNameByConn(conn)
+ td.m_conn = conn
+ return td
+}
+
+func (typeDescriptor *TypeDescriptor) init() {
+ typeDescriptor.column = new(column).InitColumn()
+
+ typeDescriptor.m_sqlName = nil
+
+ typeDescriptor.m_objId = -1
+
+ typeDescriptor.m_objVersion = -1
+
+ typeDescriptor.m_outerId = 0
+
+ typeDescriptor.m_outerVer = 0
+
+ typeDescriptor.m_subId = 0
+
+ typeDescriptor.m_cltnType = 0
+
+ typeDescriptor.m_maxCnt = 0
+
+ typeDescriptor.m_length = 0
+
+ typeDescriptor.m_size = 0
+
+ typeDescriptor.m_conn = nil
+
+ typeDescriptor.m_serverEncoding = ""
+
+ typeDescriptor.m_arrObj = nil
+
+ typeDescriptor.m_fieldsObj = nil
+
+ typeDescriptor.m_descBuf = nil
+}
+
+func (typeDescriptor *TypeDescriptor) parseDescByName() error {
+ sql := "BEGIN ? = SF_DESCRIBE_TYPE(?); END;"
+
+ params := make([]driver.Value, 2)
+ params[1] = typeDescriptor.m_sqlName.m_fulName
+
+ rs, err := typeDescriptor.m_conn.query(sql, params)
+ if err != nil {
+ return err
+ }
+ rs.close()
+ l, err := params[0].(*DmBlob).GetLength()
+ if err != nil {
+ return err
+ }
+
+ buf, err := params[0].(*DmBlob).getBytes(1, int32(l))
+ if err != nil {
+ return err
+ }
+ typeDescriptor.m_serverEncoding = typeDescriptor.m_conn.getServerEncoding()
+ err = typeDescriptor.unpack(Dm_build_5(buf))
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (typeDescriptor *TypeDescriptor) getFulName() (string, error) {
+ return typeDescriptor.m_sqlName.getFulName()
+}
+
+func (typeDescriptor *TypeDescriptor) getDType() int {
+ return int(typeDescriptor.column.colType)
+}
+
+func (typeDescriptor *TypeDescriptor) getPrec() int {
+ return int(typeDescriptor.column.prec)
+}
+
+func (typeDescriptor *TypeDescriptor) getScale() int {
+ return int(typeDescriptor.column.scale)
+}
+
+func (typeDescriptor *TypeDescriptor) getServerEncoding() string {
+ if typeDescriptor.m_serverEncoding == "" {
+ return typeDescriptor.m_conn.getServerEncoding()
+ } else {
+ return typeDescriptor.m_serverEncoding
+ }
+}
+
+func (typeDescriptor *TypeDescriptor) getObjId() int {
+ return typeDescriptor.m_objId
+}
+
+func (typeDescriptor *TypeDescriptor) getStaticArrayLength() int {
+ return typeDescriptor.m_length
+}
+
+func (typeDescriptor *TypeDescriptor) getStrctMemSize() int {
+ return typeDescriptor.m_size
+}
+
+func (typeDescriptor *TypeDescriptor) getOuterId() int {
+ return typeDescriptor.m_outerId
+}
+
+func (typeDescriptor *TypeDescriptor) getCltnType() int {
+ return typeDescriptor.m_cltnType
+}
+
+func (typeDescriptor *TypeDescriptor) getMaxCnt() int {
+ return typeDescriptor.m_maxCnt
+}
+
+func getPackSize(typeDesc *TypeDescriptor) (int, error) {
+ len := 0
+
+ switch typeDesc.column.colType {
+ case ARRAY, SARRAY:
+ return getPackArraySize(typeDesc)
+
+ case CLASS:
+ return getPackClassSize(typeDesc)
+
+ case PLTYPE_RECORD:
+ return getPackRecordSize(typeDesc)
+ }
+
+ len += ULINT_SIZE
+
+ len += ULINT_SIZE
+
+ len += ULINT_SIZE
+
+ return len, nil
+}
+
+func pack(typeDesc *TypeDescriptor, msg *Dm_build_0) error {
+ switch typeDesc.column.colType {
+ case ARRAY, SARRAY:
+ return packArray(typeDesc, msg)
+ case CLASS:
+ return packClass(typeDesc, msg)
+ case PLTYPE_RECORD:
+ return packRecord(typeDesc, msg)
+ }
+
+ msg.Dm_build_51(typeDesc.column.colType)
+
+ msg.Dm_build_51(typeDesc.column.prec)
+
+ msg.Dm_build_51(typeDesc.column.scale)
+ return nil
+}
+
+func getPackArraySize(arrDesc *TypeDescriptor) (int, error) {
+ l := 0
+
+ l += ULINT_SIZE
+
+ name := arrDesc.m_sqlName.m_name
+ l += USINT_SIZE
+
+ serverEncoding := arrDesc.getServerEncoding()
+ ret := Dm_build_1220.Dm_build_1433(name, serverEncoding, arrDesc.m_conn)
+ l += len(ret)
+
+ l += ULINT_SIZE
+
+ l += ULINT_SIZE
+
+ l += ULINT_SIZE
+
+ i, err := getPackSize(arrDesc.m_arrObj)
+ if err != nil {
+ return 0, err
+ }
+
+ l += i
+
+ return l, nil
+}
+
+func packArray(arrDesc *TypeDescriptor, msg *Dm_build_0) error {
+
+ msg.Dm_build_51(arrDesc.column.colType)
+
+ msg.Dm_build_107(arrDesc.m_sqlName.m_name, arrDesc.getServerEncoding(), arrDesc.m_conn)
+
+ msg.Dm_build_51(int32(arrDesc.m_objId))
+
+ msg.Dm_build_51(int32(arrDesc.m_objVersion))
+
+ msg.Dm_build_51(int32(arrDesc.m_length))
+
+ return pack(arrDesc.m_arrObj, msg)
+}
+
+func packRecord(strctDesc *TypeDescriptor, msg *Dm_build_0) error {
+
+ msg.Dm_build_51(strctDesc.column.colType)
+
+ msg.Dm_build_107(strctDesc.m_sqlName.m_name, strctDesc.getServerEncoding(), strctDesc.m_conn)
+
+ msg.Dm_build_51(int32(strctDesc.m_objId))
+
+ msg.Dm_build_51(int32(strctDesc.m_objVersion))
+
+ msg.Dm_build_47(int16(strctDesc.m_size))
+
+ for i := 0; i < strctDesc.m_size; i++ {
+ err := pack(&strctDesc.m_fieldsObj[i], msg)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func getPackRecordSize(strctDesc *TypeDescriptor) (int, error) {
+ l := 0
+
+ l += ULINT_SIZE
+
+ name := strctDesc.m_sqlName.m_name
+ l += USINT_SIZE
+
+ serverEncoding := strctDesc.getServerEncoding()
+ ret := Dm_build_1220.Dm_build_1433(name, serverEncoding, strctDesc.m_conn)
+ l += len(ret)
+
+ l += ULINT_SIZE
+
+ l += ULINT_SIZE
+
+ l += USINT_SIZE
+
+ for i := 0; i < strctDesc.m_size; i++ {
+ i, err := getPackSize(&strctDesc.m_fieldsObj[i])
+ if err != nil {
+ return 0, err
+ }
+ l += i
+ }
+
+ return l, nil
+}
+
+func getPackClassSize(strctDesc *TypeDescriptor) (int, error) {
+ l := 0
+
+ l += ULINT_SIZE
+
+ name := strctDesc.m_sqlName.m_name
+ l += USINT_SIZE
+
+ serverEncoding := strctDesc.getServerEncoding()
+ ret := Dm_build_1220.Dm_build_1433(name, serverEncoding, strctDesc.m_conn)
+ l += len(ret)
+
+ l += ULINT_SIZE
+
+ l += ULINT_SIZE
+
+ if strctDesc.m_objId == 4 {
+
+ l += ULINT_SIZE
+
+ l += ULINT_SIZE
+
+ l += USINT_SIZE
+ }
+
+ return l, nil
+}
+
+func packClass(strctDesc *TypeDescriptor, msg *Dm_build_0) error {
+
+ msg.Dm_build_51(strctDesc.column.colType)
+
+ msg.Dm_build_107(strctDesc.m_sqlName.m_name, strctDesc.getServerEncoding(), strctDesc.m_conn)
+
+ msg.Dm_build_51(int32(strctDesc.m_objId))
+
+ msg.Dm_build_51(int32(strctDesc.m_objVersion))
+
+ if strctDesc.m_objId == 4 {
+
+ msg.Dm_build_51(int32(strctDesc.m_outerId))
+
+ msg.Dm_build_51(int32(strctDesc.m_outerVer))
+
+ msg.Dm_build_51(int32(strctDesc.m_subId))
+
+ }
+
+ return nil
+}
+
+func (typeDescriptor *TypeDescriptor) unpack(buffer *Dm_build_0) error {
+
+ typeDescriptor.column.colType = buffer.Dm_build_125()
+
+ switch typeDescriptor.column.colType {
+ case ARRAY, SARRAY:
+ return typeDescriptor.unpackArray(buffer)
+ case CLASS:
+ return typeDescriptor.unpackClass(buffer)
+ case PLTYPE_RECORD:
+ return typeDescriptor.unpackRecord(buffer)
+ }
+
+ typeDescriptor.column.prec = buffer.Dm_build_125()
+
+ typeDescriptor.column.scale = buffer.Dm_build_125()
+ return nil
+}
+
+func (typeDescriptor *TypeDescriptor) unpackArray(buffer *Dm_build_0) error {
+
+ typeDescriptor.m_sqlName.m_name = buffer.Dm_build_175(typeDescriptor.getServerEncoding(), typeDescriptor.m_conn)
+
+ typeDescriptor.m_sqlName.m_schId = int(buffer.Dm_build_125())
+
+ typeDescriptor.m_sqlName.m_packId = int(buffer.Dm_build_125())
+
+ typeDescriptor.m_objId = int(buffer.Dm_build_125())
+
+ typeDescriptor.m_objVersion = int(buffer.Dm_build_125())
+
+ typeDescriptor.m_length = int(buffer.Dm_build_125())
+ if typeDescriptor.column.colType == ARRAY {
+ typeDescriptor.m_length = 0
+ }
+
+ typeDescriptor.m_arrObj = newTypeDescriptor(typeDescriptor.m_conn)
+ return typeDescriptor.m_arrObj.unpack(buffer)
+}
+
+func (typeDescriptor *TypeDescriptor) unpackRecord(buffer *Dm_build_0) error {
+
+ typeDescriptor.m_sqlName.m_name = buffer.Dm_build_175(typeDescriptor.getServerEncoding(), typeDescriptor.m_conn)
+
+ typeDescriptor.m_sqlName.m_schId = int(buffer.Dm_build_125())
+
+ typeDescriptor.m_sqlName.m_packId = int(buffer.Dm_build_125())
+
+ typeDescriptor.m_objId = int(buffer.Dm_build_125())
+
+ typeDescriptor.m_objVersion = int(buffer.Dm_build_125())
+
+ typeDescriptor.m_size = int(buffer.Dm_build_140())
+
+ typeDescriptor.m_fieldsObj = make([]TypeDescriptor, typeDescriptor.m_size)
+ for i := 0; i < typeDescriptor.m_size; i++ {
+ typeDescriptor.m_fieldsObj[i] = *newTypeDescriptor(typeDescriptor.m_conn)
+ typeDescriptor.m_fieldsObj[i].unpack(buffer)
+ }
+
+ return nil
+}
+
+func (typeDescriptor *TypeDescriptor) unpackClnt_nestTab(buffer *Dm_build_0) error {
+
+ typeDescriptor.m_maxCnt = int(buffer.Dm_build_125())
+
+ typeDescriptor.m_arrObj = newTypeDescriptor(typeDescriptor.m_conn)
+
+ typeDescriptor.m_arrObj.unpack(buffer)
+
+ return nil
+}
+
+func (typeDescriptor *TypeDescriptor) unpackClnt(buffer *Dm_build_0) error {
+
+ typeDescriptor.m_outerId = int(buffer.Dm_build_125())
+
+ typeDescriptor.m_outerVer = int(buffer.Dm_build_125())
+
+ typeDescriptor.m_subId = int(buffer.Dm_build_140())
+
+ typeDescriptor.m_cltnType = int(buffer.Dm_build_140())
+
+ switch typeDescriptor.m_cltnType {
+ case CLTN_TYPE_IND_TABLE:
+ return ECGO_UNSUPPORTED_TYPE.throw()
+
+ case CLTN_TYPE_NST_TABLE, CLTN_TYPE_VARRAY:
+ return typeDescriptor.unpackClnt_nestTab(buffer)
+
+ }
+ return nil
+}
+
+func (typeDescriptor *TypeDescriptor) unpackClass(buffer *Dm_build_0) error {
+
+ typeDescriptor.m_sqlName.m_name = buffer.Dm_build_175(typeDescriptor.getServerEncoding(), typeDescriptor.m_conn)
+
+ typeDescriptor.m_sqlName.m_schId = int(buffer.Dm_build_125())
+
+ typeDescriptor.m_sqlName.m_packId = int(buffer.Dm_build_125())
+
+ typeDescriptor.m_objId = int(buffer.Dm_build_125())
+
+ typeDescriptor.m_objVersion = int(buffer.Dm_build_125())
+
+ if typeDescriptor.m_objId == 4 {
+ return typeDescriptor.unpackClnt(buffer)
+ } else {
+
+ typeDescriptor.m_size = int(buffer.Dm_build_140())
+
+ typeDescriptor.m_fieldsObj = make([]TypeDescriptor, typeDescriptor.m_size)
+ for i := 0; i < typeDescriptor.m_size; i++ {
+ typeDescriptor.m_fieldsObj[i] = *newTypeDescriptor(typeDescriptor.m_conn)
+ err := typeDescriptor.m_fieldsObj[i].unpack(buffer)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+ }
+
+}
+
+func calcChkDescLen_array(desc *TypeDescriptor) (int, error) {
+ offset := 0
+
+ offset += USINT_SIZE
+
+ offset += ULINT_SIZE
+
+ tmp, err := calcChkDescLen(desc)
+ if err != nil {
+ return 0, err
+ }
+
+ offset += tmp
+
+ return offset, nil
+}
+
+func calcChkDescLen_record(desc *TypeDescriptor) (int, error) {
+ offset := 0
+
+ offset += USINT_SIZE
+
+ offset += USINT_SIZE
+
+ for i := 0; i < desc.m_size; i++ {
+ tmp, err := calcChkDescLen(&desc.m_fieldsObj[i])
+ if err != nil {
+ return 0, err
+ }
+ offset += tmp
+ }
+
+ return offset, nil
+}
+
+func calcChkDescLen_class_normal(desc *TypeDescriptor) (int, error) {
+ offset := 0
+
+ offset += USINT_SIZE
+
+ for i := 0; i < desc.m_size; i++ {
+ tmp, err := calcChkDescLen(&desc.m_fieldsObj[i])
+ if err != nil {
+ return 0, err
+ }
+ offset += tmp
+ }
+
+ return offset, nil
+}
+
+func calcChkDescLen_class_cnlt(desc *TypeDescriptor) (int, error) {
+ offset := 0
+
+ offset += USINT_SIZE
+
+ offset += ULINT_SIZE
+
+ switch desc.getCltnType() {
+ case CLTN_TYPE_IND_TABLE:
+ return 0, ECGO_UNSUPPORTED_TYPE.throw()
+
+ case CLTN_TYPE_VARRAY, CLTN_TYPE_NST_TABLE:
+
+ i, err := calcChkDescLen(desc.m_arrObj)
+ if err != nil {
+ return 0, err
+ }
+
+ offset += i
+ }
+
+ return offset, nil
+}
+
+func calcChkDescLen_class(desc *TypeDescriptor) (int, error) {
+ offset := 0
+
+ offset += USINT_SIZE
+
+ offset += BYTE_SIZE
+
+ if desc.m_objId == 4 {
+ i, err := calcChkDescLen_class_cnlt(desc)
+ if err != nil {
+ return 0, err
+ }
+ offset += i
+ } else {
+ i, err := calcChkDescLen_class_normal(desc)
+ if err != nil {
+ return 0, err
+ }
+ offset += i
+ }
+
+ return offset, nil
+}
+
+func calcChkDescLen_buildin() int {
+ offset := 0
+
+ offset += USINT_SIZE
+
+ offset += USINT_SIZE
+
+ offset += USINT_SIZE
+
+ return offset
+}
+
+func calcChkDescLen(desc *TypeDescriptor) (int, error) {
+
+ switch desc.getDType() {
+ case ARRAY, SARRAY:
+ return calcChkDescLen_array(desc)
+
+ case PLTYPE_RECORD:
+ return calcChkDescLen_record(desc)
+
+ case CLASS:
+ return calcChkDescLen_class(desc)
+
+ default:
+ return calcChkDescLen_buildin(), nil
+ }
+
+}
+
+func (typeDescriptor *TypeDescriptor) makeChkDesc_array(offset int, desc *TypeDescriptor) (int, error) {
+
+ Dm_build_1220.Dm_build_1231(typeDescriptor.m_descBuf, offset, ARRAY)
+ offset += USINT_SIZE
+
+ Dm_build_1220.Dm_build_1236(typeDescriptor.m_descBuf, offset, int32(desc.m_length))
+ offset += ULINT_SIZE
+
+ return typeDescriptor.makeChkDesc(offset, desc)
+}
+
+func (typeDescriptor *TypeDescriptor) makeChkDesc_record(offset int, desc *TypeDescriptor) (int, error) {
+
+ Dm_build_1220.Dm_build_1231(typeDescriptor.m_descBuf, offset, PLTYPE_RECORD)
+ offset += USINT_SIZE
+
+ Dm_build_1220.Dm_build_1231(typeDescriptor.m_descBuf, offset, int16(desc.m_size))
+ offset += USINT_SIZE
+ var err error
+ for i := 0; i < desc.m_size; i++ {
+ offset, err = typeDescriptor.makeChkDesc(offset, &desc.m_fieldsObj[i])
+ if err != nil {
+ return 0, err
+ }
+ }
+
+ return offset, nil
+}
+
+func (typeDescriptor *TypeDescriptor) makeChkDesc_buildin(offset int, desc *TypeDescriptor) int {
+ dtype := int16(desc.getDType())
+ prec := 0
+ scale := 0
+
+ if dtype != BLOB {
+ prec = desc.getPrec()
+ scale = desc.getScale()
+ }
+
+ Dm_build_1220.Dm_build_1231(typeDescriptor.m_descBuf, offset, dtype)
+ offset += USINT_SIZE
+
+ Dm_build_1220.Dm_build_1231(typeDescriptor.m_descBuf, offset, int16(prec))
+ offset += USINT_SIZE
+
+ Dm_build_1220.Dm_build_1231(typeDescriptor.m_descBuf, offset, int16(scale))
+ offset += USINT_SIZE
+
+ return offset
+}
+
+func (typeDescriptor *TypeDescriptor) makeChkDesc_class_normal(offset int, desc *TypeDescriptor) (int, error) {
+
+ Dm_build_1220.Dm_build_1231(typeDescriptor.m_descBuf, offset, int16(desc.m_size))
+ offset += USINT_SIZE
+ var err error
+
+ for i := 0; i < desc.m_size; i++ {
+ offset, err = typeDescriptor.makeChkDesc(offset, &desc.m_fieldsObj[i])
+ if err != nil {
+ return 0, err
+ }
+ }
+
+ return offset, nil
+}
+
+func (typeDescriptor *TypeDescriptor) makeChkDesc_class_clnt(offset int, desc *TypeDescriptor) (int, error) {
+
+ Dm_build_1220.Dm_build_1231(typeDescriptor.m_descBuf, offset, int16(desc.m_cltnType))
+ offset += USINT_SIZE
+
+ Dm_build_1220.Dm_build_1236(typeDescriptor.m_descBuf, offset, int32(desc.getMaxCnt()))
+ offset += ULINT_SIZE
+
+ switch desc.m_cltnType {
+ case CLTN_TYPE_IND_TABLE:
+ return 0, ECGO_UNSUPPORTED_TYPE.throw()
+
+ case CLTN_TYPE_NST_TABLE, CLTN_TYPE_VARRAY:
+
+ return typeDescriptor.makeChkDesc(offset, desc.m_arrObj)
+ }
+
+ return offset, nil
+}
+
+func (typeDescriptor *TypeDescriptor) makeChkDesc_class(offset int, desc *TypeDescriptor) (int, error) {
+
+ Dm_build_1220.Dm_build_1231(typeDescriptor.m_descBuf, offset, CLASS)
+ offset += USINT_SIZE
+
+ isClnt := false
+ if desc.m_objId == 4 {
+ isClnt = true
+ }
+
+ if isClnt {
+ Dm_build_1220.Dm_build_1221(typeDescriptor.m_descBuf, offset, byte(1))
+ } else {
+ Dm_build_1220.Dm_build_1221(typeDescriptor.m_descBuf, offset, byte(0))
+ }
+
+ offset += BYTE_SIZE
+
+ if isClnt {
+ return typeDescriptor.makeChkDesc_class_clnt(offset, desc)
+ } else {
+ return typeDescriptor.makeChkDesc_class_normal(offset, desc)
+ }
+}
+
+func (typeDescriptor *TypeDescriptor) makeChkDesc(offset int, subDesc *TypeDescriptor) (int, error) {
+ switch subDesc.getDType() {
+ case ARRAY, SARRAY:
+ return typeDescriptor.makeChkDesc_array(offset, subDesc)
+
+ case PLTYPE_RECORD:
+ return typeDescriptor.makeChkDesc_record(offset, subDesc)
+
+ case CLASS:
+ return typeDescriptor.makeChkDesc_class(offset, subDesc)
+
+ default:
+ return typeDescriptor.makeChkDesc_buildin(offset, subDesc), nil
+ }
+
+}
+
+func (typeDescriptor *TypeDescriptor) getClassDescChkInfo() ([]byte, error) {
+ if typeDescriptor.m_descBuf != nil {
+ return typeDescriptor.m_descBuf, nil
+ }
+
+ l, err := calcChkDescLen(typeDescriptor)
+ if err != nil {
+ return nil, err
+ }
+ typeDescriptor.m_descBuf = make([]byte, l)
+
+ typeDescriptor.makeChkDesc(0, typeDescriptor)
+ return typeDescriptor.m_descBuf, nil
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..919d573
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,13 @@
+module github.com/nfjBill/gorm-driver-dm
+
+go 1.17
+
+require (
+ github.com/emirpasic/gods v1.12.0 // indirect
+ github.com/golang/snappy v0.0.1 // indirect
+ github.com/jinzhu/inflection v1.0.0 // indirect
+ github.com/jinzhu/now v1.1.4 // indirect
+ github.com/thoas/go-funk v0.9.1 // indirect
+ golang.org/x/text v0.3.2 // indirect
+ gorm.io/gorm v1.22.5 // indirect
+)
diff --git a/mask.go b/mask.go
new file mode 100644
index 0000000..cda6f0d
--- /dev/null
+++ b/mask.go
@@ -0,0 +1,82 @@
+package dm
+
+import (
+ "database/sql"
+ "gorm.io/gorm"
+ "gorm.io/gorm/clause"
+ "reflect"
+)
+
+type STable struct {
+ Conn *gorm.DB
+ Table interface{}
+}
+
+var conn *gorm.DB
+
+func Table(table ...interface{}) *STable {
+ var tb interface{}
+ if len(table) == 1 {
+ tb = table[0]
+ }
+ return &STable{Table: tb, Conn: conn}
+}
+
+func TB(db *gorm.DB) {
+ conn = db
+}
+
+func (stb *STable) DB() (*sql.DB, error) {
+ return stb.Conn.DB()
+}
+
+func (stb *STable) Model() *gorm.DB {
+ if reflect.ValueOf(stb.Table).Kind() == reflect.String {
+ return stb.Conn.Table(stb.Table.(string))
+ }
+ return stb.Conn.Model(stb.Table)
+}
+
+func (stb *STable) Create() error {
+ return stb.Conn.Create(stb.Table).Error
+}
+
+func (stb *STable) Get(dest interface{}, conds ...interface{}) error {
+ return stb.Conn.Where(stb.Table).First(dest, conds...).Error
+}
+
+func (stb *STable) GetWhere(dest interface{}) error {
+ return stb.Conn.Model(stb.Table).Where(stb.Table).Find(dest).Error
+}
+
+func (stb *STable) GetAll(dest interface{}) error {
+ return stb.Conn.Model(stb.Table).Find(dest).Error
+}
+
+func (stb *STable) ClausesAssignmentColumns(name string, doUpdates []string) error {
+ return stb.Conn.Clauses(clause.OnConflict{
+ Columns: []clause.Column{{Name: name}},
+ DoUpdates: clause.AssignmentColumns(doUpdates),
+ }).Create(stb.Table).Error
+}
+
+func (stb *STable) Delete() error {
+ tx := stb.Conn.Begin()
+ if err := tx.Where(stb.Table).Delete(stb.Table).Error; err != nil {
+ tx.Rollback()
+ return err
+ }
+ return tx.Commit().Error
+}
+
+func (stb *STable) AutoMigrate(dst ...interface{}) error {
+ return stb.Conn.AutoMigrate(dst...)
+}
+
+func (stb *STable) DropTable(dest ...interface{}) error {
+ return stb.Conn.Migrator().DropTable(dest...)
+}
+
+func (stb *STable) HasTable(dest interface{}) bool {
+ return stb.Conn.Migrator().HasTable(dest)
+}
diff --git a/migrator.go b/migrator.go
new file mode 100644
index 0000000..1268f72
--- /dev/null
+++ b/migrator.go
@@ -0,0 +1,367 @@
+package dm
+
+import (
+ "fmt"
+ "gorm.io/gorm/schema"
+ "strconv"
+ "strings"
+
+ "gorm.io/gorm"
+ "gorm.io/gorm/clause"
+ "gorm.io/gorm/migrator"
+)
+
+type Migrator struct {
+ migrator.Migrator
+}
+
+func (m Migrator) CurrentDatabase() (name string) {
+ m.DB.Raw(
+ fmt.Sprintf(`SELECT ORA_DATABASE_NAME as "Current Database" FROM %s`, m.Dialector.(Dialector).DummyTableName()),
+ ).Row().Scan(&name)
+ return
+}
+
+func buildConstraint(constraint *schema.Constraint) (sql string, results []interface{}) {
+ sql = "CONSTRAINT ? FOREIGN KEY ? REFERENCES ??"
+ if constraint.OnDelete != "" {
+ sql += " ON DELETE " + constraint.OnDelete
+ }
+
+ if constraint.OnUpdate != "" {
+ sql += " ON UPDATE " + constraint.OnUpdate
+ }
+
+ var foreignKeys, references []interface{}
+ for _, field := range constraint.ForeignKeys {
+ foreignKeys = append(foreignKeys, clause.Column{Name: field.DBName})
+ }
+
+ for _, field := range constraint.References {
+ references = append(references, clause.Column{Name: field.DBName})
+ }
+ results = append(results, clause.Table{Name: constraint.Name}, foreignKeys, clause.Table{Name: constraint.ReferenceSchema.Table}, references)
+ return
+}
+
+func (m Migrator) CreateTable(values ...interface{}) error {
+ for _, value := range values {
+ m.TryQuotifyReservedWords(value)
+ m.TryRemoveOnUpdate(value)
+ }
+
+ for _, value := range m.ReorderModels(values, false) {
+ tx := m.DB.Session(&gorm.Session{})
+ if err := m.RunWithValue(value, func(stmt *gorm.Statement) (errr error) {
+ var (
+ createTableSQL = "CREATE TABLE ? ("
+ values = []interface{}{m.CurrentTable(stmt)}
+ hasPrimaryKeyInDataType bool
+ )
+
+ for _, dbName := range stmt.Schema.DBNames {
+ field := stmt.Schema.FieldsByDBName[dbName]
+ if !field.IgnoreMigration {
+ createTableSQL += "? ?"
+ hasPrimaryKeyInDataType = hasPrimaryKeyInDataType || strings.Contains(strings.ToUpper(string(field.DataType)), "PRIMARY KEY")
+ f := m.DB.Migrator().FullDataTypeOf(field)
+ if field.AutoIncrement {
+ f.SQL = "INTEGER IDENTITY(1, " + strconv.FormatInt(field.AutoIncrementIncrement, 10) + ")"
+ }
+ values = append(values, clause.Column{Name: dbName}, f)
+ createTableSQL += ","
+ }
+ }
+
+ if !hasPrimaryKeyInDataType && len(stmt.Schema.PrimaryFields) > 0 {
+ createTableSQL += "PRIMARY KEY ?,"
+ primaryKeys := []interface{}{}
+ for _, field := range stmt.Schema.PrimaryFields {
+ primaryKeys = append(primaryKeys, clause.Column{Name: field.DBName})
+ }
+
+ values = append(values, primaryKeys)
+ }
+
+ for _, idx := range stmt.Schema.ParseIndexes() {
+ if m.CreateIndexAfterCreateTable {
+ //defer func(value interface{}, name string) {
+ // if errr == nil {
+ // errr = tx.Migrator().CreateIndex(value, name)
+ // }
+ //}(value, idx.Name)
+ } else {
+ if idx.Class != "" {
+ createTableSQL += idx.Class + " "
+ }
+ createTableSQL += "INDEX ? ?"
+
+ if idx.Comment != "" {
+ createTableSQL += fmt.Sprintf(" COMMENT '%s'", idx.Comment)
+ }
+
+ if idx.Option != "" {
+ createTableSQL += " " + idx.Option
+ }
+
+ createTableSQL += ","
+ values = append(values, clause.Expr{SQL: idx.Name}, tx.Migrator().(migrator.BuildIndexOptionsInterface).BuildIndexOptions(idx.Fields, stmt))
+ }
+ }
+
+ for _, rel := range stmt.Schema.Relationships.Relations {
+ if !m.DB.DisableForeignKeyConstraintWhenMigrating {
+ if constraint := rel.ParseConstraint(); constraint != nil {
+ if constraint.Schema == stmt.Schema {
+ sql, vars := buildConstraint(constraint)
+ createTableSQL += sql + ","
+ values = append(values, vars...)
+ }
+ }
+ }
+ }
+
+ for _, chk := range stmt.Schema.ParseCheckConstraints() {
+ createTableSQL += "CONSTRAINT ? CHECK (?),"
+ values = append(values, clause.Column{Name: chk.Name}, clause.Expr{SQL: chk.Constraint})
+ }
+
+ createTableSQL = strings.TrimSuffix(createTableSQL, ",")
+
+ createTableSQL += ")"
+
+ if tableOption, ok := m.DB.Get("gorm:table_options"); ok {
+ createTableSQL += fmt.Sprint(tableOption)
+ }
+
+ errr = tx.Exec(createTableSQL, values...).Error
+ return errr
+ }); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (m Migrator) DropTable(values ...interface{}) error {
+ values = m.ReorderModels(values, false)
+ for i := len(values) - 1; i >= 0; i-- {
+ value := values[i]
+ tx := m.DB.Session(&gorm.Session{})
+ if m.HasTable(value) {
+ if err := m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ return tx.Exec("DROP TABLE ? CASCADE CONSTRAINTS", clause.Table{Name: stmt.Table}).Error
+ }); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+func (m Migrator) HasTable(value interface{}) bool {
+ var count int64
+
+ m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ return m.DB.Raw("SELECT COUNT(*) FROM USER_TABLES WHERE TABLE_NAME = ?", stmt.Table).Row().Scan(&count)
+ })
+
+ return count > 0
+}
+
+func (m Migrator) RenameTable(oldName, newName interface{}) (err error) {
+ resolveTable := func(name interface{}) (result string, err error) {
+ if v, ok := name.(string); ok {
+ result = v
+ } else {
+ stmt := &gorm.Statement{DB: m.DB}
+ if err = stmt.Parse(name); err == nil {
+ result = stmt.Table
+ }
+ }
+ return
+ }
+
+ var oldTable, newTable string
+
+ if oldTable, err = resolveTable(oldName); err != nil {
+ return
+ }
+
+ if newTable, err = resolveTable(newName); err != nil {
+ return
+ }
+
+ if !m.HasTable(oldTable) {
+ return
+ }
+
+ return m.DB.Exec("RENAME TABLE ? TO ?",
+ clause.Table{Name: oldTable},
+ clause.Table{Name: newTable},
+ ).Error
+}
+
+func (m Migrator) AddColumn(value interface{}, field string) error {
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ if field := stmt.Schema.LookUpField(field); field != nil {
+ return m.DB.Exec(
+ "ALTER TABLE ? ADD ? ?",
+ clause.Table{Name: stmt.Table}, clause.Column{Name: field.DBName}, m.DB.Migrator().FullDataTypeOf(field),
+ ).Error
+ }
+ return fmt.Errorf("failed to look up field with name: %s", field)
+ })
+}
+
+func (m Migrator) DropColumn(value interface{}, name string) error {
+ if !m.HasColumn(value, name) {
+ return nil
+ }
+
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ if field := stmt.Schema.LookUpField(name); field != nil {
+ name = field.DBName
+ }
+
+ return m.DB.Exec(
+ "ALTER TABLE ? DROP ?",
+ clause.Table{Name: stmt.Table},
+ clause.Column{Name: name},
+ ).Error
+ })
+}
+
+func (m Migrator) AlterColumn(value interface{}, field string) error {
+ if !m.HasColumn(value, field) {
+ return nil
+ }
+
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ if field := stmt.Schema.LookUpField(field); field != nil {
+ return m.DB.Exec(
+ "ALTER TABLE ? MODIFY ? ?",
+ clause.Table{Name: stmt.Table},
+ clause.Column{Name: field.DBName},
+ m.FullDataTypeOf(field),
+ ).Error
+ }
+ return fmt.Errorf("failed to look up field with name: %s", field)
+ })
+}
+
+func (m Migrator) HasColumn(value interface{}, field string) bool {
+ var count int64
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ return m.DB.Raw("SELECT COUNT(*) FROM USER_TAB_COLUMNS WHERE TABLE_NAME = ? AND COLUMN_NAME = ?", stmt.Table, field).Row().Scan(&count)
+ }) == nil && count > 0
+}
+
+func (m Migrator) CreateConstraint(value interface{}, name string) error {
+ m.TryRemoveOnUpdate(value)
+ return m.Migrator.CreateConstraint(value, name)
+}
+
+func (m Migrator) DropConstraint(value interface{}, name string) error {
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ for _, chk := range stmt.Schema.ParseCheckConstraints() {
+ if chk.Name == name {
+ return m.DB.Exec(
+ "ALTER TABLE ? DROP CHECK ?",
+ clause.Table{Name: stmt.Table}, clause.Column{Name: name},
+ ).Error
+ }
+ }
+
+ return m.DB.Exec(
+ "ALTER TABLE ? DROP CONSTRAINT ?",
+ clause.Table{Name: stmt.Table}, clause.Column{Name: name},
+ ).Error
+ })
+}
+
+func (m Migrator) HasConstraint(value interface{}, name string) bool {
+ var count int64
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ return m.DB.Raw(
+ "SELECT COUNT(*) FROM USER_CONSTRAINTS WHERE TABLE_NAME = ? AND CONSTRAINT_NAME = ?", stmt.Table, name,
+ ).Row().Scan(&count)
+ }) == nil && count > 0
+}
+
+func (m Migrator) DropIndex(value interface{}, name string) error {
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ if idx := stmt.Schema.LookIndex(name); idx != nil {
+ name = idx.Name
+ }
+
+ return m.DB.Exec("DROP INDEX ?", clause.Column{Name: name}, clause.Table{Name: stmt.Table}).Error
+ })
+}
+
+func (m Migrator) HasIndex(value interface{}, name string) bool {
+ var count int64
+ m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ if idx := stmt.Schema.LookIndex(name); idx != nil {
+ name = idx.Name
+ }
+
+ return m.DB.Raw(
+ "SELECT COUNT(*) FROM USER_INDEXES WHERE TABLE_NAME = ? AND INDEX_NAME = ?",
+ m.Migrator.DB.NamingStrategy.TableName(stmt.Table),
+ m.Migrator.DB.NamingStrategy.IndexName(stmt.Table, name),
+ ).Row().Scan(&count)
+ })
+
+ return count > 0
+}
+
+// https://docs.dm.com/database/121/SPATL/alter-index-rename.htm
+func (m Migrator) RenameIndex(value interface{}, oldName, newName string) error {
+ panic("TODO")
+ return m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ return m.DB.Exec(
+ "ALTER INDEX ?.? RENAME TO ?", // wat
+ clause.Table{Name: stmt.Table}, clause.Column{Name: oldName}, clause.Column{Name: newName},
+ ).Error
+ })
+}
+
+func (m Migrator) TryRemoveOnUpdate(values ...interface{}) error {
+ for _, value := range values {
+ if err := m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ for _, rel := range stmt.Schema.Relationships.Relations {
+ constraint := rel.ParseConstraint()
+ if constraint != nil {
+ rel.Field.TagSettings["CONSTRAINT"] = strings.ReplaceAll(rel.Field.TagSettings["CONSTRAINT"], fmt.Sprintf("ON UPDATE %s", constraint.OnUpdate), "")
+ }
+ }
+ return nil
+ }); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (m Migrator) TryQuotifyReservedWords(values ...interface{}) error {
+ for _, value := range values {
+ if err := m.RunWithValue(value, func(stmt *gorm.Statement) error {
+ for idx, v := range stmt.Schema.DBNames {
+ if IsReservedWord(v) {
+ stmt.Schema.DBNames[idx] = fmt.Sprintf(`"%s"`, v)
+ }
+ }
+
+ for _, v := range stmt.Schema.Fields {
+ if IsReservedWord(v.DBName) {
+ v.DBName = fmt.Sprintf(`"%s"`, v.DBName)
+ }
+ }
+ return nil
+ }); err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/namer.go b/namer.go
new file mode 100644
index 0000000..b06d059
--- /dev/null
+++ b/namer.go
@@ -0,0 +1,38 @@
+package dm
+
+import (
+ "gorm.io/gorm/schema"
+ "strings"
+)
+
+type Namer struct {
+ schema.NamingStrategy
+}
+
+func ConvertNameToFormat(x string) string {
+ return strings.ToUpper(x)
+}
+
+func (n Namer) TableName(table string) (name string) {
+ return ConvertNameToFormat(n.NamingStrategy.TableName(table))
+}
+
+func (n Namer) ColumnName(table, column string) (name string) {
+ return ConvertNameToFormat(n.NamingStrategy.ColumnName(table, column))
+}
+
+func (n Namer) JoinTableName(table string) (name string) {
+ return ConvertNameToFormat(n.NamingStrategy.JoinTableName(table))
+}
+
+func (n Namer) RelationshipFKName(relationship schema.Relationship) (name string) {
+ return ConvertNameToFormat(n.NamingStrategy.RelationshipFKName(relationship))
+}
+
+func (n Namer) CheckerName(table, column string) (name string) {
+ return ConvertNameToFormat(n.NamingStrategy.CheckerName(table, column))
+}
+
+func (n Namer) IndexName(table, column string) (name string) {
+ return ConvertNameToFormat(n.NamingStrategy.IndexName(table, column))
+}
diff --git a/reserved.go b/reserved.go
new file mode 100644
index 0000000..f2a7d50
--- /dev/null
+++ b/reserved.go
@@ -0,0 +1,28 @@
+package dm
+
+import (
+ "github.com/emirpasic/gods/sets/hashset"
+ "github.com/thoas/go-funk"
+)
+
+var ReservedWords = hashset.New(funk.Map(ReservedWordsList, func(s string) interface{} { return s }).([]interface{})...)
+
+func IsReservedWord(v string) bool {
+ return ReservedWords.Contains(v)
+}
+
+var ReservedWordsList = []string{
+ "AGGREGATE", "AGGREGATES", "ALL", "ALLOW", "ANALYZE", "ANCESTOR", "AND", "ANY", "AS", "ASC", "AT", "AVG", "BETWEEN",
+ "BINARY_DOUBLE", "BINARY_FLOAT", "BLOB", "BRANCH", "BUILD", "BY", "BYTE", "CASE", "CAST", "CHAR", "CHILD", "CLEAR",
+ "CLOB", "COMMIT", "COMPILE", "CONSIDER", "COUNT", "DATATYPE", "DATE", "DATE_MEASURE", "DAY", "DECIMAL", "DELETE",
+ "DESC", "DESCENDANT", "DIMENSION", "DISALLOW", "DIVISION", "DML", "ELSE", "END", "ESCAPE", "EXECUTE", "FIRST",
+ "FLOAT", "FOR", "FROM", "HIERARCHIES", "HIERARCHY", "HOUR", "IGNORE", "IN", "INFINITE", "INSERT", "INTEGER",
+ "INTERVAL", "INTO", "IS", "LAST", "LEAF_DESCENDANT", "LEAVES", "LEVEL", "LIKE", "LIKEC", "LIKE2", "LIKE4", "LOAD",
+ "LOCAL", "LOG_SPEC", "LONG", "MAINTAIN", "MAX", "MEASURE", "MEASURES", "MEMBER", "MEMBERS", "MERGE", "MLSLABEL",
+ "MIN", "MINUTE", "MODEL", "MONTH", "NAN", "NCHAR", "NCLOB", "NO", "NONE", "NOT", "NULL", "NULLS", "NUMBER",
+ "NVARCHAR2", "OF", "OLAP", "OLAP_DML_EXPRESSION", "ON", "ONLY", "OPERATOR", "OR", "ORDER", "OVER", "OVERFLOW",
+ "PARALLEL", "PARENT", "PLSQL", "PRUNE", "RAW", "RELATIVE", "ROOT_ANCESTOR", "ROWID", "SCN", "SECOND", "SELF",
+ "SERIAL", "SET", "SOLVE", "SOME", "SORT", "SPEC", "SUM", "SYNCH", "TEXT_MEASURE", "THEN", "TIME", "TIMESTAMP",
+ "TO", "UNBRANCH", "UPDATE", "USING", "VALIDATE", "VALUES", "VARCHAR2", "WHEN", "WHERE", "WITHIN", "WITH", "YEAR",
+ "ZERO", "ZONE",
+}
diff --git a/schema/clob.go b/schema/clob.go
new file mode 100644
index 0000000..d27ba35
--- /dev/null
+++ b/schema/clob.go
@@ -0,0 +1,40 @@
+package dmSchema
+
+import (
+ "database/sql/driver"
+ "errors"
+ "fmt"
+
+ "github.com/nfjBill/gorm-driver-dm/dmr"
+)
+
+type Clob string
+
+// 写入数据库之前,对数据做类型转换
+func (clob Clob) Value() (driver.Value, error) {
+ if len(clob) == 0 {
+ return nil, nil
+ }
+ return string(clob), nil
+}
+
+// 将数据库中取出的数据,赋值给目标类型
+func (clob *Clob) Scan(v interface{}) error {
+ switch v.(type) {
+ case *dmr.DmClob:
+ tmp := v.(*dmr.DmClob)
+ le, err := tmp.GetLength()
+ if err != nil {
+ return errors.New(fmt.Sprint("err:", err))
+ }
+
+ str, err := tmp.ReadString(1, int(le))
+ *clob = Clob(str)
+ break
+
+ //非clob,当成字符串,兼容oracle
+ default:
+ *clob = Clob(v.(string))
+ }
+ return nil
+}