diff --git a/go.mod b/go.mod index 63c16764c4..2ed3941012 100644 --- a/go.mod +++ b/go.mod @@ -88,20 +88,21 @@ require ( k8s.io/client-go v0.19.3 k8s.io/cluster-bootstrap v0.19.3 moul.io/http2curl/v2 v2.3.0 - yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240223082938-77dea2c9d55b + yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240228112145-f7432518ad4b yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32 yunion.io/x/jsonutils v1.0.1-0.20240203102553-4096f103b401 yunion.io/x/log v1.0.1-0.20230411060016-feb3f46ab361 yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900 yunion.io/x/pkg v1.10.1-0.20240127153242-cdf9dc071f4f yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e - yunion.io/x/sqlchemy v1.1.3-0.20240210161427-e48bb9a658b7 + yunion.io/x/sqlchemy v1.1.3-0.20240228104732-b8924f0c2e81 yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c ) require ( cloud.google.com/go v0.65.0 // indirect cloud.google.com/go/storage v1.10.0 // indirect + gitee.com/chunanyong/dm v1.8.14 // indirect github.com/Azure/azure-sdk-for-go v36.1.0+incompatible // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.9.6 // indirect @@ -170,7 +171,7 @@ require ( github.com/golang-plus/errors v1.0.0 // indirect github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect + github.com/golang/snappy v0.0.1 // indirect github.com/google/btree v1.0.1 // indirect github.com/google/go-querystring v1.0.0 // indirect github.com/google/gofuzz v1.1.0 // indirect diff --git a/go.sum b/go.sum index 52527e9285..dd6fadd10e 100644 --- a/go.sum +++ b/go.sum @@ -36,6 +36,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +gitee.com/chunanyong/dm v1.8.14 h1:1S9+aD0fY/HXkcm8dKh2HjYsDlcdXNG+4IOX9JtrSjA= +gitee.com/chunanyong/dm v1.8.14/go.mod h1:EPRJnuPFgbyOFgJ0TRYCTGzhq+ZT4wdyaj/GW/LLcNg= github.com/360EntSecGroup-Skylar/excelize v1.4.0 h1:43rak9uafmwSJpXfFO1heKQph8tP3nlfWJWFQQtW1R0= github.com/360EntSecGroup-Skylar/excelize v1.4.0/go.mod h1:R8KYLmGns0vDPe6/HyphW0mzW+MFexlGDafU0ykVEnU= github.com/Azure/azure-sdk-for-go v5.0.0-beta.0.20161118192335-3b1282355199+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= @@ -340,8 +342,9 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -1201,8 +1204,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240223082938-77dea2c9d55b h1:DQXZfJ5C/XqQXQ6esedRXz1xWQ97zU1au6qQcW6UFCQ= -yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240223082938-77dea2c9d55b/go.mod h1:dsUESXIbXJ+/ywbNClhldOrbPOiBi2udrgOnB/ffoWk= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240228112145-f7432518ad4b h1:3dto4ZKeWQ6nKLldqVeduWr9oTXavd6d6TkPtDHGg4Q= +yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240228112145-f7432518ad4b/go.mod h1:dsUESXIbXJ+/ywbNClhldOrbPOiBi2udrgOnB/ffoWk= yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32 h1:v7POYkQwo1XzOxBoIoRVr/k0V9Y5JyjpshlIFa9raug= yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws= yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634= @@ -1220,7 +1223,7 @@ yunion.io/x/pkg v1.10.1-0.20240127153242-cdf9dc071f4f h1:nLMBj8S3/ev2pB1wzGSi6hO yunion.io/x/pkg v1.10.1-0.20240127153242-cdf9dc071f4f/go.mod h1:ksCJVQ+DwKrJ5QBEoU8pzrDFfDaZVAFH/iJ6yQCYxJk= yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e h1:v+EzIadodSwkdZ/7bremd7J8J50Cise/HCylsOJngmo= yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo= -yunion.io/x/sqlchemy v1.1.3-0.20240210161427-e48bb9a658b7 h1:T/lJOFh353MbMon3k+gzGbrmTOV1a6I8/dIlrEdwV9I= -yunion.io/x/sqlchemy v1.1.3-0.20240210161427-e48bb9a658b7/go.mod h1:uuPVZEyEq3sWd5vf9VjGSy6lZzof22X87OEHw9sddJQ= +yunion.io/x/sqlchemy v1.1.3-0.20240228104732-b8924f0c2e81 h1:0QocM63F8k9EDkf1Zx/sWX27hGYplbq+CBXBF2k1ev4= +yunion.io/x/sqlchemy v1.1.3-0.20240228104732-b8924f0c2e81/go.mod h1:5W8ghvJ4TNt/r2yDjjD3i4QsZgIiJX45dhRQBGWPHsQ= yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c h1:QuLab2kSRECZRxo4Lo2KcYn6XjQFDGaZ1+x0pYDVVwQ= yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng= diff --git a/pkg/compute/models/cloudsync.go b/pkg/compute/models/cloudsync.go index de4f7137b5..bb421a68ec 100644 --- a/pkg/compute/models/cloudsync.go +++ b/pkg/compute/models/cloudsync.go @@ -306,7 +306,9 @@ func syncRegionVPCs( if syncRange.IsNotSkipSyncResource(SecurityGroupManager) { syncVpcSecGroup(ctx, userCred, syncResults, provider, localRegion, &localVpcs[j], remoteVpcs[j], syncRange) } - syncVpcNatgateways(ctx, userCred, syncResults, provider, &localVpcs[j], remoteVpcs[j], syncRange) + if syncRange.IsNotSkipSyncResource(NatGatewayManager) { + syncVpcNatgateways(ctx, userCred, syncResults, provider, &localVpcs[j], remoteVpcs[j], syncRange) + } syncVpcPeerConnections(ctx, userCred, syncResults, provider, &localVpcs[j], remoteVpcs[j], syncRange) syncVpcRouteTables(ctx, userCred, syncResults, provider, &localVpcs[j], remoteVpcs[j], syncRange) syncIPv6Gateways(ctx, userCred, syncResults, provider, &localVpcs[j], remoteVpcs[j], syncRange) @@ -2158,7 +2160,9 @@ func syncPublicCloudProviderInfo( } if cloudprovider.IsSupportCompute(driver) { - if syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_NETWORK) || syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_EIP) { + if syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_NETWORK) || + syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_NAT) || + syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_EIP) { // 需要先同步vpc,避免私有云eip找不到network if !(driver.GetFactory().IsPublicCloud() && !syncRange.NeedSyncResource(cloudprovider.CLOUD_CAPABILITY_NETWORK)) && syncRange.IsNotSkipSyncResource(VpcManager) { syncRegionVPCs(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange) diff --git a/pkg/compute/models/natgateways.go b/pkg/compute/models/natgateways.go index 264b5ab5a8..bc1c41a829 100644 --- a/pkg/compute/models/natgateways.go +++ b/pkg/compute/models/natgateways.go @@ -73,8 +73,9 @@ type SNatGateway struct { SDeletePreventableResourceBase - NetworkId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` - IpAddr string `width:"16" charset:"ascii" nullable:"false" list:"user"` + NetworkId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional"` + NetworkType string `width:"16" charset:"ascii" nullable:"false" list:"user" create:"optional"` + IpAddr string `width:"16" charset:"ascii" nullable:"false" list:"user"` BandwidthMb int `nullable:"false" list:"user"` NatSpec string `list:"user" create:"optional"` // NAT规格 @@ -497,6 +498,7 @@ func (self *SNatGateway) SyncWithCloudNatGateway(ctx context.Context, userCred m self.Status = extNat.GetStatus() self.NatSpec = extNat.GetNatSpec() + self.NetworkType = extNat.GetNetworkType() self.BandwidthMb = extNat.GetBandwidthMb() vpc, err := self.GetVpc() @@ -554,6 +556,7 @@ func (manager *SNatGatewayManager) newFromCloudNatGateway(ctx context.Context, u nat.VpcId = vpc.Id nat.Status = extNat.GetStatus() nat.NatSpec = extNat.GetNatSpec() + nat.NetworkType = extNat.GetNetworkType() nat.BandwidthMb = extNat.GetBandwidthMb() if createdAt := extNat.GetCreatedAt(); !createdAt.IsZero() { nat.CreatedAt = extNat.GetCreatedAt() diff --git a/pkg/compute/tasks/natdentry_delete_task.go b/pkg/compute/tasks/natdentry_delete_task.go index e82255c394..406f01016e 100644 --- a/pkg/compute/tasks/natdentry_delete_task.go +++ b/pkg/compute/tasks/natdentry_delete_task.go @@ -76,7 +76,7 @@ func (self *SNatDEntryDeleteTask) OnInit(ctx context.Context, obj db.IStandalone return } - iDnat, err := iNat.GetINatDEntryByID(dnat.ExternalId) + iDnat, err := iNat.GetINatDEntryById(dnat.ExternalId) if err != nil { if errors.Cause(err) == cloudprovider.ErrNotFound { self.taskComplete(ctx, dnat) diff --git a/pkg/compute/tasks/natsentry_delete_task.go b/pkg/compute/tasks/natsentry_delete_task.go index b8b154fa40..de9adb62be 100644 --- a/pkg/compute/tasks/natsentry_delete_task.go +++ b/pkg/compute/tasks/natsentry_delete_task.go @@ -77,7 +77,7 @@ func (self *SNatSEntryDeleteTask) OnInit(ctx context.Context, obj db.IStandalone return } - iSnat, err := iNat.GetINatSEntryByID(snat.ExternalId) + iSnat, err := iNat.GetINatSEntryById(snat.ExternalId) if err != nil { if errors.Cause(err) == cloudprovider.ErrNotFound { self.taskComplete(ctx, snat) diff --git a/vendor/gitee.com/chunanyong/dm/CHANGELOG.md b/vendor/gitee.com/chunanyong/dm/CHANGELOG.md new file mode 100644 index 0000000000..5d9f822ed1 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/CHANGELOG.md @@ -0,0 +1,38 @@ +# Change Logs + +*你可以在文件p.go中的发版标记里找到当前驱动的svn号 + +## svn 16752 +支持在连接串上直接配置动态服务名,使用示例: +dm://user:password@GroupName?GroupName=(host1:port1,host2:port2,...) + +## svn 16505 +新增连接串属性driverReconnect,配合doSwitch=1或2使用,表示连接重连是否使用驱动自身的重连机制,否则在连接失效时返回sql标准错误driver.ErrBadConn,由go来处理重连 + +## svn 16258 +重连逻辑修改,当连接失效时,返回driver.ErrBadConn而不是驱动自己管理重连,连接串参数doSwitch默认值改为1 +驱动接口方法同步锁改到连接网络请求的总入口处,解决一些panic和数组越界问题 +日志优化,去除遍历结果集时因io.EOF错误记录的日志 + +## svn 15619 +驱动接口方法添加同步锁 +驱动日志修改bug,可以记录SQL语句和参数值了 + +## svn 15357 +发布方言包,支持gorm v1和v2框架,方言包位于达梦安装目录的drivers/go目录中,详细使用说明参考《DM8程序员手册》 + +## svn 15157 +修复了字符大字段(Clob)中存在乱码字符时,读取结果会漏读一些字符的问题 +修复了开启SSL后并发创建连接导致panic的问题 + +## svn 15035 +修复了连接串属性doSwitch=1时,语句不会自动切换和重连的问题 +修复了连接重置后,可能出现的空指针问题 + +## svn 14992 +修复了连接串属性doSwitch=1时,连接不会自动切换和重连的问题 +修复了连接串属性loginMode=默认值4时,备库可能会被优先连接的问题 + +## svn 14589 +sql.Result.LastInsertId()函数能优先返回自增列的值,如果没有则返回数据库表内部的rowid +修复了开启事务时指定只读不生效的问题 \ No newline at end of file diff --git a/vendor/gitee.com/chunanyong/dm/README.md b/vendor/gitee.com/chunanyong/dm/README.md new file mode 100644 index 0000000000..a291738954 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/README.md @@ -0,0 +1,51 @@ +# dm + +### 介绍 +``` +go get gitee.com/chunanyong/dm +``` +达梦数据库官方Go驱动,本项目和官方驱动版本同步,方便go mod 使用. +安装达梦数据库(版本>=8.1.1.126),安装目录下 drivers/go/dm-go-driver.zip +达梦官方文档:https://eco.dameng.com/docs/zh-cn/app-dev/go-go.html +资源下载:https://eco.dameng.com/download/ +达梦官方Go驱动包:https://package.dameng.com/eco/adapter/resource/go/dm-go-driver.zip +达梦官方论坛(提交bug):https://eco.dameng.com/community/question + +### zorm +Go轻量ORM https://gitee.com/chunanyong/zorm 原生支持达梦数据库 + +### DSN +dm://userName:password@127.0.0.1:5236?schema=DBName +用户名(userName)默认就是数据库的名称,达梦用户模式和数据库名称是对应的,也可以通过schema参数指定数据库 +建议达梦使用UTF-8字符编码,不区分大小写,建表语句的字段名不要带""双引号 + +### bug +- 达梦开启等保参数 COMM_ENCRYPT_NAME = AES128_ECB,导致连接异常 + +### 版本号 +Go三段位版本号和达梦四段位版本号不兼容,统一使用1.达梦主版本号.发布的小版本号,具体查看标签的备注 + +* v1.8.13 来自 达梦8.1.3.62 +* v1.8.12 来自 达梦8.1.3.12 +* v1.8.11 来自 达梦8.1.2.192 +* v1.8.10 来自 达梦8.1.2.174 +* v1.8.9 来自 达梦8.1.2.162 +* v1.8.8 来自 达梦8.1.2.138 +* v1.8.7 来自 达梦8.1.2.128 +* v1.8.6 来自 达梦8.1.2.114 +* v1.8.5 来自 达梦8.1.2.94 +* v1.8.4 来自 达梦8.1.2.84 +* v1.8.3 来自 达梦8.1.2.38 +* v1.8.2 来自 达梦8.1.2.18 +* v1.8.1 来自 达梦8.1.1.190 +* v1.8.0 来自 达梦8.1.1.126 + + + + + + + + + + diff --git a/vendor/gitee.com/chunanyong/dm/VERSION b/vendor/gitee.com/chunanyong/dm/VERSION new file mode 100644 index 0000000000..71e68360a9 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/VERSION @@ -0,0 +1,3 @@ +#8.1.3.100 +#2023.12.14 +#20657 diff --git a/vendor/gitee.com/chunanyong/dm/a.go b/vendor/gitee.com/chunanyong/dm/a.go new file mode 100644 index 0000000000..e708b66864 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/a.go @@ -0,0 +1,838 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "bytes" + "context" + "crypto/tls" + "fmt" + "net" + "strconv" + "time" + "unicode/utf8" + + "gitee.com/chunanyong/dm/security" +) + +const ( + Dm_build_1343 = 8192 + Dm_build_1344 = 2 * time.Second +) + +type dm_build_1345 struct { + dm_build_1346 net.Conn + dm_build_1347 *tls.Conn + dm_build_1348 *Dm_build_1009 + dm_build_1349 *DmConnection + dm_build_1350 security.Cipher + dm_build_1351 bool + dm_build_1352 bool + dm_build_1353 *security.DhKey + + dm_build_1354 bool + dm_build_1355 string + dm_build_1356 bool +} + +func dm_build_1357(dm_build_1358 context.Context, dm_build_1359 *DmConnection) (*dm_build_1345, error) { + var dm_build_1360 net.Conn + var dm_build_1361 error + + dialsLock.RLock() + dm_build_1362, dm_build_1363 := dials[dm_build_1359.dmConnector.dialName] + dialsLock.RUnlock() + if dm_build_1363 { + dm_build_1360, dm_build_1361 = dm_build_1362(dm_build_1358, dm_build_1359.dmConnector.host+":"+strconv.Itoa(int(dm_build_1359.dmConnector.port))) + } else { + dm_build_1360, dm_build_1361 = dm_build_1365(dm_build_1359.dmConnector.host+":"+strconv.Itoa(int(dm_build_1359.dmConnector.port)), time.Duration(dm_build_1359.dmConnector.socketTimeout)*time.Second) + } + if dm_build_1361 != nil { + return nil, dm_build_1361 + } + + dm_build_1364 := dm_build_1345{} + dm_build_1364.dm_build_1346 = dm_build_1360 + dm_build_1364.dm_build_1348 = Dm_build_1012(Dm_build_14) + dm_build_1364.dm_build_1349 = dm_build_1359 + dm_build_1364.dm_build_1351 = false + dm_build_1364.dm_build_1352 = false + dm_build_1364.dm_build_1354 = false + dm_build_1364.dm_build_1355 = "" + dm_build_1364.dm_build_1356 = false + dm_build_1359.Access = &dm_build_1364 + + return &dm_build_1364, nil +} + +func dm_build_1365(dm_build_1366 string, dm_build_1367 time.Duration) (net.Conn, error) { + dm_build_1368, dm_build_1369 := net.DialTimeout("tcp", dm_build_1366, dm_build_1367) + if dm_build_1369 != nil { + return &net.TCPConn{}, ECGO_COMMUNITION_ERROR.addDetail("\tdial address: " + dm_build_1366).throw() + } + + if tcpConn, ok := dm_build_1368.(*net.TCPConn); ok { + tcpConn.SetKeepAlive(true) + tcpConn.SetKeepAlivePeriod(Dm_build_1344) + tcpConn.SetNoDelay(true) + + } + return dm_build_1368, nil +} + +func (dm_build_1371 *dm_build_1345) dm_build_1370(dm_build_1372 dm_build_135) bool { + var dm_build_1373 = dm_build_1371.dm_build_1349.dmConnector.compress + if dm_build_1372.dm_build_150() == Dm_build_42 || dm_build_1373 == Dm_build_91 { + return false + } + + if dm_build_1373 == Dm_build_89 { + return true + } else if dm_build_1373 == Dm_build_90 { + return !dm_build_1371.dm_build_1349.Local && dm_build_1372.dm_build_148() > Dm_build_88 + } + + return false +} + +func (dm_build_1375 *dm_build_1345) dm_build_1374(dm_build_1376 dm_build_135) bool { + var dm_build_1377 = dm_build_1375.dm_build_1349.dmConnector.compress + if dm_build_1376.dm_build_150() == Dm_build_42 || dm_build_1377 == Dm_build_91 { + return false + } + + if dm_build_1377 == Dm_build_89 { + return true + } else if dm_build_1377 == Dm_build_90 { + return dm_build_1375.dm_build_1348.Dm_build_1276(Dm_build_50) == 1 + } + + return false +} + +func (dm_build_1379 *dm_build_1345) dm_build_1378(dm_build_1380 dm_build_135) (err error) { + defer func() { + if p := recover(); p != nil { + if _, ok := p.(string); ok { + err = ECGO_COMMUNITION_ERROR.addDetail("\t" + p.(string)).throw() + } else { + err = fmt.Errorf("internal error: %v", p) + } + } + }() + + dm_build_1382 := dm_build_1380.dm_build_148() + + if dm_build_1382 > 0 { + + if dm_build_1379.dm_build_1370(dm_build_1380) { + var retBytes, err = Compress(dm_build_1379.dm_build_1348, Dm_build_43, int(dm_build_1382), int(dm_build_1379.dm_build_1349.dmConnector.compressID)) + if err != nil { + return err + } + + dm_build_1379.dm_build_1348.Dm_build_1023(Dm_build_43) + + dm_build_1379.dm_build_1348.Dm_build_1064(dm_build_1382) + + dm_build_1379.dm_build_1348.Dm_build_1092(retBytes) + + dm_build_1380.dm_build_149(int32(len(retBytes)) + ULINT_SIZE) + + dm_build_1379.dm_build_1348.Dm_build_1196(Dm_build_50, 1) + } + + if dm_build_1379.dm_build_1352 { + dm_build_1382 = dm_build_1380.dm_build_148() + var retBytes = dm_build_1379.dm_build_1350.Encrypt(dm_build_1379.dm_build_1348.Dm_build_1303(Dm_build_43, int(dm_build_1382)), true) + + dm_build_1379.dm_build_1348.Dm_build_1023(Dm_build_43) + + dm_build_1379.dm_build_1348.Dm_build_1092(retBytes) + + dm_build_1380.dm_build_149(int32(len(retBytes))) + } + } + + if dm_build_1379.dm_build_1348.Dm_build_1021() > Dm_build_15 { + return ECGO_MSG_TOO_LONG.throw() + } + + dm_build_1380.dm_build_144() + if dm_build_1379.dm_build_1613(dm_build_1380) { + if dm_build_1379.dm_build_1347 != nil { + dm_build_1379.dm_build_1348.Dm_build_1026(0) + if _, err := dm_build_1379.dm_build_1348.Dm_build_1045(dm_build_1379.dm_build_1347); err != nil { + return err + } + } + } else { + dm_build_1379.dm_build_1348.Dm_build_1026(0) + if _, err := dm_build_1379.dm_build_1348.Dm_build_1045(dm_build_1379.dm_build_1346); err != nil { + return err + } + } + return nil +} + +func (dm_build_1384 *dm_build_1345) dm_build_1383(dm_build_1385 dm_build_135) (err error) { + defer func() { + if p := recover(); p != nil { + if _, ok := p.(string); ok { + err = ECGO_COMMUNITION_ERROR.addDetail("\t" + p.(string)).throw() + } else { + err = fmt.Errorf("internal error: %v", p) + } + } + }() + + dm_build_1387 := int32(0) + if dm_build_1384.dm_build_1613(dm_build_1385) { + if dm_build_1384.dm_build_1347 != nil { + dm_build_1384.dm_build_1348.Dm_build_1023(0) + if _, err := dm_build_1384.dm_build_1348.Dm_build_1039(dm_build_1384.dm_build_1347, Dm_build_43); err != nil { + return err + } + + dm_build_1387 = dm_build_1385.dm_build_148() + if dm_build_1387 > 0 { + if _, err := dm_build_1384.dm_build_1348.Dm_build_1039(dm_build_1384.dm_build_1347, int(dm_build_1387)); err != nil { + return err + } + } + } + } else { + + dm_build_1384.dm_build_1348.Dm_build_1023(0) + if _, err := dm_build_1384.dm_build_1348.Dm_build_1039(dm_build_1384.dm_build_1346, Dm_build_43); err != nil { + return err + } + dm_build_1387 = dm_build_1385.dm_build_148() + + if dm_build_1387 > 0 { + if _, err := dm_build_1384.dm_build_1348.Dm_build_1039(dm_build_1384.dm_build_1346, int(dm_build_1387)); err != nil { + return err + } + } + } + + dm_build_1385.dm_build_145() + + dm_build_1387 = dm_build_1385.dm_build_148() + if dm_build_1387 <= 0 { + return nil + } + + if dm_build_1384.dm_build_1352 { + ebytes := dm_build_1384.dm_build_1348.Dm_build_1303(Dm_build_43, int(dm_build_1387)) + bytes, err := dm_build_1384.dm_build_1350.Decrypt(ebytes, true) + if err != nil { + return err + } + dm_build_1384.dm_build_1348.Dm_build_1023(Dm_build_43) + dm_build_1384.dm_build_1348.Dm_build_1092(bytes) + dm_build_1385.dm_build_149(int32(len(bytes))) + } + + if dm_build_1384.dm_build_1374(dm_build_1385) { + + dm_build_1387 = dm_build_1385.dm_build_148() + cbytes := dm_build_1384.dm_build_1348.Dm_build_1303(Dm_build_43+ULINT_SIZE, int(dm_build_1387-ULINT_SIZE)) + bytes, err := UnCompress(cbytes, int(dm_build_1384.dm_build_1349.dmConnector.compressID)) + if err != nil { + return err + } + dm_build_1384.dm_build_1348.Dm_build_1023(Dm_build_43) + dm_build_1384.dm_build_1348.Dm_build_1092(bytes) + dm_build_1385.dm_build_149(int32(len(bytes))) + } + return nil +} + +func (dm_build_1389 *dm_build_1345) dm_build_1388(dm_build_1390 dm_build_135) (dm_build_1391 interface{}, dm_build_1392 error) { + if dm_build_1389.dm_build_1356 { + return nil, ECGO_CONNECTION_CLOSED.throw() + } + dm_build_1393 := dm_build_1389.dm_build_1349 + dm_build_1393.mu.Lock() + defer dm_build_1393.mu.Unlock() + dm_build_1392 = dm_build_1390.dm_build_139(dm_build_1390) + if dm_build_1392 != nil { + return nil, dm_build_1392 + } + + dm_build_1392 = dm_build_1389.dm_build_1378(dm_build_1390) + if dm_build_1392 != nil { + return nil, dm_build_1392 + } + + dm_build_1392 = dm_build_1389.dm_build_1383(dm_build_1390) + if dm_build_1392 != nil { + return nil, dm_build_1392 + } + + return dm_build_1390.dm_build_143(dm_build_1390) +} + +func (dm_build_1395 *dm_build_1345) dm_build_1394() (*dm_build_592, error) { + + Dm_build_1396 := dm_build_598(dm_build_1395) + _, dm_build_1397 := dm_build_1395.dm_build_1388(Dm_build_1396) + if dm_build_1397 != nil { + return nil, dm_build_1397 + } + + return Dm_build_1396, nil +} + +func (dm_build_1399 *dm_build_1345) dm_build_1398() error { + + dm_build_1400 := dm_build_459(dm_build_1399) + _, dm_build_1401 := dm_build_1399.dm_build_1388(dm_build_1400) + if dm_build_1401 != nil { + return dm_build_1401 + } + + return nil +} + +func (dm_build_1403 *dm_build_1345) dm_build_1402() error { + + var dm_build_1404 *dm_build_592 + var err error + if dm_build_1404, err = dm_build_1403.dm_build_1394(); err != nil { + return err + } + + if dm_build_1403.dm_build_1349.sslEncrypt == 2 { + if err = dm_build_1403.dm_build_1609(false); err != nil { + return ECGO_INIT_SSL_FAILED.addDetail("\n" + err.Error()).throw() + } + } else if dm_build_1403.dm_build_1349.sslEncrypt == 1 { + if err = dm_build_1403.dm_build_1609(true); err != nil { + return ECGO_INIT_SSL_FAILED.addDetail("\n" + err.Error()).throw() + } + } + + if dm_build_1403.dm_build_1352 || dm_build_1403.dm_build_1351 { + k, err := dm_build_1403.dm_build_1599() + if err != nil { + return err + } + sessionKey := security.ComputeSessionKey(k, dm_build_1404.Dm_build_596) + encryptType := dm_build_1404.dm_build_594 + hashType := int(dm_build_1404.Dm_build_595) + if encryptType == -1 { + encryptType = security.DES_CFB + } + if hashType == -1 { + hashType = security.MD5 + } + err = dm_build_1403.dm_build_1602(encryptType, sessionKey, dm_build_1403.dm_build_1349.dmConnector.cipherPath, hashType) + if err != nil { + return err + } + } + + if err := dm_build_1403.dm_build_1398(); err != nil { + return err + } + return nil +} + +func (dm_build_1407 *dm_build_1345) Dm_build_1406(dm_build_1408 *DmStatement) error { + dm_build_1409 := dm_build_621(dm_build_1407, dm_build_1408) + _, dm_build_1410 := dm_build_1407.dm_build_1388(dm_build_1409) + if dm_build_1410 != nil { + return dm_build_1410 + } + + return nil +} + +func (dm_build_1412 *dm_build_1345) Dm_build_1411(dm_build_1413 int32) error { + dm_build_1414 := dm_build_631(dm_build_1412, dm_build_1413) + _, dm_build_1415 := dm_build_1412.dm_build_1388(dm_build_1414) + if dm_build_1415 != nil { + return dm_build_1415 + } + + return nil +} + +func (dm_build_1417 *dm_build_1345) Dm_build_1416(dm_build_1418 *DmStatement, dm_build_1419 bool, dm_build_1420 int16) (*execRetInfo, error) { + dm_build_1421 := dm_build_498(dm_build_1417, dm_build_1418, dm_build_1419, dm_build_1420) + dm_build_1422, dm_build_1423 := dm_build_1417.dm_build_1388(dm_build_1421) + if dm_build_1423 != nil { + return nil, dm_build_1423 + } + return dm_build_1422.(*execRetInfo), nil +} + +func (dm_build_1425 *dm_build_1345) Dm_build_1424(dm_build_1426 *DmStatement, dm_build_1427 int16) (*execRetInfo, error) { + return dm_build_1425.Dm_build_1416(dm_build_1426, false, Dm_build_95) +} + +func (dm_build_1429 *dm_build_1345) Dm_build_1428(dm_build_1430 *DmStatement, dm_build_1431 []OptParameter) (*execRetInfo, error) { + dm_build_1432, dm_build_1433 := dm_build_1429.dm_build_1388(dm_build_238(dm_build_1429, dm_build_1430, dm_build_1431)) + if dm_build_1433 != nil { + return nil, dm_build_1433 + } + + return dm_build_1432.(*execRetInfo), nil +} + +func (dm_build_1435 *dm_build_1345) Dm_build_1434(dm_build_1436 *DmStatement, dm_build_1437 int16) (*execRetInfo, error) { + return dm_build_1435.Dm_build_1416(dm_build_1436, true, dm_build_1437) +} + +func (dm_build_1439 *dm_build_1345) Dm_build_1438(dm_build_1440 *DmStatement, dm_build_1441 [][]interface{}) (*execRetInfo, error) { + dm_build_1442 := dm_build_270(dm_build_1439, dm_build_1440, dm_build_1441) + dm_build_1443, dm_build_1444 := dm_build_1439.dm_build_1388(dm_build_1442) + if dm_build_1444 != nil { + return nil, dm_build_1444 + } + return dm_build_1443.(*execRetInfo), nil +} + +func (dm_build_1446 *dm_build_1345) Dm_build_1445(dm_build_1447 *DmStatement, dm_build_1448 [][]interface{}, dm_build_1449 bool) (*execRetInfo, error) { + var dm_build_1450, dm_build_1451 = 0, 0 + var dm_build_1452 = len(dm_build_1448) + var dm_build_1453 [][]interface{} + var dm_build_1454 = NewExceInfo() + dm_build_1454.updateCounts = make([]int64, dm_build_1452) + var dm_build_1455 = false + for dm_build_1450 < dm_build_1452 { + for dm_build_1451 = dm_build_1450; dm_build_1451 < dm_build_1452; dm_build_1451++ { + paramData := dm_build_1448[dm_build_1451] + bindData := make([]interface{}, dm_build_1447.paramCount) + dm_build_1455 = false + for icol := 0; icol < int(dm_build_1447.paramCount); icol++ { + if dm_build_1447.bindParams[icol].ioType == IO_TYPE_OUT { + continue + } + if dm_build_1446.dm_build_1582(bindData, paramData, icol) { + dm_build_1455 = true + break + } + } + + if dm_build_1455 { + break + } + dm_build_1453 = append(dm_build_1453, bindData) + } + + if dm_build_1451 != dm_build_1450 { + tmpExecInfo, err := dm_build_1446.Dm_build_1438(dm_build_1447, dm_build_1453) + if err != nil { + return nil, err + } + dm_build_1453 = dm_build_1453[0:0] + dm_build_1454.union(tmpExecInfo, dm_build_1450, dm_build_1451-dm_build_1450) + } + + if dm_build_1451 < dm_build_1452 { + tmpExecInfo, err := dm_build_1446.Dm_build_1456(dm_build_1447, dm_build_1448[dm_build_1451], dm_build_1449) + if err != nil { + return nil, err + } + + dm_build_1449 = true + dm_build_1454.union(tmpExecInfo, dm_build_1451, 1) + } + + dm_build_1450 = dm_build_1451 + 1 + } + for _, i := range dm_build_1454.updateCounts { + if i > 0 { + dm_build_1454.updateCount += i + } + } + return dm_build_1454, nil +} + +func (dm_build_1457 *dm_build_1345) Dm_build_1456(dm_build_1458 *DmStatement, dm_build_1459 []interface{}, dm_build_1460 bool) (*execRetInfo, error) { + + var dm_build_1461 = make([]interface{}, dm_build_1458.paramCount) + for icol := 0; icol < int(dm_build_1458.paramCount); icol++ { + if dm_build_1458.bindParams[icol].ioType == IO_TYPE_OUT { + continue + } + if dm_build_1457.dm_build_1582(dm_build_1461, dm_build_1459, icol) { + + if !dm_build_1460 { + preExecute := dm_build_487(dm_build_1457, dm_build_1458, dm_build_1458.bindParams) + dm_build_1457.dm_build_1388(preExecute) + dm_build_1460 = true + } + + dm_build_1457.dm_build_1588(dm_build_1458, dm_build_1458.bindParams[icol], icol, dm_build_1459[icol].(iOffRowBinder)) + dm_build_1461[icol] = ParamDataEnum_OFF_ROW + } + } + + var dm_build_1462 = make([][]interface{}, 1, 1) + dm_build_1462[0] = dm_build_1461 + + dm_build_1463 := dm_build_270(dm_build_1457, dm_build_1458, dm_build_1462) + dm_build_1464, dm_build_1465 := dm_build_1457.dm_build_1388(dm_build_1463) + if dm_build_1465 != nil { + return nil, dm_build_1465 + } + return dm_build_1464.(*execRetInfo), nil +} + +func (dm_build_1467 *dm_build_1345) Dm_build_1466(dm_build_1468 *DmStatement, dm_build_1469 int16) (*execRetInfo, error) { + dm_build_1470 := dm_build_474(dm_build_1467, dm_build_1468, dm_build_1469) + + dm_build_1471, dm_build_1472 := dm_build_1467.dm_build_1388(dm_build_1470) + if dm_build_1472 != nil { + return nil, dm_build_1472 + } + return dm_build_1471.(*execRetInfo), nil +} + +func (dm_build_1474 *dm_build_1345) Dm_build_1473(dm_build_1475 *innerRows, dm_build_1476 int64) (*execRetInfo, error) { + dm_build_1477 := dm_build_377(dm_build_1474, dm_build_1475, dm_build_1476, INT64_MAX) + dm_build_1478, dm_build_1479 := dm_build_1474.dm_build_1388(dm_build_1477) + if dm_build_1479 != nil { + return nil, dm_build_1479 + } + return dm_build_1478.(*execRetInfo), nil +} + +func (dm_build_1481 *dm_build_1345) Commit() error { + dm_build_1482 := dm_build_223(dm_build_1481) + _, dm_build_1483 := dm_build_1481.dm_build_1388(dm_build_1482) + if dm_build_1483 != nil { + return dm_build_1483 + } + + return nil +} + +func (dm_build_1485 *dm_build_1345) Rollback() error { + dm_build_1486 := dm_build_536(dm_build_1485) + _, dm_build_1487 := dm_build_1485.dm_build_1388(dm_build_1486) + if dm_build_1487 != nil { + return dm_build_1487 + } + + return nil +} + +func (dm_build_1489 *dm_build_1345) Dm_build_1488(dm_build_1490 *DmConnection) error { + dm_build_1491 := dm_build_541(dm_build_1489, dm_build_1490.IsoLevel) + _, dm_build_1492 := dm_build_1489.dm_build_1388(dm_build_1491) + if dm_build_1492 != nil { + return dm_build_1492 + } + + return nil +} + +func (dm_build_1494 *dm_build_1345) Dm_build_1493(dm_build_1495 *DmStatement, dm_build_1496 string) error { + dm_build_1497 := dm_build_228(dm_build_1494, dm_build_1495, dm_build_1496) + _, dm_build_1498 := dm_build_1494.dm_build_1388(dm_build_1497) + if dm_build_1498 != nil { + return dm_build_1498 + } + + return nil +} + +func (dm_build_1500 *dm_build_1345) Dm_build_1499(dm_build_1501 []uint32) ([]int64, error) { + dm_build_1502 := dm_build_639(dm_build_1500, dm_build_1501) + dm_build_1503, dm_build_1504 := dm_build_1500.dm_build_1388(dm_build_1502) + if dm_build_1504 != nil { + return nil, dm_build_1504 + } + return dm_build_1503.([]int64), nil +} + +func (dm_build_1506 *dm_build_1345) Close() error { + if dm_build_1506.dm_build_1356 { + return nil + } + + dm_build_1507 := dm_build_1506.dm_build_1346.Close() + if dm_build_1507 != nil { + return dm_build_1507 + } + + dm_build_1506.dm_build_1349 = nil + dm_build_1506.dm_build_1356 = true + return nil +} + +func (dm_build_1509 *dm_build_1345) dm_build_1508(dm_build_1510 *lob) (int64, error) { + dm_build_1511 := dm_build_410(dm_build_1509, dm_build_1510) + dm_build_1512, dm_build_1513 := dm_build_1509.dm_build_1388(dm_build_1511) + if dm_build_1513 != nil { + return 0, dm_build_1513 + } + return dm_build_1512.(int64), nil +} + +func (dm_build_1515 *dm_build_1345) dm_build_1514(dm_build_1516 *lob, dm_build_1517 int32, dm_build_1518 int32) (*lobRetInfo, error) { + dm_build_1519 := dm_build_395(dm_build_1515, dm_build_1516, int(dm_build_1517), int(dm_build_1518)) + dm_build_1520, dm_build_1521 := dm_build_1515.dm_build_1388(dm_build_1519) + if dm_build_1521 != nil { + return nil, dm_build_1521 + } + return dm_build_1520.(*lobRetInfo), nil +} + +func (dm_build_1523 *dm_build_1345) dm_build_1522(dm_build_1524 *DmBlob, dm_build_1525 int32, dm_build_1526 int32) ([]byte, error) { + var dm_build_1527 = make([]byte, dm_build_1526) + var dm_build_1528 int32 = 0 + var dm_build_1529 int32 = 0 + var dm_build_1530 *lobRetInfo + var dm_build_1531 []byte + var dm_build_1532 error + for dm_build_1528 < dm_build_1526 { + dm_build_1529 = dm_build_1526 - dm_build_1528 + if dm_build_1529 > Dm_build_128 { + dm_build_1529 = Dm_build_128 + } + dm_build_1530, dm_build_1532 = dm_build_1523.dm_build_1514(&dm_build_1524.lob, dm_build_1525+dm_build_1528, dm_build_1529) + if dm_build_1532 != nil { + return nil, dm_build_1532 + } + dm_build_1531 = dm_build_1530.data + if dm_build_1531 == nil || len(dm_build_1531) == 0 { + break + } + Dm_build_650.Dm_build_706(dm_build_1527, int(dm_build_1528), dm_build_1531, 0, len(dm_build_1531)) + dm_build_1528 += int32(len(dm_build_1531)) + if dm_build_1524.readOver { + break + } + } + return dm_build_1527, nil +} + +func (dm_build_1534 *dm_build_1345) dm_build_1533(dm_build_1535 *DmClob, dm_build_1536 int32, dm_build_1537 int32) (string, error) { + var dm_build_1538 bytes.Buffer + var dm_build_1539 int32 = 0 + var dm_build_1540 int32 = 0 + var dm_build_1541 *lobRetInfo + var dm_build_1542 []byte + var dm_build_1543 string + var dm_build_1544 error + for dm_build_1539 < dm_build_1537 { + dm_build_1540 = dm_build_1537 - dm_build_1539 + if dm_build_1540 > Dm_build_128/2 { + dm_build_1540 = Dm_build_128 / 2 + } + dm_build_1541, dm_build_1544 = dm_build_1534.dm_build_1514(&dm_build_1535.lob, dm_build_1536+dm_build_1539, dm_build_1540) + if dm_build_1544 != nil { + return "", dm_build_1544 + } + dm_build_1542 = dm_build_1541.data + if dm_build_1542 == nil || len(dm_build_1542) == 0 { + break + } + dm_build_1543 = Dm_build_650.Dm_build_807(dm_build_1542, 0, len(dm_build_1542), dm_build_1535.serverEncoding, dm_build_1534.dm_build_1349) + + dm_build_1538.WriteString(dm_build_1543) + var strLen = dm_build_1541.charLen + if strLen == -1 { + strLen = int64(utf8.RuneCountInString(dm_build_1543)) + } + dm_build_1539 += int32(strLen) + if dm_build_1535.readOver { + break + } + } + return dm_build_1538.String(), nil +} + +func (dm_build_1546 *dm_build_1345) dm_build_1545(dm_build_1547 *DmClob, dm_build_1548 int, dm_build_1549 string, dm_build_1550 string) (int, error) { + var dm_build_1551 = Dm_build_650.Dm_build_866(dm_build_1549, dm_build_1550, dm_build_1546.dm_build_1349) + var dm_build_1552 = 0 + var dm_build_1553 = len(dm_build_1551) + var dm_build_1554 = 0 + var dm_build_1555 = 0 + var dm_build_1556 = 0 + var dm_build_1557 = dm_build_1553/Dm_build_127 + 1 + var dm_build_1558 byte = 0 + var dm_build_1559 byte = 0x01 + var dm_build_1560 byte = 0x02 + for i := 0; i < dm_build_1557; i++ { + dm_build_1558 = 0 + if i == 0 { + dm_build_1558 |= dm_build_1559 + } + if i == dm_build_1557-1 { + dm_build_1558 |= dm_build_1560 + } + dm_build_1556 = dm_build_1553 - dm_build_1555 + if dm_build_1556 > Dm_build_127 { + dm_build_1556 = Dm_build_127 + } + + setLobData := dm_build_555(dm_build_1546, &dm_build_1547.lob, dm_build_1558, dm_build_1548, dm_build_1551, dm_build_1552, dm_build_1556) + ret, err := dm_build_1546.dm_build_1388(setLobData) + if err != nil { + return 0, err + } + tmp := ret.(int32) + if err != nil { + return -1, err + } + if tmp <= 0 { + return dm_build_1554, nil + } else { + dm_build_1548 += int(tmp) + dm_build_1554 += int(tmp) + dm_build_1555 += dm_build_1556 + dm_build_1552 += dm_build_1556 + } + } + return dm_build_1554, nil +} + +func (dm_build_1562 *dm_build_1345) dm_build_1561(dm_build_1563 *DmBlob, dm_build_1564 int, dm_build_1565 []byte) (int, error) { + var dm_build_1566 = 0 + var dm_build_1567 = len(dm_build_1565) + var dm_build_1568 = 0 + var dm_build_1569 = 0 + var dm_build_1570 = 0 + var dm_build_1571 = dm_build_1567/Dm_build_127 + 1 + var dm_build_1572 byte = 0 + var dm_build_1573 byte = 0x01 + var dm_build_1574 byte = 0x02 + for i := 0; i < dm_build_1571; i++ { + dm_build_1572 = 0 + if i == 0 { + dm_build_1572 |= dm_build_1573 + } + if i == dm_build_1571-1 { + dm_build_1572 |= dm_build_1574 + } + dm_build_1570 = dm_build_1567 - dm_build_1569 + if dm_build_1570 > Dm_build_127 { + dm_build_1570 = Dm_build_127 + } + + setLobData := dm_build_555(dm_build_1562, &dm_build_1563.lob, dm_build_1572, dm_build_1564, dm_build_1565, dm_build_1566, dm_build_1570) + ret, err := dm_build_1562.dm_build_1388(setLobData) + if err != nil { + return 0, err + } + tmp := ret.(int32) + if tmp <= 0 { + return dm_build_1568, nil + } else { + dm_build_1564 += int(tmp) + dm_build_1568 += int(tmp) + dm_build_1569 += dm_build_1570 + dm_build_1566 += dm_build_1570 + } + } + return dm_build_1568, nil +} + +func (dm_build_1576 *dm_build_1345) dm_build_1575(dm_build_1577 *lob, dm_build_1578 int) (int64, error) { + dm_build_1579 := dm_build_421(dm_build_1576, dm_build_1577, dm_build_1578) + dm_build_1580, dm_build_1581 := dm_build_1576.dm_build_1388(dm_build_1579) + if dm_build_1581 != nil { + return dm_build_1577.length, dm_build_1581 + } + return dm_build_1580.(int64), nil +} + +func (dm_build_1583 *dm_build_1345) dm_build_1582(dm_build_1584 []interface{}, dm_build_1585 []interface{}, dm_build_1586 int) bool { + var dm_build_1587 = false + dm_build_1584[dm_build_1586] = dm_build_1585[dm_build_1586] + + if binder, ok := dm_build_1585[dm_build_1586].(iOffRowBinder); ok { + dm_build_1587 = true + dm_build_1584[dm_build_1586] = make([]byte, 0) + 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_1583.dm_build_1349) { + dm_build_1584[dm_build_1586] = &lobCtl{lob.buildCtlData()} + dm_build_1587 = false + } + } else { + dm_build_1584[dm_build_1586] = dm_build_1585[dm_build_1586] + } + return dm_build_1587 +} + +func (dm_build_1589 *dm_build_1345) dm_build_1588(dm_build_1590 *DmStatement, dm_build_1591 parameter, dm_build_1592 int, dm_build_1593 iOffRowBinder) error { + var dm_build_1594 = Dm_build_935() + dm_build_1593.read(dm_build_1594) + var dm_build_1595 = 0 + for !dm_build_1593.isReadOver() || dm_build_1594.Dm_build_936() > 0 { + if !dm_build_1593.isReadOver() && dm_build_1594.Dm_build_936() < Dm_build_127 { + dm_build_1593.read(dm_build_1594) + } + if dm_build_1594.Dm_build_936() > Dm_build_127 { + dm_build_1595 = Dm_build_127 + } else { + dm_build_1595 = dm_build_1594.Dm_build_936() + } + + putData := dm_build_526(dm_build_1589, dm_build_1590, int16(dm_build_1592), dm_build_1594, int32(dm_build_1595)) + _, err := dm_build_1589.dm_build_1388(putData) + if err != nil { + return err + } + } + return nil +} + +func (dm_build_1597 *dm_build_1345) dm_build_1596() ([]byte, error) { + var dm_build_1598 error + if dm_build_1597.dm_build_1353 == nil { + if dm_build_1597.dm_build_1353, dm_build_1598 = security.NewClientKeyPair(); dm_build_1598 != nil { + return nil, dm_build_1598 + } + } + return security.Bn2Bytes(dm_build_1597.dm_build_1353.GetY(), security.DH_KEY_LENGTH), nil +} + +func (dm_build_1600 *dm_build_1345) dm_build_1599() (*security.DhKey, error) { + var dm_build_1601 error + if dm_build_1600.dm_build_1353 == nil { + if dm_build_1600.dm_build_1353, dm_build_1601 = security.NewClientKeyPair(); dm_build_1601 != nil { + return nil, dm_build_1601 + } + } + return dm_build_1600.dm_build_1353, nil +} + +func (dm_build_1603 *dm_build_1345) dm_build_1602(dm_build_1604 int, dm_build_1605 []byte, dm_build_1606 string, dm_build_1607 int) (dm_build_1608 error) { + if dm_build_1604 > 0 && dm_build_1604 < security.MIN_EXTERNAL_CIPHER_ID && dm_build_1605 != nil { + dm_build_1603.dm_build_1350, dm_build_1608 = security.NewSymmCipher(dm_build_1604, dm_build_1605) + } else if dm_build_1604 >= security.MIN_EXTERNAL_CIPHER_ID { + if dm_build_1603.dm_build_1350, dm_build_1608 = security.NewThirdPartCipher(dm_build_1604, dm_build_1605, dm_build_1606, dm_build_1607); dm_build_1608 != nil { + dm_build_1608 = THIRD_PART_CIPHER_INIT_FAILED.addDetailln(dm_build_1608.Error()).throw() + } + } + return +} + +func (dm_build_1610 *dm_build_1345) dm_build_1609(dm_build_1611 bool) (dm_build_1612 error) { + if dm_build_1610.dm_build_1347, dm_build_1612 = security.NewTLSFromTCP(dm_build_1610.dm_build_1346, dm_build_1610.dm_build_1349.dmConnector.sslCertPath, dm_build_1610.dm_build_1349.dmConnector.sslKeyPath, dm_build_1610.dm_build_1349.dmConnector.user); dm_build_1612 != nil { + return + } + if !dm_build_1611 { + dm_build_1610.dm_build_1347 = nil + } + return +} + +func (dm_build_1614 *dm_build_1345) dm_build_1613(dm_build_1615 dm_build_135) bool { + return dm_build_1615.dm_build_150() != Dm_build_42 && dm_build_1614.dm_build_1349.sslEncrypt == 1 +} diff --git a/vendor/gitee.com/chunanyong/dm/b.go b/vendor/gitee.com/chunanyong/dm/b.go new file mode 100644 index 0000000000..6939100e52 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/b.go @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +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/vendor/gitee.com/chunanyong/dm/c.go b/vendor/gitee.com/chunanyong/dm/c.go new file mode 100644 index 0000000000..1704999ff5 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/c.go @@ -0,0 +1,495 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "io" + "math" +) + +type Dm_build_1009 struct { + dm_build_1010 []byte + dm_build_1011 int +} + +func Dm_build_1012(dm_build_1013 int) *Dm_build_1009 { + return &Dm_build_1009{make([]byte, 0, dm_build_1013), 0} +} + +func Dm_build_1014(dm_build_1015 []byte) *Dm_build_1009 { + return &Dm_build_1009{dm_build_1015, 0} +} + +func (dm_build_1017 *Dm_build_1009) dm_build_1016(dm_build_1018 int) *Dm_build_1009 { + + dm_build_1019 := len(dm_build_1017.dm_build_1010) + dm_build_1020 := cap(dm_build_1017.dm_build_1010) + + if dm_build_1019+dm_build_1018 <= dm_build_1020 { + dm_build_1017.dm_build_1010 = dm_build_1017.dm_build_1010[:dm_build_1019+dm_build_1018] + } else { + + var calCap = int64(math.Max(float64(2*dm_build_1020), float64(dm_build_1018+dm_build_1019))) + + nbuf := make([]byte, dm_build_1018+dm_build_1019, calCap) + copy(nbuf, dm_build_1017.dm_build_1010) + dm_build_1017.dm_build_1010 = nbuf + } + + return dm_build_1017 +} + +func (dm_build_1022 *Dm_build_1009) Dm_build_1021() int { + return len(dm_build_1022.dm_build_1010) +} + +func (dm_build_1024 *Dm_build_1009) Dm_build_1023(dm_build_1025 int) *Dm_build_1009 { + for i := dm_build_1025; i < len(dm_build_1024.dm_build_1010); i++ { + dm_build_1024.dm_build_1010[i] = 0 + } + dm_build_1024.dm_build_1010 = dm_build_1024.dm_build_1010[:dm_build_1025] + return dm_build_1024 +} + +func (dm_build_1027 *Dm_build_1009) Dm_build_1026(dm_build_1028 int) *Dm_build_1009 { + dm_build_1027.dm_build_1011 = dm_build_1028 + return dm_build_1027 +} + +func (dm_build_1030 *Dm_build_1009) Dm_build_1029() int { + return dm_build_1030.dm_build_1011 +} + +func (dm_build_1032 *Dm_build_1009) Dm_build_1031(dm_build_1033 bool) int { + return len(dm_build_1032.dm_build_1010) - dm_build_1032.dm_build_1011 +} + +func (dm_build_1035 *Dm_build_1009) Dm_build_1034(dm_build_1036 int, dm_build_1037 bool, dm_build_1038 bool) *Dm_build_1009 { + + if dm_build_1037 { + if dm_build_1038 { + dm_build_1035.dm_build_1016(dm_build_1036) + } else { + dm_build_1035.dm_build_1010 = dm_build_1035.dm_build_1010[:len(dm_build_1035.dm_build_1010)-dm_build_1036] + } + } else { + if dm_build_1038 { + dm_build_1035.dm_build_1011 += dm_build_1036 + } else { + dm_build_1035.dm_build_1011 -= dm_build_1036 + } + } + + return dm_build_1035 +} + +func (dm_build_1040 *Dm_build_1009) Dm_build_1039(dm_build_1041 io.Reader, dm_build_1042 int) (int, error) { + dm_build_1043 := len(dm_build_1040.dm_build_1010) + dm_build_1040.dm_build_1016(dm_build_1042) + dm_build_1044 := 0 + for dm_build_1042 > 0 { + n, err := dm_build_1041.Read(dm_build_1040.dm_build_1010[dm_build_1043+dm_build_1044:]) + if n > 0 && err == io.EOF { + dm_build_1044 += n + dm_build_1040.dm_build_1010 = dm_build_1040.dm_build_1010[:dm_build_1043+dm_build_1044] + return dm_build_1044, nil + } else if n > 0 && err == nil { + dm_build_1042 -= n + dm_build_1044 += n + } else if n == 0 && err != nil { + return -1, ECGO_COMMUNITION_ERROR.addDetailln(err.Error()).throw() + } + } + + return dm_build_1044, nil +} + +func (dm_build_1046 *Dm_build_1009) Dm_build_1045(dm_build_1047 io.Writer) (*Dm_build_1009, error) { + if _, err := dm_build_1047.Write(dm_build_1046.dm_build_1010); err != nil { + return nil, ECGO_COMMUNITION_ERROR.addDetailln(err.Error()).throw() + } + return dm_build_1046, nil +} + +func (dm_build_1049 *Dm_build_1009) Dm_build_1048(dm_build_1050 bool) int { + dm_build_1051 := len(dm_build_1049.dm_build_1010) + dm_build_1049.dm_build_1016(1) + + if dm_build_1050 { + return copy(dm_build_1049.dm_build_1010[dm_build_1051:], []byte{1}) + } else { + return copy(dm_build_1049.dm_build_1010[dm_build_1051:], []byte{0}) + } +} + +func (dm_build_1053 *Dm_build_1009) Dm_build_1052(dm_build_1054 byte) int { + dm_build_1055 := len(dm_build_1053.dm_build_1010) + dm_build_1053.dm_build_1016(1) + + return copy(dm_build_1053.dm_build_1010[dm_build_1055:], Dm_build_650.Dm_build_828(dm_build_1054)) +} + +func (dm_build_1057 *Dm_build_1009) Dm_build_1056(dm_build_1058 int8) int { + dm_build_1059 := len(dm_build_1057.dm_build_1010) + dm_build_1057.dm_build_1016(1) + + return copy(dm_build_1057.dm_build_1010[dm_build_1059:], Dm_build_650.Dm_build_831(dm_build_1058)) +} + +func (dm_build_1061 *Dm_build_1009) Dm_build_1060(dm_build_1062 int16) int { + dm_build_1063 := len(dm_build_1061.dm_build_1010) + dm_build_1061.dm_build_1016(2) + + return copy(dm_build_1061.dm_build_1010[dm_build_1063:], Dm_build_650.Dm_build_834(dm_build_1062)) +} + +func (dm_build_1065 *Dm_build_1009) Dm_build_1064(dm_build_1066 int32) int { + dm_build_1067 := len(dm_build_1065.dm_build_1010) + dm_build_1065.dm_build_1016(4) + + return copy(dm_build_1065.dm_build_1010[dm_build_1067:], Dm_build_650.Dm_build_837(dm_build_1066)) +} + +func (dm_build_1069 *Dm_build_1009) Dm_build_1068(dm_build_1070 uint8) int { + dm_build_1071 := len(dm_build_1069.dm_build_1010) + dm_build_1069.dm_build_1016(1) + + return copy(dm_build_1069.dm_build_1010[dm_build_1071:], Dm_build_650.Dm_build_849(dm_build_1070)) +} + +func (dm_build_1073 *Dm_build_1009) Dm_build_1072(dm_build_1074 uint16) int { + dm_build_1075 := len(dm_build_1073.dm_build_1010) + dm_build_1073.dm_build_1016(2) + + return copy(dm_build_1073.dm_build_1010[dm_build_1075:], Dm_build_650.Dm_build_852(dm_build_1074)) +} + +func (dm_build_1077 *Dm_build_1009) Dm_build_1076(dm_build_1078 uint32) int { + dm_build_1079 := len(dm_build_1077.dm_build_1010) + dm_build_1077.dm_build_1016(4) + + return copy(dm_build_1077.dm_build_1010[dm_build_1079:], Dm_build_650.Dm_build_855(dm_build_1078)) +} + +func (dm_build_1081 *Dm_build_1009) Dm_build_1080(dm_build_1082 uint64) int { + dm_build_1083 := len(dm_build_1081.dm_build_1010) + dm_build_1081.dm_build_1016(8) + + return copy(dm_build_1081.dm_build_1010[dm_build_1083:], Dm_build_650.Dm_build_858(dm_build_1082)) +} + +func (dm_build_1085 *Dm_build_1009) Dm_build_1084(dm_build_1086 float32) int { + dm_build_1087 := len(dm_build_1085.dm_build_1010) + dm_build_1085.dm_build_1016(4) + + return copy(dm_build_1085.dm_build_1010[dm_build_1087:], Dm_build_650.Dm_build_855(math.Float32bits(dm_build_1086))) +} + +func (dm_build_1089 *Dm_build_1009) Dm_build_1088(dm_build_1090 float64) int { + dm_build_1091 := len(dm_build_1089.dm_build_1010) + dm_build_1089.dm_build_1016(8) + + return copy(dm_build_1089.dm_build_1010[dm_build_1091:], Dm_build_650.Dm_build_858(math.Float64bits(dm_build_1090))) +} + +func (dm_build_1093 *Dm_build_1009) Dm_build_1092(dm_build_1094 []byte) int { + dm_build_1095 := len(dm_build_1093.dm_build_1010) + dm_build_1093.dm_build_1016(len(dm_build_1094)) + return copy(dm_build_1093.dm_build_1010[dm_build_1095:], dm_build_1094) +} + +func (dm_build_1097 *Dm_build_1009) Dm_build_1096(dm_build_1098 []byte) int { + return dm_build_1097.Dm_build_1064(int32(len(dm_build_1098))) + dm_build_1097.Dm_build_1092(dm_build_1098) +} + +func (dm_build_1100 *Dm_build_1009) Dm_build_1099(dm_build_1101 []byte) int { + return dm_build_1100.Dm_build_1068(uint8(len(dm_build_1101))) + dm_build_1100.Dm_build_1092(dm_build_1101) +} + +func (dm_build_1103 *Dm_build_1009) Dm_build_1102(dm_build_1104 []byte) int { + return dm_build_1103.Dm_build_1072(uint16(len(dm_build_1104))) + dm_build_1103.Dm_build_1092(dm_build_1104) +} + +func (dm_build_1106 *Dm_build_1009) Dm_build_1105(dm_build_1107 []byte) int { + return dm_build_1106.Dm_build_1092(dm_build_1107) + dm_build_1106.Dm_build_1052(0) +} + +func (dm_build_1109 *Dm_build_1009) Dm_build_1108(dm_build_1110 string, dm_build_1111 string, dm_build_1112 *DmConnection) int { + dm_build_1113 := Dm_build_650.Dm_build_866(dm_build_1110, dm_build_1111, dm_build_1112) + return dm_build_1109.Dm_build_1096(dm_build_1113) +} + +func (dm_build_1115 *Dm_build_1009) Dm_build_1114(dm_build_1116 string, dm_build_1117 string, dm_build_1118 *DmConnection) int { + dm_build_1119 := Dm_build_650.Dm_build_866(dm_build_1116, dm_build_1117, dm_build_1118) + return dm_build_1115.Dm_build_1099(dm_build_1119) +} + +func (dm_build_1121 *Dm_build_1009) Dm_build_1120(dm_build_1122 string, dm_build_1123 string, dm_build_1124 *DmConnection) int { + dm_build_1125 := Dm_build_650.Dm_build_866(dm_build_1122, dm_build_1123, dm_build_1124) + return dm_build_1121.Dm_build_1102(dm_build_1125) +} + +func (dm_build_1127 *Dm_build_1009) Dm_build_1126(dm_build_1128 string, dm_build_1129 string, dm_build_1130 *DmConnection) int { + dm_build_1131 := Dm_build_650.Dm_build_866(dm_build_1128, dm_build_1129, dm_build_1130) + return dm_build_1127.Dm_build_1105(dm_build_1131) +} + +func (dm_build_1133 *Dm_build_1009) Dm_build_1132() byte { + dm_build_1134 := Dm_build_650.Dm_build_743(dm_build_1133.dm_build_1010, dm_build_1133.dm_build_1011) + dm_build_1133.dm_build_1011++ + return dm_build_1134 +} + +func (dm_build_1136 *Dm_build_1009) Dm_build_1135() int16 { + dm_build_1137 := Dm_build_650.Dm_build_747(dm_build_1136.dm_build_1010, dm_build_1136.dm_build_1011) + dm_build_1136.dm_build_1011 += 2 + return dm_build_1137 +} + +func (dm_build_1139 *Dm_build_1009) Dm_build_1138() int32 { + dm_build_1140 := Dm_build_650.Dm_build_752(dm_build_1139.dm_build_1010, dm_build_1139.dm_build_1011) + dm_build_1139.dm_build_1011 += 4 + return dm_build_1140 +} + +func (dm_build_1142 *Dm_build_1009) Dm_build_1141() int64 { + dm_build_1143 := Dm_build_650.Dm_build_757(dm_build_1142.dm_build_1010, dm_build_1142.dm_build_1011) + dm_build_1142.dm_build_1011 += 8 + return dm_build_1143 +} + +func (dm_build_1145 *Dm_build_1009) Dm_build_1144() float32 { + dm_build_1146 := Dm_build_650.Dm_build_762(dm_build_1145.dm_build_1010, dm_build_1145.dm_build_1011) + dm_build_1145.dm_build_1011 += 4 + return dm_build_1146 +} + +func (dm_build_1148 *Dm_build_1009) Dm_build_1147() float64 { + dm_build_1149 := Dm_build_650.Dm_build_766(dm_build_1148.dm_build_1010, dm_build_1148.dm_build_1011) + dm_build_1148.dm_build_1011 += 8 + return dm_build_1149 +} + +func (dm_build_1151 *Dm_build_1009) Dm_build_1150() uint8 { + dm_build_1152 := Dm_build_650.Dm_build_770(dm_build_1151.dm_build_1010, dm_build_1151.dm_build_1011) + dm_build_1151.dm_build_1011 += 1 + return dm_build_1152 +} + +func (dm_build_1154 *Dm_build_1009) Dm_build_1153() uint16 { + dm_build_1155 := Dm_build_650.Dm_build_774(dm_build_1154.dm_build_1010, dm_build_1154.dm_build_1011) + dm_build_1154.dm_build_1011 += 2 + return dm_build_1155 +} + +func (dm_build_1157 *Dm_build_1009) Dm_build_1156() uint32 { + dm_build_1158 := Dm_build_650.Dm_build_779(dm_build_1157.dm_build_1010, dm_build_1157.dm_build_1011) + dm_build_1157.dm_build_1011 += 4 + return dm_build_1158 +} + +func (dm_build_1160 *Dm_build_1009) Dm_build_1159(dm_build_1161 int) []byte { + dm_build_1162 := Dm_build_650.Dm_build_801(dm_build_1160.dm_build_1010, dm_build_1160.dm_build_1011, dm_build_1161) + dm_build_1160.dm_build_1011 += dm_build_1161 + return dm_build_1162 +} + +func (dm_build_1164 *Dm_build_1009) Dm_build_1163() []byte { + return dm_build_1164.Dm_build_1159(int(dm_build_1164.Dm_build_1138())) +} + +func (dm_build_1166 *Dm_build_1009) Dm_build_1165() []byte { + return dm_build_1166.Dm_build_1159(int(dm_build_1166.Dm_build_1132())) +} + +func (dm_build_1168 *Dm_build_1009) Dm_build_1167() []byte { + return dm_build_1168.Dm_build_1159(int(dm_build_1168.Dm_build_1135())) +} + +func (dm_build_1170 *Dm_build_1009) Dm_build_1169(dm_build_1171 int) []byte { + return dm_build_1170.Dm_build_1159(dm_build_1171) +} + +func (dm_build_1173 *Dm_build_1009) Dm_build_1172() []byte { + dm_build_1174 := 0 + for dm_build_1173.Dm_build_1132() != 0 { + dm_build_1174++ + } + dm_build_1173.Dm_build_1034(dm_build_1174, false, false) + return dm_build_1173.Dm_build_1159(dm_build_1174) +} + +func (dm_build_1176 *Dm_build_1009) Dm_build_1175(dm_build_1177 int, dm_build_1178 string, dm_build_1179 *DmConnection) string { + return Dm_build_650.Dm_build_902(dm_build_1176.Dm_build_1159(dm_build_1177), dm_build_1178, dm_build_1179) +} + +func (dm_build_1181 *Dm_build_1009) Dm_build_1180(dm_build_1182 string, dm_build_1183 *DmConnection) string { + return Dm_build_650.Dm_build_902(dm_build_1181.Dm_build_1163(), dm_build_1182, dm_build_1183) +} + +func (dm_build_1185 *Dm_build_1009) Dm_build_1184(dm_build_1186 string, dm_build_1187 *DmConnection) string { + return Dm_build_650.Dm_build_902(dm_build_1185.Dm_build_1165(), dm_build_1186, dm_build_1187) +} + +func (dm_build_1189 *Dm_build_1009) Dm_build_1188(dm_build_1190 string, dm_build_1191 *DmConnection) string { + return Dm_build_650.Dm_build_902(dm_build_1189.Dm_build_1167(), dm_build_1190, dm_build_1191) +} + +func (dm_build_1193 *Dm_build_1009) Dm_build_1192(dm_build_1194 string, dm_build_1195 *DmConnection) string { + return Dm_build_650.Dm_build_902(dm_build_1193.Dm_build_1172(), dm_build_1194, dm_build_1195) +} + +func (dm_build_1197 *Dm_build_1009) Dm_build_1196(dm_build_1198 int, dm_build_1199 byte) int { + return dm_build_1197.Dm_build_1232(dm_build_1198, Dm_build_650.Dm_build_828(dm_build_1199)) +} + +func (dm_build_1201 *Dm_build_1009) Dm_build_1200(dm_build_1202 int, dm_build_1203 int16) int { + return dm_build_1201.Dm_build_1232(dm_build_1202, Dm_build_650.Dm_build_834(dm_build_1203)) +} + +func (dm_build_1205 *Dm_build_1009) Dm_build_1204(dm_build_1206 int, dm_build_1207 int32) int { + return dm_build_1205.Dm_build_1232(dm_build_1206, Dm_build_650.Dm_build_837(dm_build_1207)) +} + +func (dm_build_1209 *Dm_build_1009) Dm_build_1208(dm_build_1210 int, dm_build_1211 int64) int { + return dm_build_1209.Dm_build_1232(dm_build_1210, Dm_build_650.Dm_build_840(dm_build_1211)) +} + +func (dm_build_1213 *Dm_build_1009) Dm_build_1212(dm_build_1214 int, dm_build_1215 float32) int { + return dm_build_1213.Dm_build_1232(dm_build_1214, Dm_build_650.Dm_build_843(dm_build_1215)) +} + +func (dm_build_1217 *Dm_build_1009) Dm_build_1216(dm_build_1218 int, dm_build_1219 float64) int { + return dm_build_1217.Dm_build_1232(dm_build_1218, Dm_build_650.Dm_build_846(dm_build_1219)) +} + +func (dm_build_1221 *Dm_build_1009) Dm_build_1220(dm_build_1222 int, dm_build_1223 uint8) int { + return dm_build_1221.Dm_build_1232(dm_build_1222, Dm_build_650.Dm_build_849(dm_build_1223)) +} + +func (dm_build_1225 *Dm_build_1009) Dm_build_1224(dm_build_1226 int, dm_build_1227 uint16) int { + return dm_build_1225.Dm_build_1232(dm_build_1226, Dm_build_650.Dm_build_852(dm_build_1227)) +} + +func (dm_build_1229 *Dm_build_1009) Dm_build_1228(dm_build_1230 int, dm_build_1231 uint32) int { + return dm_build_1229.Dm_build_1232(dm_build_1230, Dm_build_650.Dm_build_855(dm_build_1231)) +} + +func (dm_build_1233 *Dm_build_1009) Dm_build_1232(dm_build_1234 int, dm_build_1235 []byte) int { + return copy(dm_build_1233.dm_build_1010[dm_build_1234:], dm_build_1235) +} + +func (dm_build_1237 *Dm_build_1009) Dm_build_1236(dm_build_1238 int, dm_build_1239 []byte) int { + return dm_build_1237.Dm_build_1204(dm_build_1238, int32(len(dm_build_1239))) + dm_build_1237.Dm_build_1232(dm_build_1238+4, dm_build_1239) +} + +func (dm_build_1241 *Dm_build_1009) Dm_build_1240(dm_build_1242 int, dm_build_1243 []byte) int { + return dm_build_1241.Dm_build_1196(dm_build_1242, byte(len(dm_build_1243))) + dm_build_1241.Dm_build_1232(dm_build_1242+1, dm_build_1243) +} + +func (dm_build_1245 *Dm_build_1009) Dm_build_1244(dm_build_1246 int, dm_build_1247 []byte) int { + return dm_build_1245.Dm_build_1200(dm_build_1246, int16(len(dm_build_1247))) + dm_build_1245.Dm_build_1232(dm_build_1246+2, dm_build_1247) +} + +func (dm_build_1249 *Dm_build_1009) Dm_build_1248(dm_build_1250 int, dm_build_1251 []byte) int { + return dm_build_1249.Dm_build_1232(dm_build_1250, dm_build_1251) + dm_build_1249.Dm_build_1196(dm_build_1250+len(dm_build_1251), 0) +} + +func (dm_build_1253 *Dm_build_1009) Dm_build_1252(dm_build_1254 int, dm_build_1255 string, dm_build_1256 string, dm_build_1257 *DmConnection) int { + return dm_build_1253.Dm_build_1236(dm_build_1254, Dm_build_650.Dm_build_866(dm_build_1255, dm_build_1256, dm_build_1257)) +} + +func (dm_build_1259 *Dm_build_1009) Dm_build_1258(dm_build_1260 int, dm_build_1261 string, dm_build_1262 string, dm_build_1263 *DmConnection) int { + return dm_build_1259.Dm_build_1240(dm_build_1260, Dm_build_650.Dm_build_866(dm_build_1261, dm_build_1262, dm_build_1263)) +} + +func (dm_build_1265 *Dm_build_1009) Dm_build_1264(dm_build_1266 int, dm_build_1267 string, dm_build_1268 string, dm_build_1269 *DmConnection) int { + return dm_build_1265.Dm_build_1244(dm_build_1266, Dm_build_650.Dm_build_866(dm_build_1267, dm_build_1268, dm_build_1269)) +} + +func (dm_build_1271 *Dm_build_1009) Dm_build_1270(dm_build_1272 int, dm_build_1273 string, dm_build_1274 string, dm_build_1275 *DmConnection) int { + return dm_build_1271.Dm_build_1248(dm_build_1272, Dm_build_650.Dm_build_866(dm_build_1273, dm_build_1274, dm_build_1275)) +} + +func (dm_build_1277 *Dm_build_1009) Dm_build_1276(dm_build_1278 int) byte { + return Dm_build_650.Dm_build_871(dm_build_1277.Dm_build_1303(dm_build_1278, 1)) +} + +func (dm_build_1280 *Dm_build_1009) Dm_build_1279(dm_build_1281 int) int16 { + return Dm_build_650.Dm_build_874(dm_build_1280.Dm_build_1303(dm_build_1281, 2)) +} + +func (dm_build_1283 *Dm_build_1009) Dm_build_1282(dm_build_1284 int) int32 { + return Dm_build_650.Dm_build_877(dm_build_1283.Dm_build_1303(dm_build_1284, 4)) +} + +func (dm_build_1286 *Dm_build_1009) Dm_build_1285(dm_build_1287 int) int64 { + return Dm_build_650.Dm_build_880(dm_build_1286.Dm_build_1303(dm_build_1287, 8)) +} + +func (dm_build_1289 *Dm_build_1009) Dm_build_1288(dm_build_1290 int) float32 { + return Dm_build_650.Dm_build_883(dm_build_1289.Dm_build_1303(dm_build_1290, 4)) +} + +func (dm_build_1292 *Dm_build_1009) Dm_build_1291(dm_build_1293 int) float64 { + return Dm_build_650.Dm_build_886(dm_build_1292.Dm_build_1303(dm_build_1293, 8)) +} + +func (dm_build_1295 *Dm_build_1009) Dm_build_1294(dm_build_1296 int) uint8 { + return Dm_build_650.Dm_build_889(dm_build_1295.Dm_build_1303(dm_build_1296, 1)) +} + +func (dm_build_1298 *Dm_build_1009) Dm_build_1297(dm_build_1299 int) uint16 { + return Dm_build_650.Dm_build_892(dm_build_1298.Dm_build_1303(dm_build_1299, 2)) +} + +func (dm_build_1301 *Dm_build_1009) Dm_build_1300(dm_build_1302 int) uint32 { + return Dm_build_650.Dm_build_895(dm_build_1301.Dm_build_1303(dm_build_1302, 4)) +} + +func (dm_build_1304 *Dm_build_1009) Dm_build_1303(dm_build_1305 int, dm_build_1306 int) []byte { + return dm_build_1304.dm_build_1010[dm_build_1305 : dm_build_1305+dm_build_1306] +} + +func (dm_build_1308 *Dm_build_1009) Dm_build_1307(dm_build_1309 int) []byte { + dm_build_1310 := dm_build_1308.Dm_build_1282(dm_build_1309) + return dm_build_1308.Dm_build_1303(dm_build_1309+4, int(dm_build_1310)) +} + +func (dm_build_1312 *Dm_build_1009) Dm_build_1311(dm_build_1313 int) []byte { + dm_build_1314 := dm_build_1312.Dm_build_1276(dm_build_1313) + return dm_build_1312.Dm_build_1303(dm_build_1313+1, int(dm_build_1314)) +} + +func (dm_build_1316 *Dm_build_1009) Dm_build_1315(dm_build_1317 int) []byte { + dm_build_1318 := dm_build_1316.Dm_build_1279(dm_build_1317) + return dm_build_1316.Dm_build_1303(dm_build_1317+2, int(dm_build_1318)) +} + +func (dm_build_1320 *Dm_build_1009) Dm_build_1319(dm_build_1321 int) []byte { + dm_build_1322 := 0 + for dm_build_1320.Dm_build_1276(dm_build_1321) != 0 { + dm_build_1321++ + dm_build_1322++ + } + + return dm_build_1320.Dm_build_1303(dm_build_1321-dm_build_1322, int(dm_build_1322)) +} + +func (dm_build_1324 *Dm_build_1009) Dm_build_1323(dm_build_1325 int, dm_build_1326 string, dm_build_1327 *DmConnection) string { + return Dm_build_650.Dm_build_902(dm_build_1324.Dm_build_1307(dm_build_1325), dm_build_1326, dm_build_1327) +} + +func (dm_build_1329 *Dm_build_1009) Dm_build_1328(dm_build_1330 int, dm_build_1331 string, dm_build_1332 *DmConnection) string { + return Dm_build_650.Dm_build_902(dm_build_1329.Dm_build_1311(dm_build_1330), dm_build_1331, dm_build_1332) +} + +func (dm_build_1334 *Dm_build_1009) Dm_build_1333(dm_build_1335 int, dm_build_1336 string, dm_build_1337 *DmConnection) string { + return Dm_build_650.Dm_build_902(dm_build_1334.Dm_build_1315(dm_build_1335), dm_build_1336, dm_build_1337) +} + +func (dm_build_1339 *Dm_build_1009) Dm_build_1338(dm_build_1340 int, dm_build_1341 string, dm_build_1342 *DmConnection) string { + return Dm_build_650.Dm_build_902(dm_build_1339.Dm_build_1319(dm_build_1340), dm_build_1341, dm_build_1342) +} diff --git a/vendor/gitee.com/chunanyong/dm/d.go b/vendor/gitee.com/chunanyong/dm/d.go new file mode 100644 index 0000000000..7f1f967775 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/d.go @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "container/list" + "io" +) + +type Dm_build_931 struct { + dm_build_932 *list.List + dm_build_933 *dm_build_985 + dm_build_934 int +} + +func Dm_build_935() *Dm_build_931 { + return &Dm_build_931{ + dm_build_932: list.New(), + dm_build_934: 0, + } +} + +func (dm_build_937 *Dm_build_931) Dm_build_936() int { + return dm_build_937.dm_build_934 +} + +func (dm_build_939 *Dm_build_931) Dm_build_938(dm_build_940 *Dm_build_1009, dm_build_941 int) int { + var dm_build_942 = 0 + var dm_build_943 = 0 + for dm_build_942 < dm_build_941 && dm_build_939.dm_build_933 != nil { + dm_build_943 = dm_build_939.dm_build_933.dm_build_993(dm_build_940, dm_build_941-dm_build_942) + if dm_build_939.dm_build_933.dm_build_988 == 0 { + dm_build_939.dm_build_975() + } + dm_build_942 += dm_build_943 + dm_build_939.dm_build_934 -= dm_build_943 + } + return dm_build_942 +} + +func (dm_build_945 *Dm_build_931) Dm_build_944(dm_build_946 []byte, dm_build_947 int, dm_build_948 int) int { + var dm_build_949 = 0 + var dm_build_950 = 0 + for dm_build_949 < dm_build_948 && dm_build_945.dm_build_933 != nil { + dm_build_950 = dm_build_945.dm_build_933.dm_build_997(dm_build_946, dm_build_947, dm_build_948-dm_build_949) + if dm_build_945.dm_build_933.dm_build_988 == 0 { + dm_build_945.dm_build_975() + } + dm_build_949 += dm_build_950 + dm_build_945.dm_build_934 -= dm_build_950 + dm_build_947 += dm_build_950 + } + return dm_build_949 +} + +func (dm_build_952 *Dm_build_931) Dm_build_951(dm_build_953 io.Writer, dm_build_954 int) int { + var dm_build_955 = 0 + var dm_build_956 = 0 + for dm_build_955 < dm_build_954 && dm_build_952.dm_build_933 != nil { + dm_build_956 = dm_build_952.dm_build_933.dm_build_1002(dm_build_953, dm_build_954-dm_build_955) + if dm_build_952.dm_build_933.dm_build_988 == 0 { + dm_build_952.dm_build_975() + } + dm_build_955 += dm_build_956 + dm_build_952.dm_build_934 -= dm_build_956 + } + return dm_build_955 +} + +func (dm_build_958 *Dm_build_931) Dm_build_957(dm_build_959 []byte, dm_build_960 int, dm_build_961 int) { + if dm_build_961 == 0 { + return + } + var dm_build_962 = dm_build_989(dm_build_959, dm_build_960, dm_build_961) + if dm_build_958.dm_build_933 == nil { + dm_build_958.dm_build_933 = dm_build_962 + } else { + dm_build_958.dm_build_932.PushBack(dm_build_962) + } + dm_build_958.dm_build_934 += dm_build_961 +} + +func (dm_build_964 *Dm_build_931) dm_build_963(dm_build_965 int) byte { + var dm_build_966 = dm_build_965 + var dm_build_967 = dm_build_964.dm_build_933 + for dm_build_966 > 0 && dm_build_967 != nil { + if dm_build_967.dm_build_988 == 0 { + continue + } + if dm_build_966 > dm_build_967.dm_build_988-1 { + dm_build_966 -= dm_build_967.dm_build_988 + dm_build_967 = dm_build_964.dm_build_932.Front().Value.(*dm_build_985) + } else { + break + } + } + return dm_build_967.dm_build_1006(dm_build_966) +} +func (dm_build_969 *Dm_build_931) Dm_build_968(dm_build_970 *Dm_build_931) { + if dm_build_970.dm_build_934 == 0 { + return + } + var dm_build_971 = dm_build_970.dm_build_933 + for dm_build_971 != nil { + dm_build_969.dm_build_972(dm_build_971) + dm_build_970.dm_build_975() + dm_build_971 = dm_build_970.dm_build_933 + } + dm_build_970.dm_build_934 = 0 +} +func (dm_build_973 *Dm_build_931) dm_build_972(dm_build_974 *dm_build_985) { + if dm_build_974.dm_build_988 == 0 { + return + } + if dm_build_973.dm_build_933 == nil { + dm_build_973.dm_build_933 = dm_build_974 + } else { + dm_build_973.dm_build_932.PushBack(dm_build_974) + } + dm_build_973.dm_build_934 += dm_build_974.dm_build_988 +} + +func (dm_build_976 *Dm_build_931) dm_build_975() { + var dm_build_977 = dm_build_976.dm_build_932.Front() + if dm_build_977 == nil { + dm_build_976.dm_build_933 = nil + } else { + dm_build_976.dm_build_933 = dm_build_977.Value.(*dm_build_985) + dm_build_976.dm_build_932.Remove(dm_build_977) + } +} + +func (dm_build_979 *Dm_build_931) Dm_build_978() []byte { + var dm_build_980 = make([]byte, dm_build_979.dm_build_934) + var dm_build_981 = dm_build_979.dm_build_933 + var dm_build_982 = 0 + var dm_build_983 = len(dm_build_980) + var dm_build_984 = 0 + for dm_build_981 != nil { + if dm_build_981.dm_build_988 > 0 { + if dm_build_983 > dm_build_981.dm_build_988 { + dm_build_984 = dm_build_981.dm_build_988 + } else { + dm_build_984 = dm_build_983 + } + copy(dm_build_980[dm_build_982:dm_build_982+dm_build_984], dm_build_981.dm_build_986[dm_build_981.dm_build_987:dm_build_981.dm_build_987+dm_build_984]) + dm_build_982 += dm_build_984 + dm_build_983 -= dm_build_984 + } + if dm_build_979.dm_build_932.Front() == nil { + dm_build_981 = nil + } else { + dm_build_981 = dm_build_979.dm_build_932.Front().Value.(*dm_build_985) + } + } + return dm_build_980 +} + +type dm_build_985 struct { + dm_build_986 []byte + dm_build_987 int + dm_build_988 int +} + +func dm_build_989(dm_build_990 []byte, dm_build_991 int, dm_build_992 int) *dm_build_985 { + return &dm_build_985{ + dm_build_990, + dm_build_991, + dm_build_992, + } +} + +func (dm_build_994 *dm_build_985) dm_build_993(dm_build_995 *Dm_build_1009, dm_build_996 int) int { + if dm_build_994.dm_build_988 <= dm_build_996 { + dm_build_996 = dm_build_994.dm_build_988 + } + dm_build_995.Dm_build_1092(dm_build_994.dm_build_986[dm_build_994.dm_build_987 : dm_build_994.dm_build_987+dm_build_996]) + dm_build_994.dm_build_987 += dm_build_996 + dm_build_994.dm_build_988 -= dm_build_996 + return dm_build_996 +} + +func (dm_build_998 *dm_build_985) dm_build_997(dm_build_999 []byte, dm_build_1000 int, dm_build_1001 int) int { + if dm_build_998.dm_build_988 <= dm_build_1001 { + dm_build_1001 = dm_build_998.dm_build_988 + } + copy(dm_build_999[dm_build_1000:dm_build_1000+dm_build_1001], dm_build_998.dm_build_986[dm_build_998.dm_build_987:dm_build_998.dm_build_987+dm_build_1001]) + dm_build_998.dm_build_987 += dm_build_1001 + dm_build_998.dm_build_988 -= dm_build_1001 + return dm_build_1001 +} + +func (dm_build_1003 *dm_build_985) dm_build_1002(dm_build_1004 io.Writer, dm_build_1005 int) int { + if dm_build_1003.dm_build_988 <= dm_build_1005 { + dm_build_1005 = dm_build_1003.dm_build_988 + } + dm_build_1004.Write(dm_build_1003.dm_build_986[dm_build_1003.dm_build_987 : dm_build_1003.dm_build_987+dm_build_1005]) + dm_build_1003.dm_build_987 += dm_build_1005 + dm_build_1003.dm_build_988 -= dm_build_1005 + return dm_build_1005 +} +func (dm_build_1007 *dm_build_985) dm_build_1006(dm_build_1008 int) byte { + return dm_build_1007.dm_build_986[dm_build_1007.dm_build_987+dm_build_1008] +} diff --git a/vendor/gitee.com/chunanyong/dm/e.go b/vendor/gitee.com/chunanyong/dm/e.go new file mode 100644 index 0000000000..3861183c30 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/e.go @@ -0,0 +1,522 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +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_649 struct{} + +var Dm_build_650 = &dm_build_649{} + +func (Dm_build_652 *dm_build_649) Dm_build_651(dm_build_653 []byte, dm_build_654 int, dm_build_655 byte) int { + dm_build_653[dm_build_654] = dm_build_655 + return 1 +} + +func (Dm_build_657 *dm_build_649) Dm_build_656(dm_build_658 []byte, dm_build_659 int, dm_build_660 int8) int { + dm_build_658[dm_build_659] = byte(dm_build_660) + return 1 +} + +func (Dm_build_662 *dm_build_649) Dm_build_661(dm_build_663 []byte, dm_build_664 int, dm_build_665 int16) int { + dm_build_663[dm_build_664] = byte(dm_build_665) + dm_build_664++ + dm_build_663[dm_build_664] = byte(dm_build_665 >> 8) + return 2 +} + +func (Dm_build_667 *dm_build_649) Dm_build_666(dm_build_668 []byte, dm_build_669 int, dm_build_670 int32) int { + dm_build_668[dm_build_669] = byte(dm_build_670) + dm_build_669++ + dm_build_668[dm_build_669] = byte(dm_build_670 >> 8) + dm_build_669++ + dm_build_668[dm_build_669] = byte(dm_build_670 >> 16) + dm_build_669++ + dm_build_668[dm_build_669] = byte(dm_build_670 >> 24) + dm_build_669++ + return 4 +} + +func (Dm_build_672 *dm_build_649) Dm_build_671(dm_build_673 []byte, dm_build_674 int, dm_build_675 int64) int { + dm_build_673[dm_build_674] = byte(dm_build_675) + dm_build_674++ + dm_build_673[dm_build_674] = byte(dm_build_675 >> 8) + dm_build_674++ + dm_build_673[dm_build_674] = byte(dm_build_675 >> 16) + dm_build_674++ + dm_build_673[dm_build_674] = byte(dm_build_675 >> 24) + dm_build_674++ + dm_build_673[dm_build_674] = byte(dm_build_675 >> 32) + dm_build_674++ + dm_build_673[dm_build_674] = byte(dm_build_675 >> 40) + dm_build_674++ + dm_build_673[dm_build_674] = byte(dm_build_675 >> 48) + dm_build_674++ + dm_build_673[dm_build_674] = byte(dm_build_675 >> 56) + return 8 +} + +func (Dm_build_677 *dm_build_649) Dm_build_676(dm_build_678 []byte, dm_build_679 int, dm_build_680 float32) int { + return Dm_build_677.Dm_build_696(dm_build_678, dm_build_679, math.Float32bits(dm_build_680)) +} + +func (Dm_build_682 *dm_build_649) Dm_build_681(dm_build_683 []byte, dm_build_684 int, dm_build_685 float64) int { + return Dm_build_682.Dm_build_701(dm_build_683, dm_build_684, math.Float64bits(dm_build_685)) +} + +func (Dm_build_687 *dm_build_649) Dm_build_686(dm_build_688 []byte, dm_build_689 int, dm_build_690 uint8) int { + dm_build_688[dm_build_689] = byte(dm_build_690) + return 1 +} + +func (Dm_build_692 *dm_build_649) Dm_build_691(dm_build_693 []byte, dm_build_694 int, dm_build_695 uint16) int { + dm_build_693[dm_build_694] = byte(dm_build_695) + dm_build_694++ + dm_build_693[dm_build_694] = byte(dm_build_695 >> 8) + return 2 +} + +func (Dm_build_697 *dm_build_649) Dm_build_696(dm_build_698 []byte, dm_build_699 int, dm_build_700 uint32) int { + dm_build_698[dm_build_699] = byte(dm_build_700) + dm_build_699++ + dm_build_698[dm_build_699] = byte(dm_build_700 >> 8) + dm_build_699++ + dm_build_698[dm_build_699] = byte(dm_build_700 >> 16) + dm_build_699++ + dm_build_698[dm_build_699] = byte(dm_build_700 >> 24) + return 3 +} + +func (Dm_build_702 *dm_build_649) Dm_build_701(dm_build_703 []byte, dm_build_704 int, dm_build_705 uint64) int { + dm_build_703[dm_build_704] = byte(dm_build_705) + dm_build_704++ + dm_build_703[dm_build_704] = byte(dm_build_705 >> 8) + dm_build_704++ + dm_build_703[dm_build_704] = byte(dm_build_705 >> 16) + dm_build_704++ + dm_build_703[dm_build_704] = byte(dm_build_705 >> 24) + dm_build_704++ + dm_build_703[dm_build_704] = byte(dm_build_705 >> 32) + dm_build_704++ + dm_build_703[dm_build_704] = byte(dm_build_705 >> 40) + dm_build_704++ + dm_build_703[dm_build_704] = byte(dm_build_705 >> 48) + dm_build_704++ + dm_build_703[dm_build_704] = byte(dm_build_705 >> 56) + return 3 +} + +func (Dm_build_707 *dm_build_649) Dm_build_706(dm_build_708 []byte, dm_build_709 int, dm_build_710 []byte, dm_build_711 int, dm_build_712 int) int { + copy(dm_build_708[dm_build_709:dm_build_709+dm_build_712], dm_build_710[dm_build_711:dm_build_711+dm_build_712]) + return dm_build_712 +} + +func (Dm_build_714 *dm_build_649) Dm_build_713(dm_build_715 []byte, dm_build_716 int, dm_build_717 []byte, dm_build_718 int, dm_build_719 int) int { + dm_build_716 += Dm_build_714.Dm_build_696(dm_build_715, dm_build_716, uint32(dm_build_719)) + return 4 + Dm_build_714.Dm_build_706(dm_build_715, dm_build_716, dm_build_717, dm_build_718, dm_build_719) +} + +func (Dm_build_721 *dm_build_649) Dm_build_720(dm_build_722 []byte, dm_build_723 int, dm_build_724 []byte, dm_build_725 int, dm_build_726 int) int { + dm_build_723 += Dm_build_721.Dm_build_691(dm_build_722, dm_build_723, uint16(dm_build_726)) + return 2 + Dm_build_721.Dm_build_706(dm_build_722, dm_build_723, dm_build_724, dm_build_725, dm_build_726) +} + +func (Dm_build_728 *dm_build_649) Dm_build_727(dm_build_729 []byte, dm_build_730 int, dm_build_731 string, dm_build_732 string, dm_build_733 *DmConnection) int { + dm_build_734 := Dm_build_728.Dm_build_866(dm_build_731, dm_build_732, dm_build_733) + dm_build_730 += Dm_build_728.Dm_build_696(dm_build_729, dm_build_730, uint32(len(dm_build_734))) + return 4 + Dm_build_728.Dm_build_706(dm_build_729, dm_build_730, dm_build_734, 0, len(dm_build_734)) +} + +func (Dm_build_736 *dm_build_649) Dm_build_735(dm_build_737 []byte, dm_build_738 int, dm_build_739 string, dm_build_740 string, dm_build_741 *DmConnection) int { + dm_build_742 := Dm_build_736.Dm_build_866(dm_build_739, dm_build_740, dm_build_741) + + dm_build_738 += Dm_build_736.Dm_build_691(dm_build_737, dm_build_738, uint16(len(dm_build_742))) + return 2 + Dm_build_736.Dm_build_706(dm_build_737, dm_build_738, dm_build_742, 0, len(dm_build_742)) +} + +func (Dm_build_744 *dm_build_649) Dm_build_743(dm_build_745 []byte, dm_build_746 int) byte { + return dm_build_745[dm_build_746] +} + +func (Dm_build_748 *dm_build_649) Dm_build_747(dm_build_749 []byte, dm_build_750 int) int16 { + var dm_build_751 int16 + dm_build_751 = int16(dm_build_749[dm_build_750] & 0xff) + dm_build_750++ + dm_build_751 |= int16(dm_build_749[dm_build_750]&0xff) << 8 + return dm_build_751 +} + +func (Dm_build_753 *dm_build_649) Dm_build_752(dm_build_754 []byte, dm_build_755 int) int32 { + var dm_build_756 int32 + dm_build_756 = int32(dm_build_754[dm_build_755] & 0xff) + dm_build_755++ + dm_build_756 |= int32(dm_build_754[dm_build_755]&0xff) << 8 + dm_build_755++ + dm_build_756 |= int32(dm_build_754[dm_build_755]&0xff) << 16 + dm_build_755++ + dm_build_756 |= int32(dm_build_754[dm_build_755]&0xff) << 24 + return dm_build_756 +} + +func (Dm_build_758 *dm_build_649) Dm_build_757(dm_build_759 []byte, dm_build_760 int) int64 { + var dm_build_761 int64 + dm_build_761 = int64(dm_build_759[dm_build_760] & 0xff) + dm_build_760++ + dm_build_761 |= int64(dm_build_759[dm_build_760]&0xff) << 8 + dm_build_760++ + dm_build_761 |= int64(dm_build_759[dm_build_760]&0xff) << 16 + dm_build_760++ + dm_build_761 |= int64(dm_build_759[dm_build_760]&0xff) << 24 + dm_build_760++ + dm_build_761 |= int64(dm_build_759[dm_build_760]&0xff) << 32 + dm_build_760++ + dm_build_761 |= int64(dm_build_759[dm_build_760]&0xff) << 40 + dm_build_760++ + dm_build_761 |= int64(dm_build_759[dm_build_760]&0xff) << 48 + dm_build_760++ + dm_build_761 |= int64(dm_build_759[dm_build_760]&0xff) << 56 + return dm_build_761 +} + +func (Dm_build_763 *dm_build_649) Dm_build_762(dm_build_764 []byte, dm_build_765 int) float32 { + return math.Float32frombits(Dm_build_763.Dm_build_779(dm_build_764, dm_build_765)) +} + +func (Dm_build_767 *dm_build_649) Dm_build_766(dm_build_768 []byte, dm_build_769 int) float64 { + return math.Float64frombits(Dm_build_767.Dm_build_784(dm_build_768, dm_build_769)) +} + +func (Dm_build_771 *dm_build_649) Dm_build_770(dm_build_772 []byte, dm_build_773 int) uint8 { + return uint8(dm_build_772[dm_build_773] & 0xff) +} + +func (Dm_build_775 *dm_build_649) Dm_build_774(dm_build_776 []byte, dm_build_777 int) uint16 { + var dm_build_778 uint16 + dm_build_778 = uint16(dm_build_776[dm_build_777] & 0xff) + dm_build_777++ + dm_build_778 |= uint16(dm_build_776[dm_build_777]&0xff) << 8 + return dm_build_778 +} + +func (Dm_build_780 *dm_build_649) Dm_build_779(dm_build_781 []byte, dm_build_782 int) uint32 { + var dm_build_783 uint32 + dm_build_783 = uint32(dm_build_781[dm_build_782] & 0xff) + dm_build_782++ + dm_build_783 |= uint32(dm_build_781[dm_build_782]&0xff) << 8 + dm_build_782++ + dm_build_783 |= uint32(dm_build_781[dm_build_782]&0xff) << 16 + dm_build_782++ + dm_build_783 |= uint32(dm_build_781[dm_build_782]&0xff) << 24 + return dm_build_783 +} + +func (Dm_build_785 *dm_build_649) Dm_build_784(dm_build_786 []byte, dm_build_787 int) uint64 { + var dm_build_788 uint64 + dm_build_788 = uint64(dm_build_786[dm_build_787] & 0xff) + dm_build_787++ + dm_build_788 |= uint64(dm_build_786[dm_build_787]&0xff) << 8 + dm_build_787++ + dm_build_788 |= uint64(dm_build_786[dm_build_787]&0xff) << 16 + dm_build_787++ + dm_build_788 |= uint64(dm_build_786[dm_build_787]&0xff) << 24 + dm_build_787++ + dm_build_788 |= uint64(dm_build_786[dm_build_787]&0xff) << 32 + dm_build_787++ + dm_build_788 |= uint64(dm_build_786[dm_build_787]&0xff) << 40 + dm_build_787++ + dm_build_788 |= uint64(dm_build_786[dm_build_787]&0xff) << 48 + dm_build_787++ + dm_build_788 |= uint64(dm_build_786[dm_build_787]&0xff) << 56 + return dm_build_788 +} + +func (Dm_build_790 *dm_build_649) Dm_build_789(dm_build_791 []byte, dm_build_792 int) []byte { + dm_build_793 := Dm_build_790.Dm_build_779(dm_build_791, dm_build_792) + + dm_build_794 := make([]byte, dm_build_793) + copy(dm_build_794[:int(dm_build_793)], dm_build_791[dm_build_792+4:dm_build_792+4+int(dm_build_793)]) + return dm_build_794 +} + +func (Dm_build_796 *dm_build_649) Dm_build_795(dm_build_797 []byte, dm_build_798 int) []byte { + dm_build_799 := Dm_build_796.Dm_build_774(dm_build_797, dm_build_798) + + dm_build_800 := make([]byte, dm_build_799) + copy(dm_build_800[:int(dm_build_799)], dm_build_797[dm_build_798+2:dm_build_798+2+int(dm_build_799)]) + return dm_build_800 +} + +func (Dm_build_802 *dm_build_649) Dm_build_801(dm_build_803 []byte, dm_build_804 int, dm_build_805 int) []byte { + + dm_build_806 := make([]byte, dm_build_805) + copy(dm_build_806[:dm_build_805], dm_build_803[dm_build_804:dm_build_804+dm_build_805]) + return dm_build_806 +} + +func (Dm_build_808 *dm_build_649) Dm_build_807(dm_build_809 []byte, dm_build_810 int, dm_build_811 int, dm_build_812 string, dm_build_813 *DmConnection) string { + return Dm_build_808.Dm_build_902(dm_build_809[dm_build_810:dm_build_810+dm_build_811], dm_build_812, dm_build_813) +} + +func (Dm_build_815 *dm_build_649) Dm_build_814(dm_build_816 []byte, dm_build_817 int, dm_build_818 string, dm_build_819 *DmConnection) string { + dm_build_820 := Dm_build_815.Dm_build_779(dm_build_816, dm_build_817) + dm_build_817 += 4 + return Dm_build_815.Dm_build_807(dm_build_816, dm_build_817, int(dm_build_820), dm_build_818, dm_build_819) +} + +func (Dm_build_822 *dm_build_649) Dm_build_821(dm_build_823 []byte, dm_build_824 int, dm_build_825 string, dm_build_826 *DmConnection) string { + dm_build_827 := Dm_build_822.Dm_build_774(dm_build_823, dm_build_824) + dm_build_824 += 2 + return Dm_build_822.Dm_build_807(dm_build_823, dm_build_824, int(dm_build_827), dm_build_825, dm_build_826) +} + +func (Dm_build_829 *dm_build_649) Dm_build_828(dm_build_830 byte) []byte { + return []byte{dm_build_830} +} + +func (Dm_build_832 *dm_build_649) Dm_build_831(dm_build_833 int8) []byte { + return []byte{byte(dm_build_833)} +} + +func (Dm_build_835 *dm_build_649) Dm_build_834(dm_build_836 int16) []byte { + return []byte{byte(dm_build_836), byte(dm_build_836 >> 8)} +} + +func (Dm_build_838 *dm_build_649) Dm_build_837(dm_build_839 int32) []byte { + return []byte{byte(dm_build_839), byte(dm_build_839 >> 8), byte(dm_build_839 >> 16), byte(dm_build_839 >> 24)} +} + +func (Dm_build_841 *dm_build_649) Dm_build_840(dm_build_842 int64) []byte { + return []byte{byte(dm_build_842), byte(dm_build_842 >> 8), byte(dm_build_842 >> 16), byte(dm_build_842 >> 24), byte(dm_build_842 >> 32), + byte(dm_build_842 >> 40), byte(dm_build_842 >> 48), byte(dm_build_842 >> 56)} +} + +func (Dm_build_844 *dm_build_649) Dm_build_843(dm_build_845 float32) []byte { + return Dm_build_844.Dm_build_855(math.Float32bits(dm_build_845)) +} + +func (Dm_build_847 *dm_build_649) Dm_build_846(dm_build_848 float64) []byte { + return Dm_build_847.Dm_build_858(math.Float64bits(dm_build_848)) +} + +func (Dm_build_850 *dm_build_649) Dm_build_849(dm_build_851 uint8) []byte { + return []byte{byte(dm_build_851)} +} + +func (Dm_build_853 *dm_build_649) Dm_build_852(dm_build_854 uint16) []byte { + return []byte{byte(dm_build_854), byte(dm_build_854 >> 8)} +} + +func (Dm_build_856 *dm_build_649) Dm_build_855(dm_build_857 uint32) []byte { + return []byte{byte(dm_build_857), byte(dm_build_857 >> 8), byte(dm_build_857 >> 16), byte(dm_build_857 >> 24)} +} + +func (Dm_build_859 *dm_build_649) Dm_build_858(dm_build_860 uint64) []byte { + return []byte{byte(dm_build_860), byte(dm_build_860 >> 8), byte(dm_build_860 >> 16), byte(dm_build_860 >> 24), byte(dm_build_860 >> 32), byte(dm_build_860 >> 40), byte(dm_build_860 >> 48), byte(dm_build_860 >> 56)} +} + +func (Dm_build_862 *dm_build_649) Dm_build_861(dm_build_863 []byte, dm_build_864 string, dm_build_865 *DmConnection) []byte { + if dm_build_864 == "UTF-8" { + return dm_build_863 + } + + if dm_build_865 == nil { + if e := dm_build_907(dm_build_864); e != nil { + tmp, err := ioutil.ReadAll( + transform.NewReader(bytes.NewReader(dm_build_863), e.NewEncoder()), + ) + if err != nil { + panic("UTF8 To Charset error!") + } + + return tmp + } + + panic("Unsupported Charset!") + } + + if dm_build_865.encodeBuffer == nil { + dm_build_865.encodeBuffer = bytes.NewBuffer(nil) + dm_build_865.encode = dm_build_907(dm_build_865.getServerEncoding()) + dm_build_865.transformReaderDst = make([]byte, 4096) + dm_build_865.transformReaderSrc = make([]byte, 4096) + } + + if e := dm_build_865.encode; e != nil { + + dm_build_865.encodeBuffer.Reset() + + n, err := dm_build_865.encodeBuffer.ReadFrom( + Dm_build_921(bytes.NewReader(dm_build_863), e.NewEncoder(), dm_build_865.transformReaderDst, dm_build_865.transformReaderSrc), + ) + if err != nil { + panic("UTF8 To Charset error!") + } + var tmp = make([]byte, n) + if _, err = dm_build_865.encodeBuffer.Read(tmp); err != nil { + panic("UTF8 To Charset error!") + } + return tmp + } + + panic("Unsupported Charset!") +} + +func (Dm_build_867 *dm_build_649) Dm_build_866(dm_build_868 string, dm_build_869 string, dm_build_870 *DmConnection) []byte { + return Dm_build_867.Dm_build_861([]byte(dm_build_868), dm_build_869, dm_build_870) +} + +func (Dm_build_872 *dm_build_649) Dm_build_871(dm_build_873 []byte) byte { + return Dm_build_872.Dm_build_743(dm_build_873, 0) +} + +func (Dm_build_875 *dm_build_649) Dm_build_874(dm_build_876 []byte) int16 { + return Dm_build_875.Dm_build_747(dm_build_876, 0) +} + +func (Dm_build_878 *dm_build_649) Dm_build_877(dm_build_879 []byte) int32 { + return Dm_build_878.Dm_build_752(dm_build_879, 0) +} + +func (Dm_build_881 *dm_build_649) Dm_build_880(dm_build_882 []byte) int64 { + return Dm_build_881.Dm_build_757(dm_build_882, 0) +} + +func (Dm_build_884 *dm_build_649) Dm_build_883(dm_build_885 []byte) float32 { + return Dm_build_884.Dm_build_762(dm_build_885, 0) +} + +func (Dm_build_887 *dm_build_649) Dm_build_886(dm_build_888 []byte) float64 { + return Dm_build_887.Dm_build_766(dm_build_888, 0) +} + +func (Dm_build_890 *dm_build_649) Dm_build_889(dm_build_891 []byte) uint8 { + return Dm_build_890.Dm_build_770(dm_build_891, 0) +} + +func (Dm_build_893 *dm_build_649) Dm_build_892(dm_build_894 []byte) uint16 { + return Dm_build_893.Dm_build_774(dm_build_894, 0) +} + +func (Dm_build_896 *dm_build_649) Dm_build_895(dm_build_897 []byte) uint32 { + return Dm_build_896.Dm_build_779(dm_build_897, 0) +} + +func (Dm_build_899 *dm_build_649) Dm_build_898(dm_build_900 []byte, dm_build_901 string) []byte { + if dm_build_901 == "UTF-8" { + return dm_build_900 + } + + if e := dm_build_907(dm_build_901); e != nil { + + tmp, err := ioutil.ReadAll( + transform.NewReader(bytes.NewReader(dm_build_900), e.NewDecoder()), + ) + if err != nil { + + panic("Charset To UTF8 error!") + } + + return tmp + } + + panic("Unsupported Charset!") + +} + +func (Dm_build_903 *dm_build_649) Dm_build_902(dm_build_904 []byte, dm_build_905 string, dm_build_906 *DmConnection) string { + return string(Dm_build_903.Dm_build_898(dm_build_904, dm_build_905)) +} + +func dm_build_907(dm_build_908 string) encoding.Encoding { + if e, err := ianaindex.MIB.Encoding(dm_build_908); err == nil && e != nil { + return e + } + return nil +} + +type Dm_build_909 struct { + dm_build_910 io.Reader + dm_build_911 transform.Transformer + dm_build_912 error + + dm_build_913 []byte + dm_build_914, dm_build_915 int + + dm_build_916 []byte + dm_build_917, dm_build_918 int + + dm_build_919 bool +} + +const dm_build_920 = 4096 + +func Dm_build_921(dm_build_922 io.Reader, dm_build_923 transform.Transformer, dm_build_924 []byte, dm_build_925 []byte) *Dm_build_909 { + dm_build_923.Reset() + return &Dm_build_909{ + dm_build_910: dm_build_922, + dm_build_911: dm_build_923, + dm_build_913: dm_build_924, + dm_build_916: dm_build_925, + } +} + +func (dm_build_927 *Dm_build_909) Read(dm_build_928 []byte) (int, error) { + dm_build_929, dm_build_930 := 0, error(nil) + for { + + if dm_build_927.dm_build_914 != dm_build_927.dm_build_915 { + dm_build_929 = copy(dm_build_928, dm_build_927.dm_build_913[dm_build_927.dm_build_914:dm_build_927.dm_build_915]) + dm_build_927.dm_build_914 += dm_build_929 + if dm_build_927.dm_build_914 == dm_build_927.dm_build_915 && dm_build_927.dm_build_919 { + return dm_build_929, dm_build_927.dm_build_912 + } + return dm_build_929, nil + } else if dm_build_927.dm_build_919 { + return 0, dm_build_927.dm_build_912 + } + + if dm_build_927.dm_build_917 != dm_build_927.dm_build_918 || dm_build_927.dm_build_912 != nil { + dm_build_927.dm_build_914 = 0 + dm_build_927.dm_build_915, dm_build_929, dm_build_930 = dm_build_927.dm_build_911.Transform(dm_build_927.dm_build_913, dm_build_927.dm_build_916[dm_build_927.dm_build_917:dm_build_927.dm_build_918], dm_build_927.dm_build_912 == io.EOF) + dm_build_927.dm_build_917 += dm_build_929 + + switch { + case dm_build_930 == nil: + if dm_build_927.dm_build_917 != dm_build_927.dm_build_918 { + dm_build_927.dm_build_912 = nil + } + + dm_build_927.dm_build_919 = dm_build_927.dm_build_912 != nil + continue + case dm_build_930 == transform.ErrShortDst && (dm_build_927.dm_build_915 != 0 || dm_build_929 != 0): + + continue + case dm_build_930 == transform.ErrShortSrc && dm_build_927.dm_build_918-dm_build_927.dm_build_917 != len(dm_build_927.dm_build_916) && dm_build_927.dm_build_912 == nil: + + default: + dm_build_927.dm_build_919 = true + + if dm_build_927.dm_build_912 == nil || dm_build_927.dm_build_912 == io.EOF { + dm_build_927.dm_build_912 = dm_build_930 + } + continue + } + } + + if dm_build_927.dm_build_917 != 0 { + dm_build_927.dm_build_917, dm_build_927.dm_build_918 = 0, copy(dm_build_927.dm_build_916, dm_build_927.dm_build_916[dm_build_927.dm_build_917:dm_build_927.dm_build_918]) + } + dm_build_929, dm_build_927.dm_build_912 = dm_build_927.dm_build_910.Read(dm_build_927.dm_build_916[dm_build_927.dm_build_918:]) + dm_build_927.dm_build_918 += dm_build_929 + } +} diff --git a/vendor/gitee.com/chunanyong/dm/f.go b/vendor/gitee.com/chunanyong/dm/f.go new file mode 100644 index 0000000000..6cb0318291 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/f.go @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "bytes" + "compress/zlib" + "github.com/golang/snappy" +) + +func Compress(srcBuffer *Dm_build_1009, offset int, length int, compressID int) ([]byte, error) { + if compressID == Dm_build_93 { + return snappy.Encode(nil, srcBuffer.Dm_build_1303(offset, length)), nil + } + return GzlibCompress(srcBuffer, offset, length) +} + +func UnCompress(srcBytes []byte, compressID int) ([]byte, error) { + if compressID == Dm_build_93 { + return snappy.Decode(nil, srcBytes) + } + return GzlibUncompress(srcBytes) +} + +func GzlibCompress(srcBuffer *Dm_build_1009, offset int, length int) ([]byte, error) { + var ret bytes.Buffer + var w = zlib.NewWriter(&ret) + w.Write(srcBuffer.Dm_build_1303(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/vendor/gitee.com/chunanyong/dm/g.go b/vendor/gitee.com/chunanyong/dm/g.go new file mode 100644 index 0000000000..a94db26f9a --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/g.go @@ -0,0 +1,2158 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "fmt" + "math" + "os" + "sort" + "strconv" + "strings" + "sync" + "sync/atomic" + "time" + + "gitee.com/chunanyong/dm/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_931 +} + +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_935() + 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_957(bytes, 0, len(bytes)) + + if sf.buffer.Dm_build_936() >= FLUSH_SIZE { + sf.doFlush(sf.buffer) + } + } + + if sf.buffer.Dm_build_936() > 0 { + sf.doFlush(sf.buffer) + } +} + +func (sf *statFlusher) doFlush(buffer *Dm_build_931) { + if sf.needCreateNewFile() { + sf.closeCurrentFile() + sf.logFile = sf.createNewFile() + } + if sf.logFile != nil { + buffer.Dm_build_951(sf.logFile, buffer.Dm_build_936()) + } +} +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 { + fmt.Println(err) + return nil + } + 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/vendor/gitee.com/chunanyong/dm/h.go b/vendor/gitee.com/chunanyong/dm/h.go new file mode 100644 index 0000000000..6976be71e2 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/h.go @@ -0,0 +1,923 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "math" + "strconv" + "strings" + "time" + "unicode" +) + +func encodeByString(x string, column column, conn DmConnection) ([]byte, error) { + dt := make([]int, DT_LEN) + if _, err := toDTFromString(x, dt); err != nil { + return nil, err + } + return encode(dt, column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone)) +} + +func encodeByTime(x time.Time, column column, conn DmConnection) ([]byte, error) { + dt := toDTFromTime(x) + return encode(dt, column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone)) +} + +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_NANOSECOND] + 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, column column, ltz int, dtz int) []int { + var dt []int + if isBdta { + dt = dmdtDecodeBdta(value) + } else { + dt = dmdtDecodeFast(value) + } + + if column.mask == MASK_LOCAL_DATETIME { + transformTZ(dt, dtz, ltz) + } + + return dt +} + +func dmdtDecodeFast(value []byte) []int { + dt := make([]int, DT_LEN) + dt[OFFSET_TIMEZONE] = INVALID_VALUE + + dtype := 0 + if len(value) == DATE_PREC { + dtype = DATE + } else if len(value) == TIME_PREC { + dtype = TIME + } else if len(value) == TIME_TZ_PREC { + dtype = TIME_TZ + } else if len(value) == DATETIME_PREC { + dtype = DATETIME + } else if len(value) == DATETIME2_PREC { + dtype = DATETIME2 + } else if len(value) == DATETIME_TZ_PREC { + dtype = DATETIME_TZ + } else if len(value) == DATETIME2_TZ_PREC { + dtype = DATETIME2_TZ + } + + if dtype == DATE { + + dt[OFFSET_YEAR] = int(Dm_build_650.Dm_build_747(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 dtype == TIME { + 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_NANOSECOND] = ((int(value[2]) >> 1) & 0x7f) + ((int(value[3]) & 0x00ff) << 7) + ((int(value[4]) & 0x1F) << 15) + dt[OFFSET_NANOSECOND] *= 1000 + } else if dtype == TIME_TZ { + 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_NANOSECOND] = ((int(value[2]) >> 1) & 0x7f) + ((int(value[3]) & 0x00ff) << 7) + ((int(value[4]) & 0x1F) << 15) + dt[OFFSET_NANOSECOND] *= 1000 + dt[OFFSET_TIMEZONE] = int(Dm_build_650.Dm_build_747(value, 5)) + } else if dtype == DATETIME { + + dt[OFFSET_YEAR] = int(Dm_build_650.Dm_build_747(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_NANOSECOND] = ((int(value[5]) >> 1) & 0x7f) + ((int(value[6]) & 0x00ff) << 7) + ((int(value[7]) & 0x1F) << 15) + dt[OFFSET_NANOSECOND] *= 1000 + } else if dtype == DATETIME_TZ { + + dt[OFFSET_YEAR] = int(Dm_build_650.Dm_build_747(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_NANOSECOND] = ((int(value[5]) >> 1) & 0x7f) + ((int(value[6]) & 0x00ff) << 7) + ((int(value[7]) & 0x1F) << 15) + dt[OFFSET_NANOSECOND] *= 1000 + + dt[OFFSET_TIMEZONE] = int(Dm_build_650.Dm_build_747(value, len(value)-2)) + } else if dtype == DATETIME2 { + + dt[OFFSET_YEAR] = int(Dm_build_650.Dm_build_747(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_NANOSECOND] = ((int(value[5]) >> 1) & 0x7f) + ((int(value[6]) & 0x00ff) << 7) + ((int(value[7]) & 0x00ff) << 15) + ((int(value[8]) & 0x7F) << 23) + } else if dtype == DATETIME2_TZ { + + dt[OFFSET_YEAR] = int(Dm_build_650.Dm_build_747(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_NANOSECOND] = ((int(value[5]) >> 1) & 0x7f) + ((int(value[6]) & 0x00ff) << 7) + ((int(value[7]) & 0x00ff) << 15) + ((int(value[8]) & 0x7F) << 23) + + dt[OFFSET_TIMEZONE] = int(Dm_build_650.Dm_build_747(value, len(value)-2)) + } + return dt +} + +func dmdtDecodeBdta(value []byte) []int { + dt := make([]int, DT_LEN) + dt[OFFSET_YEAR] = int(Dm_build_650.Dm_build_747(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_NANOSECOND] = int((value[7] & 0xFF) + (value[8] << 8) + (value[9] << 16)) + dt[OFFSET_TIMEZONE] = int(Dm_build_650.Dm_build_747(value, 10)) + + if len(value) > 12 { + + dt[OFFSET_NANOSECOND] += int(value[12] << 24) + } + return dt +} + +func dtToStringByOracleFormat(dt []int, oracleFormatPattern string, scale int32, language int) string { + return format(dt, oracleFormatPattern, scale, 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_NANOSECOND], 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_NANOSECOND], 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, DATETIME2: + 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_NANOSECOND], 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, DATETIME2_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_NANOSECOND], 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 = "00000000" + strconv.FormatInt(int64(ms), 10) + } else if ms < 100 { + ret = "0000000" + strconv.FormatInt(int64(ms), 10) + } else if ms < 1000 { + ret = "000000" + strconv.FormatInt(int64(ms), 10) + } else if ms < 10000 { + ret = "00000" + strconv.FormatInt(int64(ms), 10) + } else if ms < 100000 { + ret = "0000" + strconv.FormatInt(int64(ms), 10) + } else if ms < 1000000 { + ret = "000" + strconv.FormatInt(int64(ms), 10) + } else if ms < 10000000 { + ret = "00" + strconv.FormatInt(int64(ms), 10) + } else if ms < 100000000 { + ret = "0" + strconv.FormatInt(int64(ms), 10) + } else { + ret = strconv.FormatInt(int64(ms), 10) + } + + if prec < NANOSECOND_DIGITS { + 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_NANOSECOND] = (int)(x.Nanosecond()) + _, 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) > NANOSECOND_DIGITS { + 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:NANOSECOND_DIGITS-len(nanos_s)] + + i, err = strconv.ParseInt(nanos_s, 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_NANOSECOND] = a_nanos + dt[OFFSET_TIMEZONE] = int(ownTz) + return dtype, nil +} + +func transformTZ(dt []int, defaultSrcTz int, destTz int) { + srcTz := defaultSrcTz + + if srcTz != INVALID_VALUE && destTz != INVALID_VALUE && destTz != srcTz { + dt = addMinute(dt, destTz-srcTz) + + dt[OFFSET_TIMEZONE] = destTz + + } +} + +func encode(dt []int, column column, lTz int, dTz int) ([]byte, error) { + if dt[OFFSET_TIMEZONE] != INVALID_VALUE { + transformTZ(dt, dt[OFFSET_TIMEZONE], lTz) + } + + if column.mask == MASK_LOCAL_DATETIME { + transformTZ(dt, dt[OFFSET_TIMEZONE], dTz) + } + + 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_NANOSECOND] + + var tz int + + if dt[OFFSET_TIMEZONE] == INVALID_VALUE { + tz = dTz + } else { + tz = dt[OFFSET_TIMEZONE] + } + + var ret []byte + + if column.colType == 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 column.colType == DATETIME { + msec /= 1000 + 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 column.colType == DATETIME2 { + ret = make([]byte, 9) + + 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) + + ret[8] = (byte)((msec >> 23) & 0xFF) + } else if column.colType == DATETIME_TZ { + msec /= 1000 + 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_650.Dm_build_661(ret, 8, int16(tz)) + } else if column.colType == DATETIME2_TZ { + ret = make([]byte, 11) + + 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) + + ret[8] = (byte)((msec >> 23) & 0xFF) + + Dm_build_650.Dm_build_661(ret, 8, int16(tz)) + } else if column.colType == TIME { + msec /= 1000 + 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 column.colType == TIME_TZ { + msec /= 1000 + 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_650.Dm_build_661(ret, 5, int16(tz)) + } + + return ret, nil +} + +func toDate(x int64, column column, conn DmConnection) ([]byte, error) { + switch column.colType { + case DATETIME, DATETIME2: + if x > 2958463*24*60*60 { + return nil, ECGO_DATETIME_OVERFLOW.throw() + } + + dt := toDTFromUnix(x-Seconds_1900_1970, 0) + return encode(dt, column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone)) + + case TIME: + dt := toDTFromUnix(x, 0) + return encode(dt, column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone)) + + 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, column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone)) + + default: + return nil, ECGO_DATA_CONVERTION_ERROR.throw() + } +} + +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/vendor/gitee.com/chunanyong/dm/i.go b/vendor/gitee.com/chunanyong/dm/i.go new file mode 100644 index 0000000000..4101f92fe0 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/i.go @@ -0,0 +1,917 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "strconv" + "time" + + "gitee.com/chunanyong/dm/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_650.Dm_build_902(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_650.Dm_build_801(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_650.Dm_build_866(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_650.Dm_build_874(bytes)), 10) + case INT: + return strconv.FormatInt(int64(Dm_build_650.Dm_build_877(bytes)), 10) + case BIGINT: + return strconv.FormatInt(int64(Dm_build_650.Dm_build_880(bytes)), 10) + case REAL: + return strconv.FormatFloat(float64(Dm_build_650.Dm_build_883(bytes)), 'f', -1, 32) + case DOUBLE: + return strconv.FormatFloat(float64(Dm_build_650.Dm_build_886(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, *column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone)) + if conn.FormatDate != "" { + return dtToStringByOracleFormat(dt, conn.FormatDate, column.scale, int(conn.OracleDateLanguage)) + } + case TIME: + dt := decode(bytes, column.isBdta, *column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone)) + if conn.FormatTime != "" { + return dtToStringByOracleFormat(dt, conn.FormatTime, column.scale, int(conn.OracleDateLanguage)) + } + case DATETIME, DATETIME2: + dt := decode(bytes, column.isBdta, *column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone)) + if conn.FormatTimestamp != "" { + return dtToStringByOracleFormat(dt, conn.FormatTimestamp, column.scale, int(conn.OracleDateLanguage)) + } + case TIME_TZ: + dt := decode(bytes, column.isBdta, *column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone)) + if conn.FormatTimeTZ != "" { + return dtToStringByOracleFormat(dt, conn.FormatTimeTZ, column.scale, int(conn.OracleDateLanguage)) + } + case DATETIME_TZ, DATETIME2_TZ: + dt := decode(bytes, column.isBdta, *column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone)) + if conn.FormatTimestampTZ != "" { + return dtToStringByOracleFormat(dt, conn.FormatTimestampTZ, column.scale, 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_650.Dm_build_747(bytes, 0) != 0, nil + case INT: + return Dm_build_650.Dm_build_752(bytes, 0) != 0, nil + case BIGINT: + return Dm_build_650.Dm_build_757(bytes, 0) != 0, nil + case REAL: + return Dm_build_650.Dm_build_762(bytes, 0) != 0, nil + case DOUBLE: + return Dm_build_650.Dm_build_766(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_650.Dm_build_747(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_650.Dm_build_752(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_650.Dm_build_757(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_650.Dm_build_762(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_650.Dm_build_766(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_650.Dm_build_747(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_650.Dm_build_752(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_650.Dm_build_757(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_650.Dm_build_762(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_650.Dm_build_766(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_650.Dm_build_747(bytes, 0), nil + case INT: + + tval := Dm_build_650.Dm_build_752(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_650.Dm_build_757(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_650.Dm_build_762(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_650.Dm_build_766(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_650.Dm_build_747(bytes, 0)), nil + case INT: + tval := Dm_build_650.Dm_build_752(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_650.Dm_build_757(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_650.Dm_build_762(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_650.Dm_build_766(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_650.Dm_build_747(bytes, 0)), nil + case INT: + return Dm_build_650.Dm_build_752(bytes, 0), nil + case BIGINT: + tval := Dm_build_650.Dm_build_757(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_650.Dm_build_762(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_650.Dm_build_766(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_650.Dm_build_747(bytes, 0)), nil + case INT: + return uint32(Dm_build_650.Dm_build_752(bytes, 0)), nil + case BIGINT: + tval := Dm_build_650.Dm_build_757(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_650.Dm_build_762(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_650.Dm_build_766(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_650.Dm_build_874(bytes)), nil + case INT: + return int64(Dm_build_650.Dm_build_877(bytes)), nil + case BIGINT: + return int64(Dm_build_650.Dm_build_880(bytes)), nil + case REAL: + return int64(Dm_build_650.Dm_build_883(bytes)), nil + case DOUBLE: + return int64(Dm_build_650.Dm_build_886(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_650.Dm_build_874(bytes)), nil + case INT: + return uint64(Dm_build_650.Dm_build_877(bytes)), nil + case BIGINT: + return uint64(Dm_build_650.Dm_build_880(bytes)), nil + case REAL: + return uint64(Dm_build_650.Dm_build_883(bytes)), nil + case DOUBLE: + return uint64(Dm_build_650.Dm_build_886(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_650.Dm_build_747(bytes, 0)), nil + case INT: + return float32(Dm_build_650.Dm_build_752(bytes, 0)), nil + case BIGINT: + return float32(Dm_build_650.Dm_build_757(bytes, 0)), nil + case REAL: + return Dm_build_650.Dm_build_762(bytes, 0), nil + case DOUBLE: + dval := Dm_build_650.Dm_build_766(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_650.Dm_build_747(bytes, 0)), nil + case INT: + return float64(Dm_build_650.Dm_build_752(bytes, 0)), nil + case BIGINT: + return float64(Dm_build_650.Dm_build_757(bytes, 0)), nil + case REAL: + return float64(Dm_build_650.Dm_build_762(bytes, 0)), nil + case DOUBLE: + return Dm_build_650.Dm_build_766(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()) + default: + return newBlobOfLocal(value, conn) + } +} + +func (DB2G db2g) toDmClob(value []byte, conn *DmConnection, column *column) *DmClob { + + switch column.colType { + case CLOB: + return newClobFromDB(value, conn, column, conn.lobFetchAll()) + default: + return newClobOfLocal(DB2G.toString(value, column, conn), conn) + } +} + +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_650.Dm_build_747(value, 0))) + case INT: + return NewDecimalFromInt64(int64(Dm_build_650.Dm_build_752(value, 0))) + case BIGINT: + return NewDecimalFromInt64(Dm_build_650.Dm_build_757(value, 0)) + case REAL: + return NewDecimalFromFloat64(float64(Dm_build_650.Dm_build_762(value, 0))) + case DOUBLE: + return NewDecimalFromFloat64(Dm_build_650.Dm_build_766(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, DATETIME2_TZ, DATETIME2: + dt := decode(bytes, column.isBdta, *column, 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_650.Dm_build_743(bytes, 0), nil + case SMALLINT: + return Dm_build_650.Dm_build_747(bytes, 0), nil + case INT: + return Dm_build_650.Dm_build_752(bytes, 0), nil + case BIGINT: + return Dm_build_650.Dm_build_757(bytes, 0), nil + case DECIMAL: + return DB2G.decToDecimal(bytes, int(column.prec), int(column.scale), conn.CompatibleOracle()) + case REAL: + return Dm_build_650.Dm_build_762(bytes, 0), nil + case DOUBLE: + return Dm_build_650.Dm_build_766(bytes, 0), nil + case DATE, TIME, DATETIME, TIME_TZ, DATETIME_TZ, DATETIME2, DATETIME2_TZ: + dt := decode(bytes, column.isBdta, *column, 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 column.mask == MASK_BFILE { + + } + + 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() +} + +func (DB2G db2g) toComplexType(bytes []byte, column *column, conn *DmConnection) (interface{}, error) { + switch column.colType { + case BLOB: + if !isComplexType(int(column.colType), int(column.scale)) { + return nil, ECGO_DATA_CONVERTION_ERROR.throw() + } + blob := newBlobFromDB(bytes, conn, column, true) + return TypeDataSV.objBlobToObj(blob, column.typeDescriptor) + case ARRAY: + return TypeDataSV.bytesToArray(bytes, nil, column.typeDescriptor) + case SARRAY: + return TypeDataSV.bytesToSArray(bytes, nil, column.typeDescriptor) + case CLASS: + return TypeDataSV.bytesToObj(bytes, nil, column.typeDescriptor) + case PLTYPE_RECORD: + return nil, ECGO_DATA_CONVERTION_ERROR.throw() + default: + return nil, ECGO_DATA_CONVERTION_ERROR.throw() + } +} diff --git a/vendor/gitee.com/chunanyong/dm/i18n/zj.go b/vendor/gitee.com/chunanyong/dm/i18n/zj.go new file mode 100644 index 0000000000..62b5bfde53 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/i18n/zk.go b/vendor/gitee.com/chunanyong/dm/i18n/zk.go new file mode 100644 index 0000000000..7e1525f471 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/i18n/zk.go @@ -0,0 +1,244 @@ +/* + * 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" + }, + { + "id": "error.ParamCountLimit", + "translation": "Parameter count limit is 65536." + }, + { + "id": "error.unbindedParameter", + "translation": "Unbound parameter" + }, + { + "id": "error.stringCut", + "translation": "The string is cut" + }, + { + "id": "error.connectionClosedOrNotBuild", + "translation": "Connection is colsed or not build" + } + ] +}` diff --git a/vendor/gitee.com/chunanyong/dm/i18n/zl.go b/vendor/gitee.com/chunanyong/dm/i18n/zl.go new file mode 100644 index 0000000000..d7c87e713c --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/i18n/zl.go @@ -0,0 +1,244 @@ +/* + * 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" + }, + { + "id": "error.ParamCountLimit", + "translation": "参数个数超过最大值65536." + }, + { + "id": "error.unbindedParameter", + "translation": "有参数未绑定" + }, + { + "id": "error.stringCut", + "translation": "字符串截断" + }, + { + "id": "error.connectionClosedOrNotBuild", + "translation": "连接尚未建立或已经关闭" + } + ] +}` diff --git a/vendor/gitee.com/chunanyong/dm/i18n/zm.go b/vendor/gitee.com/chunanyong/dm/i18n/zm.go new file mode 100644 index 0000000000..5bf70f80a1 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/i18n/zm.go @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package i18n + +const Messages_zh_HK = `{ + "language": "zh-Hant", + "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" + }, + { + "id": "error.ParamCountLimit", + "translation": "參數個數超過最大值65536." + }, + { + "id": "error.unbindedParameter", + "translation": "有參數未綁定" + }, + { + "id": "error.stringCut", + "translation": "字符串截斷" + }, + { + "id": "error.connectionClosedOrNotBuild", + "translation": "連接尚未建立或已經關閉" + } + ] +}` \ No newline at end of file diff --git a/vendor/gitee.com/chunanyong/dm/j.go b/vendor/gitee.com/chunanyong/dm/j.go new file mode 100644 index 0000000000..2617e1239a --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/j.go @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +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 +} + +// 数据库自定义数组Array构造函数,typeName为库中定义的数组类型名称,elements为该数组类型的每个值 +// +// 例如,自定义数组类型语句为:create or replace type myArray is array int[]; +// +// 则绑入绑出的go对象为: val := dm.NewDmArray("myArray", []interface{} {123, 456}) +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 +} + +// 获取Array对象在数据库中的类型名称 +func (da *DmArray) GetBaseTypeName() (string, error) { + if err := da.checkValid(); err != nil { + return "", err + } + return da.m_arrDesc.m_typeDesc.getFulName() +} + +// 获取Array对象的go数组对象 +func (da *DmArray) GetArray() (interface{}, error) { + if da.m_arrData == nil || len(da.m_arrData) <= 0 { + return nil, nil; + } + + return TypeDataSV.toJavaArray(da, 0, len(da.m_arrData), da.m_arrDesc.getItemDesc().getDType()) +} + +// 获取Array对象的指定偏移和执行长度go数据对象 index从0开始 +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/vendor/gitee.com/chunanyong/dm/k.go b/vendor/gitee.com/chunanyong/dm/k.go new file mode 100644 index 0000000000..abfa83cf49 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/k.go @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +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_650.Dm_build_743(value, NBLOB_HEAD_IN_ROW_FLAG) == LOB_IN_ROW + blob.blobId = Dm_build_650.Dm_build_757(value, NBLOB_HEAD_BLOBID) + if !blob.inRow { + blob.groupId = Dm_build_650.Dm_build_747(value, NBLOB_HEAD_OUTROW_GROUPID) + blob.fileId = Dm_build_650.Dm_build_747(value, NBLOB_HEAD_OUTROW_FILEID) + blob.pageNo = Dm_build_650.Dm_build_752(value, NBLOB_HEAD_OUTROW_PAGENO) + } + if conn.NewLobFlag { + blob.tabId = Dm_build_650.Dm_build_752(value, NBLOB_EX_HEAD_TABLE_ID) + blob.colId = Dm_build_650.Dm_build_747(value, NBLOB_EX_HEAD_COL_ID) + blob.rowId = Dm_build_650.Dm_build_757(value, NBLOB_EX_HEAD_ROW_ID) + blob.exGroupId = Dm_build_650.Dm_build_747(value, NBLOB_EX_HEAD_FPA_GRPID) + blob.exFileId = Dm_build_650.Dm_build_747(value, NBLOB_EX_HEAD_FPA_FILEID) + blob.exPageNo = Dm_build_650.Dm_build_752(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_650.Dm_build_706(blob.data, 0, value, NBLOB_EX_HEAD_SIZE, len(blob.data)) + } else { + Dm_build_650.Dm_build_706(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_1561(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_650.Dm_build_706(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_1575(&blob.lob, int(length)) + if err != nil { + return err + } + if blob.groupId == -1 { + tmp := make([]byte, blob.length) + Dm_build_650.Dm_build_706(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_1522(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_650.Dm_build_706(tmp, 0, blob.data, 0, pos) + Dm_build_650.Dm_build_706(tmp, pos, p, 0, len(p)) + blob.data = tmp + } else { + Dm_build_650.Dm_build_706(blob.data, pos, p, 0, len(p)) + } + blob.length = int64(len(blob.data)) +} + +func (d *DmBlob) GormDataType() string { + return "BLOB" +} diff --git a/vendor/gitee.com/chunanyong/dm/l.go b/vendor/gitee.com/chunanyong/dm/l.go new file mode 100644 index 0000000000..5091a32927 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/l.go @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +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_650.Dm_build_743(value, NBLOB_HEAD_IN_ROW_FLAG) == LOB_IN_ROW + clob.blobId = Dm_build_650.Dm_build_757(value, NBLOB_HEAD_BLOBID) + if !clob.inRow { + clob.groupId = Dm_build_650.Dm_build_747(value, NBLOB_HEAD_OUTROW_GROUPID) + clob.fileId = Dm_build_650.Dm_build_747(value, NBLOB_HEAD_OUTROW_FILEID) + clob.pageNo = Dm_build_650.Dm_build_752(value, NBLOB_HEAD_OUTROW_PAGENO) + } + if conn.NewLobFlag { + clob.tabId = Dm_build_650.Dm_build_752(value, NBLOB_EX_HEAD_TABLE_ID) + clob.colId = Dm_build_650.Dm_build_747(value, NBLOB_EX_HEAD_COL_ID) + clob.rowId = Dm_build_650.Dm_build_757(value, NBLOB_EX_HEAD_ROW_ID) + clob.exGroupId = Dm_build_650.Dm_build_747(value, NBLOB_EX_HEAD_FPA_GRPID) + clob.exFileId = Dm_build_650.Dm_build_747(value, NBLOB_EX_HEAD_FPA_FILEID) + clob.exPageNo = Dm_build_650.Dm_build_752(value, NBLOB_EX_HEAD_FPA_PAGENO) + } + clob.resetCurrentInfo() + + clob.serverEncoding = conn.getServerEncoding() + if clob.inRow { + if conn.NewLobFlag { + clob.data = []rune(Dm_build_650.Dm_build_807(value, NBLOB_EX_HEAD_SIZE, int(clob.getLengthFromHead(value)), clob.serverEncoding, conn)) + } else { + clob.data = []rune(Dm_build_650.Dm_build_807(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_1545(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_1575(&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_1533(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)) +} + +func (d *DmClob) GormDataType() string { + return "CLOB" +} diff --git a/vendor/gitee.com/chunanyong/dm/m.go b/vendor/gitee.com/chunanyong/dm/m.go new file mode 100644 index 0000000000..f006512699 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/m.go @@ -0,0 +1,875 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "bytes" + "context" + "database/sql" + "database/sql/driver" + "fmt" + "sync" + "sync/atomic" + + "gitee.com/chunanyong/dm/parser" + + "gitee.com/chunanyong/dm/util" + "golang.org/x/text/encoding" +) + +type DmConnection struct { + filterable + mu sync.Mutex + + dmConnector *DmConnector + Access *dm_build_1345 + stmtMap map[int32]*DmStatement + + 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 + 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_132 { + case Dm_build_129, Dm_build_130, Dm_build_131: + conn.trxFinish = true + default: + conn.trxFinish = false + } +} + +func (dmConn *DmConnection) init() { + + 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.Malini2 = true + dmConn.NewLobFlag = true + dmConn.Execute2 = true + dmConn.serverEncoding = ENCODING_GB18030 + dmConn.TrxStatus = Dm_build_80 + dmConn.setTrxFinish(dmConn.TrxStatus) + dmConn.OracleDateLanguage = byte(Locale) + dmConn.lastExecInfo = NewExceInfo() + dmConn.MsgVersion = Dm_build_13 + + 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.Malini2 = true + dmConn.NewLobFlag = true + dmConn.Execute2 = true + dmConn.serverEncoding = ENCODING_GB18030 + dmConn.TrxStatus = Dm_build_80 + dmConn.setTrxFinish(dmConn.TrxStatus) +} + +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_97 { + 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_96 && 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_1428(stmt, optParamList) + if err != nil { + stmt.nativeSql = query + info, err = dc.Access.Dm_build_1434(stmt, execType) + } + } else { + info, err = dc.Access.Dm_build_1434(stmt, execType) + } + + if err != nil { + stmt.close() + return nil, err + } + dc.lastExecInfo = info + + if execType == Dm_build_96 && 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_84 + case 2: + return Dm_build_85 + case 4: + return Dm_build_86 + case 6: + return Dm_build_87 + 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) + } + if err := dc.filterChain.reset().DmConnectionResetSession(dc, ctx); err != nil { + return driver.ErrBadConn + } else { + return nil + } +} + +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 dc.ReadOnly != opts.ReadOnly { + dc.ReadOnly = opts.ReadOnly + var readonly = 0 + if opts.ReadOnly { + readonly = 1 + } + dc.exec(fmt.Sprintf("SP_SET_SESSION_READONLY(%d)", readonly), nil) + } + + if dc.IsoLevel != int32(opts.Isolation) { + switch sql.IsolationLevel(opts.Isolation) { + case sql.LevelDefault: + dc.IsoLevel = int32(sql.LevelReadCommitted) + case sql.LevelReadUncommitted, 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_1488(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.ReadOnly { + dc.exec("SP_SET_SESSION_READONLY(0)", nil) + } + }() + + 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.ReadOnly { + dc.exec("SP_SET_SESSION_READONLY(0)", nil) + } + }() + + 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 { + + for id, rs := range stmt.rsMap { + rs.Close() + delete(stmt.rsMap, id) + } + } + + var newConn *DmConnection + if dc.dmConnector.group != nil { + if newConn, err = dc.dmConnector.group.connect(dc.dmConnector); err != nil { + return err + } + } else { + newConn, err = dc.dmConnector.connect(context.Background()) + } + + oldMap := dc.stmtMap + newConn.mu = dc.mu + newConn.filterable = dc.filterable + *dc = *newConn + + for _, stmt := range oldMap { + if stmt.closed { + continue + } + err = dc.Access.Dm_build_1406(stmt) + if err != nil { + stmt.free() + continue + } + + if stmt.prepared || stmt.paramCount > 0 { + if err = stmt.prepare(); err != nil { + continue + } + } + + dc.stmtMap[stmt.id] = stmt + } + + return nil +} + +func (dc *DmConnection) cleanup() { + dc.close() +} + +func (dc *DmConnection) close() error { + if !dc.closed.TrySet(true) { + return nil + } + + util.AbsorbPanic(func() { + close(dc.closech) + }) + if dc.Access == nil { + return nil + } + + dc.rollback() + + for _, stmt := range dc.stmtMap { + stmt.free() + } + + 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) + if err != nil { + return nil, err + } + defer stmt.close() + dc.lastExecInfo = stmt.execInfo + + return stmt.exec(args) + } else { + r1, err := dc.executeInner(query, Dm_build_97) + 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) + if err != nil { + return nil, err + } + defer stmt.close() + dc.lastExecInfo = stmt.execInfo + dargs, err := namedValueToValue(stmt, args) + if err != nil { + return nil, err + } + return stmt.exec(dargs) + } else { + r1, err := dc.executeInner(query, Dm_build_97) + 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 { + return nil, err + } + dc.lastExecInfo = stmt.execInfo + + stmt.innerUsed = true + return stmt.query(args) + + } else { + r1, err := dc.executeInner(query, Dm_build_96) + 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 { + return nil, err + } + dc.lastExecInfo = stmt.execInfo + + stmt.innerUsed = true + dargs, err := namedValueToValue(stmt, args) + if err != nil { + return nil, err + } + return stmt.query(dargs) + + } else { + r1, err := dc.executeInner(query, Dm_build_96) + 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) (stmt *DmStatement, err error) { + if err = dc.checkClosed(); err != nil { + return + } + if stmt, err = NewDmStmt(dc, query); err != nil { + return + } + if err = stmt.prepare(); err != nil { + stmt.close() + stmt = nil + return + } + return +} + +func (dc *DmConnection) prepareContext(ctx context.Context, query string) (*DmStatement, error) { + if err := dc.watchCancel(ctx); err != nil { + return nil, err + } + defer dc.finish() + + return dc.prepare(query) +} + +func (dc *DmConnection) resetSession(ctx context.Context) error { + if err := dc.watchCancel(ctx); err != nil { + return err + } + defer dc.finish() + + err := dc.checkClosed() + if err != nil { + return err + } + + 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_1434(stmt, Dm_build_96) + 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) + 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/vendor/gitee.com/chunanyong/dm/n.go b/vendor/gitee.com/chunanyong/dm/n.go new file mode 100644 index 0000000000..9ca012d8f8 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/n.go @@ -0,0 +1,923 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "bytes" + "context" + "database/sql/driver" + "net" + "net/url" + "os" + "path/filepath" + "regexp" + "runtime" + "strconv" + "strings" + "sync" + "time" + + "gitee.com/chunanyong/dm/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" + DriverReconnectKey = "driverReconnect" + 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" + DialNameKey = "dialName" + 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" + + 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 + + LANGUAGE_CNT_HK = 2 + + COLUMN_NAME_NATURAL_CASE = 0 + + COLUMN_NAME_UPPER_CASE = 1 + + COLUMN_NAME_LOWER_CASE = 2 + + compressDef = Dm_build_91 + compressIDDef = Dm_build_92 + + 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_74 + + continueBatchOnErrorDef = false + + escapeProcessDef = false + + autoCommitDef = true + + maxRowsDef = 0 + + rowPrefetchDef = Dm_build_75 + + bufPrefetchDef = 0 + + lobModeDef = 1 + + stmtPoolMaxSizeDef = 15 + + ignoreCaseDef = true + + alwayseAllowCommitDef = true + + isBdtaRSDef = false + + kerberosLoginConfPathDef = "" + + uKeyNameDef = "" + + uKeyPinDef = "" + + databaseProductNameDef = "" + + caseSensitiveDef = true + + compatibleModeDef = 0 +) + +type DmConnector struct { + filterable + + mu sync.Mutex + + 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 + + driverReconnect bool + + cluster int32 + + cipherPath string + + url string + + user string + + password string + + dialName 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 + + 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_WHEN_CONN_ERROR + c.driverReconnect = false + 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 + _, tzs := time.Now().Zone() + c.localTimezone = int16(tzs / 60) + 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.dialName = props.GetString(DialNameKey, "") + c.rwStandby = props.GetBool(RwStandbyKey, c.rwStandby) + + if b := props.GetBool(IsCompressKey, false); b { + c.compress = Dm_build_90 + } + + 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) + parseLanguage(props.GetString(LanguageKey, "")) + + 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.driverReconnect = props.GetBool(DriverReconnectKey, c.driverReconnect) + 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_76), int(Dm_build_77)) + 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_74 + } else if util.StringUtil.EqualsIgnoreCase(value, "SYSDBA") { + c.osAuthType = Dm_build_70 + } else if util.StringUtil.EqualsIgnoreCase(value, "SYSAUDITOR") { + c.osAuthType = Dm_build_72 + } else if util.StringUtil.EqualsIgnoreCase(value, "SYSSSO") { + c.osAuthType = Dm_build_71 + } else if util.StringUtil.EqualsIgnoreCase(value, "AUTO") { + c.osAuthType = Dm_build_73 + } else if util.StringUtil.EqualsIgnoreCase(value, "OFF") { + c.osAuthType = Dm_build_69 + } + } else { + c.osAuthType = byte(props.GetInt(OsAuthTypeKey, int(c.osAuthType), 0, 4)) + } + if c.user == "" && c.osAuthType == Dm_build_69 { + c.user = "SYSDBA" + } else if c.osAuthType != Dm_build_69 && c.user != "" { + return ECGO_OSAUTH_ERROR.throw() + } else if c.osAuthType != Dm_build_69 { + 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 a := props.GetTrimString(host, ""); a != "" { + + if strings.HasPrefix(a, "(") && strings.HasSuffix(a, ")") { + a = strings.TrimSpace(a[1 : len(a)-1]) + } + c.group = parseServerName(host, a) + if c.group != nil { + c.group.props = NewProperties() + c.group.props.SetProperties(GlobalProperties) + } + } else if group, ok := ServerGroupMap[strings.ToLower(host)]; ok { + + c.group = group + } else { + host, port, err := net.SplitHostPort(host) + if err == nil { + ip := net.ParseIP(host) + var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff} + if ip != nil && len(ip) == net.IPv6len && !bytes.Equal(ip[0:12], v4InV6Prefix) { + + host = "[" + host + "]" + } + } + + 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) { + c.mu.Lock() + defer c.mu.Unlock() + return c.filterChain.reset().DmConnectorConnect(c, ctx) +} + +func (c *DmConnector) Driver() driver.Driver { + c.mu.Lock() + defer c.mu.Unlock() + 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{ + closech: make(chan struct{}), + dmConnector: c, + autoCommit: c.autoCommit, + } + + dc.createFilterChain(c, nil) + dc.objId = -1 + dc.init() + + dc.Access, err = dm_build_1357(ctx, 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_1402(); 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/vendor/gitee.com/chunanyong/dm/o.go b/vendor/gitee.com/chunanyong/dm/o.go new file mode 100644 index 0000000000..db5bbd5a61 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/o.go @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +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 float32, float64: + d, err := NewDecimalFromFloat64(reflect.ValueOf(src).Float()) + 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_650.Dm_build_770(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 +} + +func (d *DmDecimal) GormDataType() string { + return "DECIMAL" +} diff --git a/vendor/gitee.com/chunanyong/dm/p.go b/vendor/gitee.com/chunanyong/dm/p.go new file mode 100644 index 0000000000..51664cac31 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/p.go @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "context" + "database/sql" + "database/sql/driver" + "net" + "sync" + + "gitee.com/chunanyong/dm/i18n" +) + +// 发版标记 +var version = "8.1.3.100" +var build_date = "2023.12.14" +var svn = "20657" + +var globalDmDriver = newDmDriver() + +func init() { + sql.Register("dm", globalDmDriver) + + i18n.InitConfig(i18n.Messages_zh_CN) + i18n.InitConfig(i18n.Messages_en_US) + i18n.InitConfig(i18n.Messages_zh_HK) +} + +func driverInit(svcConfPath string) { + load(svcConfPath) + if GlobalProperties != nil && GlobalProperties.Len() > 0 { + setDriverAttributes(GlobalProperties) + } + globalDmDriver.createFilterChain(nil, GlobalProperties) +} + +type DmDriver struct { + filterable + mu sync.Mutex + //readPropMutex sync.Mutex +} + +func newDmDriver() *DmDriver { + d := new(DmDriver) + d.idGenerator = dmDriverIDGenerator + return d +} + +// 支持自定义连接网络地址,返回标准net.Conn对象,相关数据库操作的消息包都将发送到该对象 +type DialFunc func(addr string) (net.Conn, error) + +// 支持自定义连接网络地址,返回标准net.Conn对象,相关数据库操作的消息包都将发送到该对象 +type DialContextFunc func(ctx context.Context, addr string) (net.Conn, error) + +var ( + dialsLock sync.RWMutex + dials map[string]DialContextFunc +) + +// 注册自定义连接方法 +func RegisterDial(dialName string, dial DialFunc) { + RegisterDialContext(dialName, func(_ context.Context, addr string) (net.Conn, error) { + return dial(addr) + }) +} + +// 注册自定义连接方法 +func RegisterDialContext(dialName string, dial DialContextFunc) { + dialsLock.Lock() + defer dialsLock.Unlock() + if dials == nil { + dials = make(map[string]DialContextFunc) + } + dials[dialName] = dial +} + +/************************************************************* + ** PUBLIC METHODS AND FUNCTIONS + *************************************************************/ +func (d *DmDriver) Open(dsn string) (driver.Conn, error) { + d.mu.Lock() + defer d.mu.Unlock() + return d.open(dsn) +} + +func (d *DmDriver) OpenConnector(dsn string) (driver.Connector, error) { + d.mu.Lock() + defer d.mu.Unlock() + 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/vendor/gitee.com/chunanyong/dm/parser/zt.go b/vendor/gitee.com/chunanyong/dm/parser/zt.go new file mode 100644 index 0000000000..04963dd556 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/parser/zu.go b/vendor/gitee.com/chunanyong/dm/parser/zu.go new file mode 100644 index 0000000000..ed960f321c --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/q.go b/vendor/gitee.com/chunanyong/dm/q.go new file mode 100644 index 0000000000..2528463bb4 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/q.go @@ -0,0 +1,1455 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "database/sql/driver" + "math" + "strconv" + "strings" + + "gitee.com/chunanyong/dm/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_650.Dm_build_752(bytes, 20)) + dt.leadScale = (dt.scaleForSvr >> 4) & 0x0000000F + dt.secScale = dt.scaleForSvr & 0x0000000F + + switch dt._type { + case QUA_D: + dt.days = int(Dm_build_650.Dm_build_752(bytes, 0)) + case QUA_DH: + dt.days = int(Dm_build_650.Dm_build_752(bytes, 0)) + dt.hours = int(Dm_build_650.Dm_build_752(bytes, 4)) + case QUA_DHM: + dt.days = int(Dm_build_650.Dm_build_752(bytes, 0)) + dt.hours = int(Dm_build_650.Dm_build_752(bytes, 4)) + dt.minutes = int(Dm_build_650.Dm_build_752(bytes, 8)) + case QUA_DHMS: + dt.days = int(Dm_build_650.Dm_build_752(bytes, 0)) + dt.hours = int(Dm_build_650.Dm_build_752(bytes, 4)) + dt.minutes = int(Dm_build_650.Dm_build_752(bytes, 8)) + dt.seconds = int(Dm_build_650.Dm_build_752(bytes, 12)) + dt.fraction = int(Dm_build_650.Dm_build_752(bytes, 16)) + case QUA_H: + dt.hours = int(Dm_build_650.Dm_build_752(bytes, 4)) + case QUA_HM: + dt.hours = int(Dm_build_650.Dm_build_752(bytes, 4)) + dt.minutes = int(Dm_build_650.Dm_build_752(bytes, 8)) + case QUA_HMS: + dt.hours = int(Dm_build_650.Dm_build_752(bytes, 4)) + dt.minutes = int(Dm_build_650.Dm_build_752(bytes, 8)) + dt.seconds = int(Dm_build_650.Dm_build_752(bytes, 12)) + dt.fraction = int(Dm_build_650.Dm_build_752(bytes, 16)) + case QUA_M: + dt.minutes = int(Dm_build_650.Dm_build_752(bytes, 8)) + case QUA_MS: + dt.minutes = int(Dm_build_650.Dm_build_752(bytes, 8)) + dt.seconds = int(Dm_build_650.Dm_build_752(bytes, 12)) + dt.fraction = int(Dm_build_650.Dm_build_752(bytes, 16)) + case QUA_S: + dt.seconds = int(Dm_build_650.Dm_build_752(bytes, 12)) + dt.fraction = int(Dm_build_650.Dm_build_752(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_650.Dm_build_666(bytes, 0, int32(-day)) + Dm_build_650.Dm_build_666(bytes, 4, int32(-hour)) + Dm_build_650.Dm_build_666(bytes, 8, int32(-minute)) + Dm_build_650.Dm_build_666(bytes, 12, int32(-second)) + Dm_build_650.Dm_build_666(bytes, 16, int32(-f)) + Dm_build_650.Dm_build_666(bytes, 20, int32(scale)) + } else { + Dm_build_650.Dm_build_666(bytes, 0, int32(day)) + Dm_build_650.Dm_build_666(bytes, 4, int32(hour)) + Dm_build_650.Dm_build_666(bytes, 8, int32(minute)) + Dm_build_650.Dm_build_666(bytes, 12, int32(second)) + Dm_build_650.Dm_build_666(bytes, 16, int32(f)) + Dm_build_650.Dm_build_666(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 +} + +func (d *DmIntervalDT) GormDataType() string { + return "INTERVAL DAY TO SECOND" +} diff --git a/vendor/gitee.com/chunanyong/dm/r.go b/vendor/gitee.com/chunanyong/dm/r.go new file mode 100644 index 0000000000..c03290c46a --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/r.go @@ -0,0 +1,494 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "database/sql/driver" + "math" + "strconv" + "strings" + + "gitee.com/chunanyong/dm/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_650.Dm_build_752(bytes, 8)) + ym.leadScale = (ym.scaleForSvr >> 4) & 0x0000000F + ym._type = bytes[9] + switch ym._type { + case QUA_Y: + ym.years = int(Dm_build_650.Dm_build_752(bytes, 0)) + case QUA_YM: + ym.years = int(Dm_build_650.Dm_build_752(bytes, 0)) + ym.months = int(Dm_build_650.Dm_build_752(bytes, 4)) + case QUA_MO: + ym.months = int(Dm_build_650.Dm_build_752(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_650.Dm_build_666(bytes, 0, int32(year)) + Dm_build_650.Dm_build_666(bytes, 4, int32(month)) + Dm_build_650.Dm_build_666(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 +} + +func (d *DmIntervalYM) GormDataType() string { + return "INTERVAL YEAR TO MONTH" +} diff --git a/vendor/gitee.com/chunanyong/dm/s.go b/vendor/gitee.com/chunanyong/dm/s.go new file mode 100644 index 0000000000..cd025f83ff --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/s.go @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +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/vendor/gitee.com/chunanyong/dm/security/zy.go b/vendor/gitee.com/chunanyong/dm/security/zy.go new file mode 100644 index 0000000000..b3ccc38103 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/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) +} diff --git a/vendor/gitee.com/chunanyong/dm/security/zz.go b/vendor/gitee.com/chunanyong/dm/security/zz.go new file mode 100644 index 0000000000..45b2c1a02f --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/security/zza.go b/vendor/gitee.com/chunanyong/dm/security/zza.go new file mode 100644 index 0000000000..92062ced60 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/security/zzb.go b/vendor/gitee.com/chunanyong/dm/security/zzb.go new file mode 100644 index 0000000000..f9af99448d --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/security/zzc.go b/vendor/gitee.com/chunanyong/dm/security/zzc.go new file mode 100644 index 0000000000..ee09356a92 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/security/zzd.go b/vendor/gitee.com/chunanyong/dm/security/zzd.go new file mode 100644 index 0000000000..bedbc54e9f --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/security/zze.go b/vendor/gitee.com/chunanyong/dm/security/zze.go new file mode 100644 index 0000000000..ca33e1e774 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/security/zze.go @@ -0,0 +1,211 @@ +/* + * 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) +} diff --git a/vendor/gitee.com/chunanyong/dm/security/zzf.go b/vendor/gitee.com/chunanyong/dm/security/zzf.go new file mode 100644 index 0000000000..d002c65dcc --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/security/zzf.go @@ -0,0 +1,142 @@ +/* + * 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() + if err = tpc.getInfo(); err != nil { + return tpc, err + } + return tpc, nil +} + +func (tpc *ThirdPartCipher) getCount() int { + if tpc.cipherCount == -1 { + tpc.cipherCount = cipherGetCount() + } + return tpc.cipherCount +} + +func (tpc *ThirdPartCipher) getInfo() error { + 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 nil + } + } + return fmt.Errorf("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/vendor/gitee.com/chunanyong/dm/security/zzg_darwin.go b/vendor/gitee.com/chunanyong/dm/security/zzg_darwin.go new file mode 100644 index 0000000000..835002eda4 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/security/zzg_linux.go b/vendor/gitee.com/chunanyong/dm/security/zzg_linux.go new file mode 100644 index 0000000000..835002eda4 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/security/zzh_windows.go b/vendor/gitee.com/chunanyong/dm/security/zzh_windows.go new file mode 100644 index 0000000000..2fa686199a --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/security/zzi.go b/vendor/gitee.com/chunanyong/dm/security/zzi.go new file mode 100644 index 0000000000..a68cc9e31a --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/security/zzi.go @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package security + +import ( + "crypto/tls" + "errors" + "flag" + "net" + "os" + "sync" +) + +var dmHome = flag.String("DM_HOME", "", "Where DMDB installed") +var flagLock = sync.Mutex{} + +func NewTLSFromTCP(conn net.Conn, sslCertPath string, sslKeyPath string, user string) (*tls.Conn, error) { + if sslCertPath == "" && sslKeyPath == "" { + // 为什么从os.getEnv改为flag? 参照JDBC,它通过System.getProperty()获取命令中的-DDM_HOME=值 + // flag非协程安全,内部存在并发写map的操作 + func () { + flagLock.Lock() + defer flagLock.Unlock() + 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 +} diff --git a/vendor/gitee.com/chunanyong/dm/t.go b/vendor/gitee.com/chunanyong/dm/t.go new file mode 100644 index 0000000000..c77bb1347a --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/t.go @@ -0,0 +1,522 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +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 (dest *DmRows) Scan(src interface{}) error { + switch src := src.(type) { + case nil: + *dest = *new(DmRows) + return nil + case *DmRows: + *dest = *src + return nil + default: + return UNSUPPORTED_SCAN + } +} + +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 { + if err := innerRows.checkClosed(); err != nil { + return nil + } + + 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 { + return false + } + + if innerRows.nextExecInfo != nil { + return innerRows.nextExecInfo.hasResultSet + } + + innerRows.nextExecInfo, err = innerRows.dmStmt.dmConn.Access.Dm_build_1466(innerRows.dmStmt, 0) + if err != nil { + return false + } + + 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 { + if err := innerRows.checkClosed(); err != nil { + return nil + } + if column := innerRows.checkIndex(index); column != nil { + return column.ScanType() + } + return nil +} + +func (innerRows *innerRows) ColumnTypeDatabaseTypeName(index int) string { + if err := innerRows.checkClosed(); err != nil { + return "" + } + if column := innerRows.checkIndex(index); column != nil { + return column.typeName + } + return "" +} + +func (innerRows *innerRows) ColumnTypeLength(index int) (length int64, ok bool) { + if err := innerRows.checkClosed(); err != nil { + return 0, false + } + if column := innerRows.checkIndex(index); column != nil { + return column.Length() + } + return 0, false +} + +func (innerRows *innerRows) ColumnTypeNullable(index int) (nullable, ok bool) { + if err := innerRows.checkClosed(); err != nil { + return false, false + } + if column := innerRows.checkIndex(index); column != nil { + return column.nullable, true + } + return false, false +} + +func (innerRows *innerRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) { + if err := innerRows.checkClosed(); err != nil { + return 0, 0, false + } + if column := innerRows.checkIndex(index); column != nil { + return column.PrecisionScale() + } + return 0, 0, false +} + +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 { + return nil + } + + return &innerRows.columns[index] +} + +func (innerRows *innerRows) fetchData(startPos int64) bool { + execInfo, err := innerRows.dmStmt.dmConn.Access.Dm_build_1473(innerRows, startPos) + if err != nil { + return false + } + + 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_1466(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/vendor/gitee.com/chunanyong/dm/u.go b/vendor/gitee.com/chunanyong/dm/u.go new file mode 100644 index 0000000000..5cb00a4df6 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/u.go @@ -0,0 +1,1495 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "container/list" + "context" + "database/sql" + "database/sql/driver" + "fmt" + "io" + "math/big" + "reflect" + "strconv" + "strings" + "time" + + "gitee.com/chunanyong/dm/util" +) + +var rp = newRsPool() + +type DmStatement struct { + filterable + + dmConn *DmConnection + rsMap map[int16]*innerRows + inUse bool + + prepared 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 + + serverParams []parameter + + bindParams []parameter + + paramCount int32 + + 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_1499(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 -1 + } + 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_1424(st, Dm_build_95) + if err != nil { + return err + } + st.prepared = true + return nil +} + +func (stmt *DmStatement) close() error { + delete(stmt.dmConn.stmtMap, stmt.id) + if stmt.closed { + return nil + } + stmt.inUse = true + + 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_97) + } + 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_96) + if err != nil { + return nil, err + } + + if stmt.execInfo.hasResultSet { + return newDmRows(newInnerRows(0, stmt, stmt.execInfo)), nil + } else { + return newDmRows(newLocalInnerRows(stmt, nil, nil)), 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 + } + defer stmt.dmConn.finish() + + 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 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 + + err := conn.Access.Dm_build_1406(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) free() error { + delete(stmt.dmConn.stmtMap, stmt.id) + for _, rs := range stmt.rsMap { + rs.Close() + } + + err := stmt.dmConn.Access.Dm_build_1411(int32(stmt.id)) + if err != nil { + return err + } + stmt.inUse = false + stmt.closed = true + return nil +} + +func bindInParam(stmt *DmStatement, i int, dtype int32, firstRow bool) { + if !firstRow { + return + } + isNil := dtype == NULL + serverParam := &stmt.serverParams[i] + bindParam := &stmt.bindParams[i] + if serverParam == nil { + bindParam.resetType(dtype) + } else { + bindParam.name = serverParam.name + bindParam.typeDescriptor = serverParam.typeDescriptor + bindParam.mask = serverParam.mask + bindParam.typeFlag = serverParam.typeFlag + + if (serverParam.colType != UNKNOWN && (isNil || serverParam.typeFlag == TYPE_FLAG_EXACT)) || serverParam.mask != 0 { + + bindParam.colType = serverParam.colType + bindParam.prec = serverParam.prec + bindParam.scale = serverParam.scale + bindParam.mask = serverParam.mask + } else { + + bindParam.resetType(dtype) + } + } + + if bindParam.ioType == IO_TYPE_OUT || bindParam.ioType == IO_TYPE_INOUT { + bindParam.ioType = IO_TYPE_INOUT + } else { + bindParam.ioType = IO_TYPE_IN + } +} + +func checkBindParameters(stmt *DmStatement, bytes []interface{}) error { + + for i := 0; int32(i) < stmt.paramCount; i++ { + if stmt.bindParams[i].ioType == IO_TYPE_UNKNOWN { + + if stmt.serverParams[i].ioType == IO_TYPE_OUT { + + bytes[i] = nil + } else { + return ECGO_UNBINDED_PARAMETER.throw() + } + } + + if stmt.bindParams[i].colType == CURSOR { + stmt.bindParams[i].ioType = IO_TYPE_INOUT + continue + } + + if stmt.serverParams[i].ioType != stmt.bindParams[i].ioType { + + stmt.bindParams[i].ioType = stmt.serverParams[i].ioType + } + } + + for i := 0; int32(i) < stmt.paramCount; i++ { + if stmt.bindParams[i].ioType == IO_TYPE_INOUT || stmt.bindParams[i].ioType == IO_TYPE_OUT { + continue + } + switch stmt.bindParams[i].colType { + case CHAR, VARCHAR, VARCHAR2: + length := -1 + if b, ok := bytes[i].([]byte); ok { + length = len(b) + } + if length > VARCHAR_PREC { + return ECGO_STRING_CUT.throw() + } + if length > int(stmt.bindParams[i].prec) { + if length < VARCHAR_PREC/4 { + stmt.bindParams[i].prec = VARCHAR_PREC / 4 + } else if length < VARCHAR_PREC/2 { + stmt.bindParams[i].prec = VARCHAR_PREC / 2 + } else if length < VARCHAR_PREC*3/4 { + stmt.bindParams[i].prec = VARCHAR_PREC * 3 / 4 + } else { + stmt.bindParams[i].prec = VARCHAR_PREC + } + } + } + } + return nil +} + +func bindOutParam(stmt *DmStatement, i int, dtype int32) error { + var err error + serverParam := &stmt.serverParams[i] + bindParam := &stmt.bindParams[i] + + if bindParam.ioType == IO_TYPE_OUT || bindParam.ioType == IO_TYPE_UNKNOWN { + + if serverParam == nil { + + bindParam.resetType(dtype) + } else { + + bindParam.name = serverParam.name + bindParam.typeDescriptor = serverParam.typeDescriptor + bindParam.mask = serverParam.mask + bindParam.typeFlag = serverParam.typeFlag + + if (serverParam.colType != UNKNOWN && serverParam.typeFlag == TYPE_FLAG_EXACT) || serverParam.mask != 0 { + + bindParam.colType = serverParam.colType + bindParam.prec = serverParam.prec + bindParam.scale = serverParam.scale + bindParam.mask = serverParam.mask + } else { + + bindParam.resetType(dtype) + } + } + + if bindParam.colType == CURSOR { + bindParam.ioType = IO_TYPE_INOUT + if bindParam.cursorStmt == nil { + bindParam.cursorStmt = &DmStatement{dmConn: stmt.dmConn} + bindParam.cursorStmt.resetFilterable(&stmt.dmConn.filterable) + err = bindParam.cursorStmt.dmConn.Access.Dm_build_1406(bindParam.cursorStmt) + } + } + } + + if bindParam.ioType == IO_TYPE_IN || bindParam.ioType == IO_TYPE_INOUT { + bindParam.ioType = IO_TYPE_INOUT + } else { + bindParam.ioType = IO_TYPE_OUT + } + + return err +} + +func encodeArgs(stmt *DmStatement, args []driver.Value, firstRow bool) ([]interface{}, error) { + bytes := make([]interface{}, len(args), len(args)) + + var err error + + for i, arg := range args { + nextSwitch: + if stmt.serverParams[i].colType == CURSOR { + bindInParam(stmt, i, CURSOR, firstRow) + if stmt.bindParams[i].cursorStmt == nil { + stmt.bindParams[i].cursorStmt = &DmStatement{dmConn: stmt.dmConn} + stmt.bindParams[i].cursorStmt.resetFilterable(&stmt.dmConn.filterable) + err = stmt.bindParams[i].cursorStmt.dmConn.Access.Dm_build_1406(stmt.bindParams[i].cursorStmt) + } + stmt.bindParams[i].ioType = IO_TYPE_INOUT + continue + } + if arg == nil { + bindInParam(stmt, i, NULL, firstRow) + bytes[i] = nil + + continue + } + + switch v := arg.(type) { + case bool: + bindInParam(stmt, i, TINYINT, firstRow) + bytes[i], err = G2DB.fromBool(v, stmt.bindParams[i], stmt.dmConn) + case int8: + bindInParam(stmt, i, TINYINT, firstRow) + bytes[i], err = G2DB.fromInt64(int64(v), stmt.bindParams[i], stmt.dmConn) + case int16: + bindInParam(stmt, i, SMALLINT, firstRow) + bytes[i], err = G2DB.fromInt64(int64(v), stmt.bindParams[i], stmt.dmConn) + case int32: + bindInParam(stmt, i, INT, firstRow) + bytes[i], err = G2DB.fromInt64(int64(v), stmt.bindParams[i], stmt.dmConn) + case int64: + bindInParam(stmt, i, BIGINT, firstRow) + bytes[i], err = G2DB.fromInt64(int64(v), stmt.bindParams[i], stmt.dmConn) + case int: + bindInParam(stmt, i, BIGINT, firstRow) + bytes[i], err = G2DB.fromInt64(int64(v), stmt.bindParams[i], stmt.dmConn) + case uint8: + bindInParam(stmt, i, SMALLINT, firstRow) + bytes[i], err = G2DB.fromInt64(int64(v), stmt.bindParams[i], stmt.dmConn) + case uint16: + bindInParam(stmt, i, INT, firstRow) + bytes[i], err = G2DB.fromInt64(int64(v), stmt.bindParams[i], stmt.dmConn) + case uint32: + bindInParam(stmt, i, BIGINT, firstRow) + bytes[i], err = G2DB.fromInt64(int64(v), stmt.bindParams[i], stmt.dmConn) + + case float32: + bindInParam(stmt, i, REAL, firstRow) + bytes[i], err = G2DB.fromFloat32(v, stmt.bindParams[i], stmt.dmConn) + case float64: + bindInParam(stmt, i, DOUBLE, firstRow) + bytes[i], err = G2DB.fromFloat64(float64(v), stmt.bindParams[i], stmt.dmConn) + case []byte: + if v == nil { + bindInParam(stmt, i, NULL, firstRow) + bytes[i] = nil + + } else { + dtype := VARBINARY + if len(v) >= VARBINARY_PREC { + dtype = BLOB + } + bindInParam(stmt, i, int32(dtype), firstRow) + bytes[i], err = G2DB.fromBytes(v, stmt.bindParams[i], stmt.dmConn) + } + case string: + + if v == "" && emptyStringToNil(stmt.serverParams[i].colType) { + arg = nil + goto nextSwitch + } + dtype := VARCHAR + if len(v) >= VARCHAR_PREC { + dtype = CLOB + } + bindInParam(stmt, i, int32(dtype), firstRow) + bytes[i], err = G2DB.fromString(v, stmt.bindParams[i], stmt.dmConn) + case time.Time: + bindInParam(stmt, i, DATETIME, firstRow) + bytes[i], err = G2DB.fromTime(v, stmt.bindParams[i], stmt.dmConn) + case DmTimestamp: + bindInParam(stmt, i, DATETIME, firstRow) + bytes[i], err = G2DB.fromTime(v.ToTime(), stmt.bindParams[i], stmt.dmConn) + case DmIntervalDT: + bindInParam(stmt, i, INTERVAL_DT, firstRow) + if stmt.bindParams[i].typeFlag != TYPE_FLAG_EXACT { + stmt.bindParams[i].scale = int32(v.scaleForSvr) + } + bytes[i], err = G2DB.fromDmIntervalDT(v, stmt.bindParams[i], stmt.dmConn) + case DmIntervalYM: + bindInParam(stmt, i, INTERVAL_YM, firstRow) + if stmt.bindParams[i].typeFlag != TYPE_FLAG_EXACT { + stmt.bindParams[i].scale = int32(v.scaleForSvr) + } + bytes[i], err = G2DB.fromDmdbIntervalYM(v, stmt.bindParams[i], stmt.dmConn) + case DmDecimal: + bindInParam(stmt, i, DECIMAL, firstRow) + bytes[i], err = G2DB.fromDecimal(v, stmt.bindParams[i], stmt.dmConn) + + case DmBlob: + bindInParam(stmt, i, BLOB, firstRow) + bytes[i], err = G2DB.fromBlob(DmBlob(v), stmt.bindParams[i], stmt.dmConn) + if err != nil { + return nil, err + } + case DmClob: + bindInParam(stmt, i, CLOB, firstRow) + bytes[i], err = G2DB.fromClob(DmClob(v), stmt.bindParams[i], stmt.dmConn) + if err != nil { + return nil, err + } + case DmArray: + bindInParam(stmt, i, ARRAY, firstRow) + da := &v + da, err = da.create(stmt.dmConn) + if err != nil { + return nil, err + } + + bytes[i], err = G2DB.fromArray(da, stmt.bindParams[i], stmt.dmConn) + case DmStruct: + bindInParam(stmt, i, CLASS, firstRow) + ds := &v + ds, err = ds.create(stmt.dmConn) + if err != nil { + return nil, err + } + + bytes[i], err = G2DB.fromStruct(ds, stmt.bindParams[i], stmt.dmConn) + case sql.Out: + var cvt = converter{stmt.dmConn, false} + if arg, err = cvt.ConvertValue(v.Dest); err != nil { + return nil, err + } + goto nextSwitch + + case *DmTimestamp: + bindInParam(stmt, i, DATETIME, firstRow) + bytes[i], err = G2DB.fromTime(v.ToTime(), stmt.bindParams[i], stmt.dmConn) + case *DmIntervalDT: + bindInParam(stmt, i, INTERVAL_DT, firstRow) + if stmt.bindParams[i].typeFlag != TYPE_FLAG_EXACT { + stmt.bindParams[i].scale = int32(v.scaleForSvr) + } + bytes[i], err = G2DB.fromDmIntervalDT(*v, stmt.bindParams[i], stmt.dmConn) + case *DmIntervalYM: + bindInParam(stmt, i, INTERVAL_YM, firstRow) + if stmt.bindParams[i].typeFlag != TYPE_FLAG_EXACT { + stmt.bindParams[i].scale = int32(v.scaleForSvr) + } + bytes[i], err = G2DB.fromDmdbIntervalYM(*v, stmt.bindParams[i], stmt.dmConn) + case *DmDecimal: + bindInParam(stmt, i, DECIMAL, firstRow) + bytes[i], err = G2DB.fromDecimal(*v, stmt.bindParams[i], stmt.dmConn) + case *DmBlob: + bindInParam(stmt, i, BLOB, firstRow) + bytes[i], err = G2DB.fromBlob(DmBlob(*v), stmt.bindParams[i], stmt.dmConn) + case *DmClob: + bindInParam(stmt, i, CLOB, firstRow) + bytes[i], err = G2DB.fromClob(DmClob(*v), stmt.bindParams[i], stmt.dmConn) + case *DmArray: + bindInParam(stmt, i, ARRAY, firstRow) + v, err = v.create(stmt.dmConn) + if err != nil { + return nil, err + } + + bytes[i], err = G2DB.fromArray(v, stmt.bindParams[i], stmt.dmConn) + case *DmStruct: + bindInParam(stmt, i, CLASS, firstRow) + v, err = v.create(stmt.dmConn) + if err != nil { + return nil, err + } + + bytes[i], err = G2DB.fromStruct(v, stmt.bindParams[i], stmt.dmConn) + case *driver.Rows: + if stmt.serverParams[i].colType == CURSOR { + bindInParam(stmt, i, CURSOR, firstRow) + if stmt.bindParams[i].cursorStmt == nil { + stmt.bindParams[i].cursorStmt = &DmStatement{dmConn: stmt.dmConn} + stmt.bindParams[i].cursorStmt.resetFilterable(&stmt.dmConn.filterable) + err = stmt.bindParams[i].cursorStmt.dmConn.Access.Dm_build_1406(stmt.bindParams[i].cursorStmt) + } + } + case io.Reader: + bindInParam(stmt, i, stmt.serverParams[i].colType, firstRow) + bytes[i], err = G2DB.fromReader(io.Reader(v), stmt.serverParams[i], stmt.dmConn) + if err != nil { + return nil, err + } + default: + err = ECGO_UNSUPPORTED_INPARAM_TYPE.throw() + } + + if err != nil { + return nil, err + } + + } + checkBindParameters(stmt, bytes) + + 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 *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.serverParams[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, true) + if err != nil { + return err + } + } + stmt.execInfo, err = stmt.dmConn.Access.Dm_build_1456(stmt, bytes, false) + if err != nil { + return err + } + if stmt.execInfo.outParamDatas != nil { + for i, outParamData := range stmt.execInfo.outParamDatas { + if stmt.bindParams[i].ioType == IO_TYPE_IN || stmt.bindParams[i].ioType == IO_TYPE_UNKNOWN { + continue + } + + var v sql.Out + ok := true + for ok { + if v, ok = args[i].(sql.Out); ok { + args[i] = v.Dest + } + } + + if sc, ok := args[i].(sql.Scanner); ok { + var v interface{} + if outParamData == nil && stmt.bindParams[i].colType != CURSOR { + v = nil + if err = sc.Scan(v); err != nil { + return err + } + continue + } + + switch stmt.bindParams[i].colType { + case BOOLEAN: + v, err = DB2G.toBool(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case BIT: + if strings.ToLower(stmt.bindParams[i].typeName) == "boolean" { + v, err = DB2G.toBool(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + } + + v, err = DB2G.toInt8(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case TINYINT: + v, err = DB2G.toInt8(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case SMALLINT: + v, err = DB2G.toInt16(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case INT: + v, err = DB2G.toInt32(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case BIGINT: + v, err = DB2G.toInt64(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case REAL: + v, err = DB2G.toFloat32(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case DOUBLE: + v, err = DB2G.toFloat64(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case DATE, TIME, DATETIME, TIME_TZ, DATETIME_TZ, DATETIME2, DATETIME2_TZ: + v, err = DB2G.toTime(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case INTERVAL_DT: + v = newDmIntervalDTByBytes(outParamData) + case INTERVAL_YM: + v = newDmIntervalYMByBytes(outParamData) + case DECIMAL: + v, err = DB2G.toDmDecimal(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case BINARY, VARBINARY: + v = util.StringUtil.BytesToHexString(outParamData, false) + case BLOB: + v = DB2G.toDmBlob(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case CHAR, VARCHAR2, VARCHAR: + v = DB2G.toString(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case CLOB: + v = DB2G.toDmClob(outParamData, stmt.dmConn, &stmt.bindParams[i].column) + case ARRAY: + v, err = TypeDataSV.bytesToArray(outParamData, nil, stmt.bindParams[i].typeDescriptor) + case CLASS: + v, err = TypeDataSV.bytesToObj(outParamData, nil, stmt.bindParams[i].typeDescriptor) + case CURSOR: + var tmpExecInfo *execRetInfo + if tmpExecInfo, err = stmt.dmConn.Access.Dm_build_1466(stmt.bindParams[i].cursorStmt, 1); err != nil { + return err + } + if tmpExecInfo.hasResultSet { + v = newDmRows(newInnerRows(0, stmt.bindParams[i].cursorStmt, tmpExecInfo)) + } + default: + err = ECGO_UNSUPPORTED_OUTPARAM_TYPE.throw() + } + if err == nil { + err = sc.Scan(v) + } + } else if args[i] == nil { + if outParamData == nil && stmt.bindParams[i].colType != CURSOR { + continue + } + + switch stmt.bindParams[i].colType { + case BOOLEAN: + args[i], err = DB2G.toBool(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case BIT: + if strings.ToLower(stmt.bindParams[i].typeName) == "boolean" { + args[i], err = DB2G.toBool(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + } + + args[i], err = DB2G.toInt8(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case TINYINT: + args[i], err = DB2G.toInt8(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case SMALLINT: + args[i], err = DB2G.toInt16(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case INT: + args[i], err = DB2G.toInt32(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case BIGINT: + args[i], err = DB2G.toInt64(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case REAL: + args[i], err = DB2G.toFloat32(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case DOUBLE: + args[i], err = DB2G.toFloat64(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case DATE, TIME, DATETIME, TIME_TZ, DATETIME_TZ, DATETIME2, DATETIME2_TZ: + args[i], err = DB2G.toTime(outParamData, &stmt.bindParams[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.bindParams[i].column, stmt.dmConn) + case BINARY, VARBINARY: + args[i] = util.StringUtil.BytesToHexString(outParamData, false) + case BLOB: + args[i] = DB2G.toDmBlob(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case CHAR, VARCHAR2, VARCHAR: + args[i] = DB2G.toString(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + case CLOB: + args[i] = DB2G.toDmClob(outParamData, stmt.dmConn, &stmt.bindParams[i].column) + default: + err = ECGO_UNSUPPORTED_OUTPARAM_TYPE.throw() + } + } else { + switch v := args[i].(type) { + case *string: + if outParamData == nil { + *v = "" + } else { + *v = DB2G.toString(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + } + case *sql.NullString: + if outParamData == nil { + v.String = "" + v.Valid = false + } else { + v.String = DB2G.toString(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + v.Valid = true + } + case *[]byte: + if outParamData == nil { + *v = nil + } else { + var val []byte + if val, err = DB2G.toBytes(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = val + } + case *bool: + if outParamData == nil { + *v = false + } else { + var val bool + if val, err = DB2G.toBool(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = val + } + case *sql.NullBool: + if outParamData == nil { + v.Bool = false + v.Valid = false + } else { + var val bool + if val, err = DB2G.toBool(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + v.Bool = val + v.Valid = true + } + case *int8: + if outParamData == nil { + *v = 0 + } else { + var val int8 + if val, err = DB2G.toInt8(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = val + } + case *int16: + if outParamData == nil { + *v = 0 + } else { + var val int16 + if val, err = DB2G.toInt16(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = val + } + case *int32: + if outParamData == nil { + *v = 0 + } else { + var val int32 + if val, err = DB2G.toInt32(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = val + } + case *sql.NullInt32: + if outParamData == nil { + v.Int32 = 0 + v.Valid = false + } else { + var val int32 + if val, err = DB2G.toInt32(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + v.Int32 = val + v.Valid = true + } + case *int64: + if outParamData == nil { + *v = 0 + } else { + var val int64 + if val, err = DB2G.toInt64(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = val + } + case *sql.NullInt64: + if outParamData == nil { + v.Int64 = 0 + v.Valid = false + } else { + var val int64 + if val, err = DB2G.toInt64(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + v.Int64 = val + v.Valid = true + } + case *uint8: + if outParamData == nil { + *v = 0 + } else { + var val uint8 + if val, err = DB2G.toByte(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = val + } + case *uint16: + if outParamData == nil { + *v = 0 + } else { + var val uint16 + if val, err = DB2G.toUInt16(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = val + } + case *uint32: + if outParamData == nil { + *v = 0 + } else { + var val uint32 + if val, err = DB2G.toUInt32(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = val + } + case *uint64: + if outParamData == nil { + *v = 0 + } else { + var val uint64 + if val, err = DB2G.toUInt64(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = val + } + case *int: + if outParamData == nil { + *v = 0 + } else { + var val int + if val, err = DB2G.toInt(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = val + } + case *uint: + if outParamData == nil { + *v = 0 + } else { + var val uint + if val, err = DB2G.toUInt(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = val + } + case *float32: + if outParamData == nil { + *v = 0.0 + } else { + var val float32 + if val, err = DB2G.toFloat32(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = val + } + case *float64: + if outParamData == nil { + *v = 0.0 + } else { + var val float64 + if val, err = DB2G.toFloat64(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = val + } + case *sql.NullFloat64: + if outParamData == nil { + v.Float64 = 0.0 + v.Valid = false + } else { + var val float64 + if val, err = DB2G.toFloat64(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + v.Float64 = val + v.Valid = true + } + case *time.Time: + if outParamData == nil { + *v = time.Time{} + } else { + var val time.Time + if val, err = DB2G.toTime(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = val + } + case *sql.NullTime: + if outParamData == nil { + v.Time = time.Time{} + v.Valid = false + } else { + var val time.Time + if val, err = DB2G.toTime(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + v.Time = val + v.Valid = true + } + case *DmTimestamp: + if outParamData == nil { + *v = DmTimestamp{} + } else { + *v = *newDmTimestampFromBytes(outParamData, stmt.bindParams[i].column, stmt.dmConn) + } + case *DmIntervalDT: + if outParamData == nil { + *v = DmIntervalDT{} + } else { + *v = *newDmIntervalDTByBytes(outParamData) + } + case *DmIntervalYM: + if outParamData == nil { + *v = DmIntervalYM{} + } else { + *v = *newDmIntervalYMByBytes(outParamData) + } + case *DmDecimal: + if outParamData == nil { + *v = DmDecimal{} + } else { + var val *DmDecimal + if val, err = DB2G.toDmDecimal(outParamData, &stmt.bindParams[i].column, stmt.dmConn); err != nil { + return err + } + *v = *val + } + case *DmBlob: + if outParamData == nil { + *v = DmBlob{} + } else { + *v = *DB2G.toDmBlob(outParamData, &stmt.bindParams[i].column, stmt.dmConn) + } + case *DmClob: + if outParamData == nil { + *v = DmClob{} + } else { + *v = *DB2G.toDmClob(outParamData, stmt.dmConn, &stmt.bindParams[i].column) + } + case *driver.Rows: + if stmt.bindParams[i].colType == CURSOR { + var tmpExecInfo *execRetInfo + tmpExecInfo, err = stmt.dmConn.Access.Dm_build_1466(stmt.bindParams[i].cursorStmt, 1) + if err != nil { + return err + } + + if tmpExecInfo.hasResultSet { + *v = newDmRows(newInnerRows(0, stmt.bindParams[i].cursorStmt, tmpExecInfo)) + } else { + *v = nil + } + } + case *DmArray: + if outParamData == nil { + *v = DmArray{} + } else { + var val *DmArray + if val, err = TypeDataSV.bytesToArray(outParamData, nil, stmt.bindParams[i].typeDescriptor); err != nil { + return err + } + *v = *val + } + case *DmStruct: + if outParamData == nil { + *v = DmStruct{} + } else { + var tmp interface{} + if tmp, err = TypeDataSV.bytesToObj(outParamData, nil, stmt.bindParams[i].typeDescriptor); err != nil { + return err + } + if val, ok := tmp.(*DmStruct); ok { + *v = *val + } + } + default: + err = ECGO_UNSUPPORTED_OUTPARAM_TYPE.throw() + } + } + if err != nil { + return err + } + } + + } + return err +} + +func (stmt *DmStatement) executeBatch(args []driver.Value) (err error) { + + var bytes [][]interface{} + + if stmt.execInfo.retSqlType == Dm_build_110 || stmt.execInfo.retSqlType == Dm_build_115 { + 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_111) { + return stmt.executeBatchByRow(args) + } else { + for i, arg := range args { + var newArg []driver.Value + for _, a := range arg.([]interface{}) { + newArg = append(newArg, a) + } + tmpBytes, err := encodeArgs(stmt, newArg, i == 0) + if err != nil { + return err + } + bytes = append(bytes, tmpBytes) + } + stmt.execInfo, err = stmt.dmConn.Access.Dm_build_1445(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_1456(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/vendor/gitee.com/chunanyong/dm/util/zzq.go b/vendor/gitee.com/chunanyong/dm/util/zzq.go new file mode 100644 index 0000000000..00660f265d --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/util/zzr.go b/vendor/gitee.com/chunanyong/dm/util/zzr.go new file mode 100644 index 0000000000..3e6dbb3783 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/util/zzs.go b/vendor/gitee.com/chunanyong/dm/util/zzs.go new file mode 100644 index 0000000000..a575e381be --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/util/zzs.go @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package util + +const ( + LINE_SEPARATOR = "\n" +) + +// 执行f并忽略panic +func AbsorbPanic(f func()){ + defer func() { + if p := recover(); p != nil { + // TODO do something + } + }() + f() +} + +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/vendor/gitee.com/chunanyong/dm/util/zzt.go b/vendor/gitee.com/chunanyong/dm/util/zzt.go new file mode 100644 index 0000000000..e652897e3e --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/v.go b/vendor/gitee.com/chunanyong/dm/v.go new file mode 100644 index 0000000000..3e586e1612 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/v.go @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +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 +} + +// 数据库自定义类型Struct构造函数,typeName为库中定义的类型名称,elements为该类型每个字段的值 +// +// 例如,自定义类型语句为:create or replace type myType as object (a1 int, a2 varchar); +// +// 则绑入绑出的go对象为: val := dm.NewDmStruct("myType", []interface{} {123, "abc"}) +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 { + if dest == nil { + return ECGO_STORE_IN_NIL_POINTER.throw() + } + 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.throw() + } +} + +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 +} + +// 获取Struct对象在数据库中的类型名称 +func (ds *DmStruct) GetSQLTypeName() (string, error) { + return ds.m_strctDesc.m_typeDesc.getFulName() +} + +// 获取Struct对象中的各个字段的值 +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/vendor/gitee.com/chunanyong/dm/w.go b/vendor/gitee.com/chunanyong/dm/w.go new file mode 100644 index 0000000000..e21dd66c58 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/w.go @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +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_NANOSECOND = 6 + + OFFSET_TIMEZONE = 7 + + DT_LEN = 8 + + INVALID_VALUE = int(INT32_MIN) + + NANOSECOND_DIGITS = 9 + + NANOSECOND_POW = 1000000000 +) + +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, column, 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, DATETIME2: + dmts.oracleFormatPattern = conn.FormatTimestamp + case DATETIME_TZ, DATETIME2_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, int32(dmTimestamp.scale), 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 + case string: + ret, err := NewDmTimestampFromString(src) + if err != nil { + return err + } + *dest = *ret + return nil + default: + return UNSUPPORTED_SCAN.throw() + } +} + +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_NANOSECOND]) +} + +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_NANOSECOND] * 1000) +} + +func (dmTimestamp *DmTimestamp) setNano(nano int64) { + dmTimestamp.dt[OFFSET_NANOSECOND] = (int)(nano / 1000) +} + +func (dmTimestamp *DmTimestamp) string() string { + if dmTimestamp.oracleFormatPattern != "" { + return dtToStringByOracleFormat(dmTimestamp.dt, dmTimestamp.oracleFormatPattern, int32(dmTimestamp.scale), 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 +} + +/* for gorm v2 */ +func (d *DmTimestamp) GormDataType() string { + return "TIMESTAMP" +} \ No newline at end of file diff --git a/vendor/gitee.com/chunanyong/dm/x.go b/vendor/gitee.com/chunanyong/dm/x.go new file mode 100644 index 0000000000..b2f6ebf69b --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/x.go @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +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_NORMAL_FIRST: + { + // NORMAL优先: NORMAL>PRIMARY>STANDBY + switch ep.serverMode { + case SERVER_MODE_STANDBY: + sort += SORT_STANDBY + case SERVER_MODE_PRIMARY: + sort += SORT_PRIMARY * 10 + case SERVER_MODE_NORMAL: + sort += SORT_NORMAL * 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/vendor/gitee.com/chunanyong/dm/y.go b/vendor/gitee.com/chunanyong/dm/y.go new file mode 100644 index 0000000000..dcf2f12c8f --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/y.go @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +import ( + "bytes" + "math/rand" + "sync" + "time" + + "gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/z.go b/vendor/gitee.com/chunanyong/dm/z.go new file mode 100644 index 0000000000..7bb3315cfb --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/z.go @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +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/vendor/gitee.com/chunanyong/dm/za.go b/vendor/gitee.com/chunanyong/dm/za.go new file mode 100644 index 0000000000..a73f5ee2af --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/za.go @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +import ( + "bytes" + "fmt" + "runtime" + + "gitee.com/chunanyong/dm/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_UNBINDED_PARAMETER = newDmError(6054, "error.unbindedParameter") + ECGO_PARAM_COUNT_LIMIT = newDmError(6056, "error.ParamCountLimit") + ECGO_INVALID_LENGTH_OR_OFFSET = newDmError(6057, "error.invalidLenOrOffset") + ECGO_CONNECTION_CLOSED = newDmError(6060, "error.error.connectionClosedOrNotBuild") + ECGO_INTERVAL_OVERFLOW = newDmError(6066, "error.intervalValueOverflow") + ECGO_STRING_CUT = newDmError(6067, "error.stringCut") + ECGO_INVALID_HEX = newDmError(6068, "error.invalidHex") + ECGO_INVALID_CIPHER = newDmError(6069, "error.invalidCipher") + ECGO_INVALID_BFILE_STR = newDmError(6070, "error.invalidBFile") + 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) getErrText() string { + return i18n.Get(dmError.ErrText, Locale) +} + +func (dmError *DmError) Error() string { + return fmt.Sprintf("Error %d: %s", dmError.ErrCode, dmError.getErrText()) + 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/vendor/gitee.com/chunanyong/dm/zb.go b/vendor/gitee.com/chunanyong/dm/zb.go new file mode 100644 index 0000000000..ec3ba561b9 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zb.go @@ -0,0 +1,307 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +const ( + PARAM_COUNT_LIMIT int32 = 65536 + + 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_UNKNOWN int8 = -1 + + IO_TYPE_IN int8 = 0 + + IO_TYPE_OUT int8 = 1 + + IO_TYPE_INOUT int8 = 2 + + MASK_ORACLE_DATE int32 = 1 + + MASK_ORACLE_FLOAT int32 = 2 + + MASK_BFILE int32 = 3 + + MASK_LOCAL_DATETIME int32 = 4 +) + +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 + + mask int32 +} + +type parameter struct { + column + + typeFlag byte + + ioType int8 + + outJType int32 + + outScale int32 + + outObjectName string + + cursorStmt *DmStatement + + hasDefault bool +} + +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_UNKNOWN + + parameter.outJType = IGNORE_TARGET_TYPE + + parameter.outScale = IGNORE_TARGET_SCALE + + parameter.outObjectName = "" + + parameter.cursorStmt = nil + + return parameter +} + +func (parameter *parameter) resetType(colType int32) { + parameter.colType = colType + parameter.scale = 0 + switch colType { + case BIT, BOOLEAN: + parameter.prec = BIT_PREC + case TINYINT: + parameter.prec = TINYINT_PREC + case SMALLINT: + parameter.prec = SMALLINT_PREC + case INT: + parameter.prec = INT_PREC + case BIGINT: + parameter.prec = BIGINT_PREC + 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 DATE: + parameter.prec = DATE_PREC + case TIME: + parameter.prec = TIME_PREC + parameter.scale = 6 + case TIME_TZ: + parameter.prec = TIME_TZ_PREC + parameter.scale = 6 + case DATETIME: + parameter.prec = DATETIME_PREC + parameter.scale = 6 + case DATETIME_TZ: + parameter.prec = DATETIME_TZ_PREC + parameter.scale = 6 + case DATETIME2: + parameter.prec = DATETIME2_PREC + parameter.scale = 9 + case DATETIME2_TZ: + parameter.prec = DATETIME2_TZ_PREC + parameter.scale = 9 + case REAL,DOUBLE,DECIMAL,INTERVAL_YM,INTERVAL_DT,ARRAY,CLASS,PLTYPE_RECORD,SARRAY: + parameter.prec = 0 + case UNKNOWN, NULL: + // UNKNOWN 导致服务器断言 // setNull导致服务器报错“字符转换失败” + parameter.colType = VARCHAR + parameter.prec = VARCHAR_PREC + default: + } +} + +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/vendor/gitee.com/chunanyong/dm/zc.go b/vendor/gitee.com/chunanyong/dm/zc.go new file mode 100644 index 0000000000..02573531b9 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zc.go @@ -0,0 +1,444 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +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_935(), + } + 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{}) + f.recoverInfo = newRecoverInfo() + } + + 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/vendor/gitee.com/chunanyong/dm/zd.go b/vendor/gitee.com/chunanyong/dm/zd.go new file mode 100644 index 0000000000..2cf414c0d6 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zd.go @@ -0,0 +1,403 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +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/vendor/gitee.com/chunanyong/dm/ze.go b/vendor/gitee.com/chunanyong/dm/ze.go new file mode 100644 index 0000000000..1cefd189a9 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/ze.go @@ -0,0 +1,907 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +import ( + "context" + "database/sql/driver" + "fmt" + "io" + "reflect" + "strconv" + "time" + + "gitee.com/chunanyong/dm/util" +) + +type logFilter struct{} + +func (filter *logFilter) DmDriverOpen(filterChain *filterChain, d *DmDriver, dsn string) (ret *DmConnection, err error) { + var logRecord = d.logInfo.logRecord.Reset() + 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.Reset() + 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.Reset() + 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.Reset() + logRecord.Set(c, "driver") + 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.Reset() + 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.Reset() + 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.Reset() + 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.Reset() + 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.Reset() + 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.Reset() + 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.Reset() + logRecord.Set(c, "exec", convertParams2(args)...) + defer func() { + filter.executeAfter(c.logInfo, logRecord) + filter.doLog(logRecord) + }() + logRecord.SetSql(query, true) + 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.Reset() + logRecord.Set(c, "execCtx", convertParams1(args)...) + defer func() { + filter.executeAfter(c.logInfo, logRecord) + filter.doLog(logRecord) + }() + logRecord.SetSql(query, true) + 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.Reset() + logRecord.Set(c, "query", convertParams2(args)...) + defer func() { + filter.executeAfter(c.logInfo, logRecord) + filter.doLog(logRecord) + }() + logRecord.SetSql(query, true) + 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.Reset() + logRecord.Set(c, "queryCtx", convertParams1(args)...) + defer func() { + filter.executeAfter(c.logInfo, logRecord) + filter.doLog(logRecord) + }() + logRecord.SetSql(query, true) + 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.Reset() + logRecord.Set(c, "prepare", query) + defer func() { + filter.doLog(logRecord) + }() + logRecord.SetSql(query, false) + 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.Reset() + logRecord.Set(c, "prepareCtx", query) + defer func() { + filter.doLog(logRecord) + }() + logRecord.SetSql(query, false) + 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.Reset() + 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.Reset() + logRecord.Set(c, "checkNamedValue", nv.Value) + 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.Reset() + 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.Reset() + 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.Reset() + logRecord.Set(s, "exec", convertParams2(args)...) + defer func() { + filter.executeAfter(s.logInfo, logRecord) + filter.doLog(logRecord) + }() + logRecord.SetSql(s.nativeSql, true) + 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.Reset() + logRecord.Set(s, "execCtx", convertParams1(args)...) + defer func() { + filter.executeAfter(s.logInfo, logRecord) + filter.doLog(logRecord) + }() + logRecord.SetSql(s.nativeSql, true) + 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.Reset() + logRecord.Set(s, "query", convertParams2(args)...) + defer func() { + filter.executeAfter(s.logInfo, logRecord) + filter.doLog(logRecord) + }() + logRecord.SetSql(s.nativeSql, true) + 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.Reset() + logRecord.Set(s, "queryCtx", convertParams1(args)...) + defer func() { + filter.executeAfter(s.logInfo, logRecord) + filter.doLog(logRecord) + }() + logRecord.SetSql(s.nativeSql, true) + 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.Reset() + logRecord.Set(s, "checkNamedValue", nv.Value) + 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.Reset() + 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.Reset() + 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.Reset() + 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.Reset() + 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.Reset() + logRecord.Set(r, "next", convertParams2(dest)...) + defer func() { + filter.doLog(logRecord) + }() + err = filterChain.DmRowsNext(r, dest) + if err != nil && err != io.EOF { + logRecord.SetError(err) + return + } + return +} + +func (filter *logFilter) DmRowsHasNextResultSet(filterChain *filterChain, r *DmRows) (ret bool) { + var logRecord = r.logInfo.logRecord.Reset() + 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.Reset() + logRecord.Set(r, "nextResultSet") + defer func() { + filter.doLog(logRecord) + }() + err = filterChain.DmRowsNextResultSet(r) + if err != nil && err != io.EOF { + logRecord.SetError(err) + return + } + return +} + +func (filter *logFilter) DmRowsColumnTypeScanType(filterChain *filterChain, r *DmRows, index int) (ret reflect.Type) { + var logRecord = r.logInfo.logRecord.Reset() + 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.Reset() + 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.Reset() + 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.Reset() + 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.Reset() + 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 "driver-" + strconv.FormatInt(driver.getID(), 10) + } + return "driver-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-0x" + strconv.FormatInt(conn.SessionID, 16) + } + return "conn-nil" +} + +func formatStmt(stmt *DmStatement) string { + if stmt != nil && stmt.logInfo != nil { + return "stmt-" + strconv.Itoa(int(stmt.id)) + } + 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, sql 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].(driver.NamedValue); ok { + // str += fmt.Sprintf("%v", s.Value) + //} else { + str += fmt.Sprintf("%v", params[i]) + //} + } + str += "; " + } + + if sql != "" { + str += "[SQL]: " + sql + "; " + } + + return str +} + +func formatReturn(returnObj interface{}) string { + var str string + switch o := returnObj.(type) { + case *DmConnection: + str = formatConn(o) + case *DmStatement: + str = formatStmt(o) + 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 + logSql bool // 是否需要记录sql(exec,query等需要在日志中记录sql语句) +} + +func (record *LogRecord) Reset() *LogRecord { + record.source = "" + record.method = "" + record.params = nil + record.returnValue = nil + record.e = nil + record.usedTime = 0 + record.sql = "" + record.logSql = false + return record +} + +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, logSql bool) { + record.sql = sql + record.logSql = logSql +} + +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 sql string + if record.logSql && record.sql != "" { + sql = record.sql + } + var str string + str += formatTrace(record.source, sql, record.method, record.returnValue, record.params...) + if record.usedTime > 0 { + str += formatUsedTime(record.usedTime) + } + return str +} + +func convertParams1(args []driver.NamedValue) []interface{} { + tmp := make([]interface{}, len(args)) + for i := 0; i < len(tmp); i++ { + tmp[i] = args[i].Value + } + return tmp +} + +func convertParams2(args []driver.Value) []interface{} { + tmp := make([]interface{}, len(args)) + for i := 0; i < len(tmp); i++ { + tmp[i] = args[i] + } + return tmp +} diff --git a/vendor/gitee.com/chunanyong/dm/zf.go b/vendor/gitee.com/chunanyong/dm/zf.go new file mode 100644 index 0000000000..562ae24259 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zf.go @@ -0,0 +1,516 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +import ( + "context" + "database/sql/driver" + "io" + "reflect" + "time" + + "gitee.com/chunanyong/dm/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 || dmErr.ErrCode == ECGO_CONNECTION_CLOSED.ErrCode { + + if connection.dmConnector.driverReconnect { + return rf.reconnect(connection, dmErr.getErrText()) + } else { + connection.Access.Close() + connection.closed.Set(true) + return driver.ErrBadConn + } + } + } + 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 { + connection.closed.Set(true) + return ECGO_CONNECTION_SWITCH_FAILED.addDetailln(reason).throw() + } + + // 重连成功 + connection.closed.Set(false) + 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 + } + + if conn.dmConnector.driverReconnect { + return conn.reconnect() + } else { + conn.Access.Close() + conn.closed.Set(false) + return ECGO_CONNECTION_CLOSED.throw() + } + + //return driver.ErrBadConn + // 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/vendor/gitee.com/chunanyong/dm/zg.go b/vendor/gitee.com/chunanyong/dm/zg.go new file mode 100644 index 0000000000..79efa2121d --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zg.go @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +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/vendor/gitee.com/chunanyong/dm/zh.go b/vendor/gitee.com/chunanyong/dm/zh.go new file mode 100644 index 0000000000..cd74d70169 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zh.go @@ -0,0 +1,607 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +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/vendor/gitee.com/chunanyong/dm/zi.go b/vendor/gitee.com/chunanyong/dm/zi.go new file mode 100644 index 0000000000..d5c83a2462 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zi.go @@ -0,0 +1,1017 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "bytes" + "io" + "math/big" + "strconv" + "strings" + "time" + + "gitee.com/chunanyong/dm/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_650.Dm_build_828(byte(1)), nil + } else { + return Dm_build_650.Dm_build_828(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_650.Dm_build_828(byte(0)), nil + } + + return Dm_build_650.Dm_build_828(byte(1)), nil + + case TINYINT: + err := G2DB.checkTinyint(float64(val)) + + if err != nil { + return nil, err + } + + return Dm_build_650.Dm_build_828(byte(val)), nil + case SMALLINT: + err := G2DB.checkSmallint(float64(val)) + + if err != nil { + return nil, err + } + + return Dm_build_650.Dm_build_834(int16(val)), nil + case INT: + err := G2DB.checkInt(float64(val)) + + if err != nil { + return nil, err + } + + return Dm_build_650.Dm_build_837(int32(val)), nil + case BIGINT: + err := G2DB.checkBigint(float64(val)) + + if err != nil { + return nil, err + } + + return Dm_build_650.Dm_build_840(int64(val)), nil + case REAL: + err := G2DB.checkReal(float64(val)) + + if err != nil { + return nil, err + } + + return Dm_build_650.Dm_build_843(float32(val)), nil + case DOUBLE: + return Dm_build_650.Dm_build_846(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_650.Dm_build_866(strconv.FormatInt(val, 10), conn.getServerEncoding(), conn), nil + case BINARY, VARBINARY, BLOB: + return G2DB.ToBinary(val, int(param.prec)), nil + case DATE, TIME, DATETIME, DATETIME2: + if err := G2DB.checkInt(float64(val)); err != nil { + return nil, err + } + return toDate(val, param.column, *conn) + } + 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_650.Dm_build_828(0), nil + } + return Dm_build_650.Dm_build_828(1), nil + case TINYINT: + if err := G2DB.checkTinyint(float64(val)); err != nil { + return nil, err + } + return Dm_build_650.Dm_build_828(byte(val)), nil + case SMALLINT: + if err := G2DB.checkSmallint(float64(val)); err != nil { + return nil, err + } + return Dm_build_650.Dm_build_834(int16(val)), nil + case INT: + if err := G2DB.checkInt(float64(val)); err != nil { + return nil, err + } + return Dm_build_650.Dm_build_837(int32(val)), nil + case BIGINT: + if err := G2DB.checkBigint(float64(val)); err != nil { + return nil, err + } + return Dm_build_650.Dm_build_840(int64(val)), nil + case REAL: + if err := G2DB.checkReal(float64(val)); err != nil { + return nil, err + } + return Dm_build_650.Dm_build_843(val), nil + case DOUBLE: + return Dm_build_650.Dm_build_846(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_650.Dm_build_866(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_650.Dm_build_828(0), nil + } + return Dm_build_650.Dm_build_828(1), nil + + case TINYINT: + err := G2DB.checkTinyint(val) + + if err != nil { + return nil, err + } + + return Dm_build_650.Dm_build_828(byte(val)), nil + case SMALLINT: + err := G2DB.checkSmallint(val) + + if err != nil { + return nil, err + } + + return Dm_build_650.Dm_build_834(int16(val)), nil + case INT: + err := G2DB.checkInt(val) + + if err != nil { + return nil, err + } + + return Dm_build_650.Dm_build_837(int32(val)), nil + case BIGINT: + err := G2DB.checkBigint(val) + + if err != nil { + return nil, err + } + + return Dm_build_650.Dm_build_840(int64(val)), nil + case REAL: + err := G2DB.checkReal(val) + + if err != nil { + return nil, err + } + + return Dm_build_650.Dm_build_843(float32(val)), nil + case DOUBLE: + return Dm_build_650.Dm_build_846(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_650.Dm_build_866(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_650.Dm_build_828(byte(1)), nil + } else { + return Dm_build_650.Dm_build_828(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 param.mask == MASK_BFILE && !isValidBFileStr(val) { + return nil, ECGO_INVALID_BFILE_STR.throw() + } + return Dm_build_650.Dm_build_866(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, param.column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone)) + } + + return encodeByString(val, param.column, *conn) + case TIME: + if conn.FormatTime != "" { + dt, err := parse(val, conn.FormatTime, int(conn.OracleDateLanguage)) + if err != nil { + return nil, err + } + + return encode(dt, param.column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone)) + } + + return encodeByString(val, param.column, *conn) + case DATETIME, DATETIME2: + if conn.FormatTimestamp != "" { + dt, err := parse(val, conn.FormatTimestamp, int(conn.OracleDateLanguage)) + if err != nil { + return nil, err + } + + return encode(dt, param.column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone)) + } + + return encodeByString(val, param.column, *conn) + case TIME_TZ: + dt, err := parse(val, conn.FormatTimeTZ, int(conn.OracleDateLanguage)) + if err != nil { + return nil, err + } + + if conn.FormatTimeTZ != "" { + return encode(dt, param.column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone)) + } + + return encodeByString(val, param.column, *conn) + case DATETIME_TZ, DATETIME2_TZ: + if conn.FormatTimestampTZ != "" { + dt, err := parse(val, conn.FormatTimestampTZ, int(conn.OracleDateLanguage)) + if err != nil { + return nil, err + } + + return encode(dt, param.column, int(conn.dmConnector.localTimezone), int(conn.DbTimezone)) + } + + return encodeByString(val, param.column, *conn) + 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_650.Dm_build_828(0) + } else { + ret = Dm_build_650.Dm_build_828(1) + } + case TINYINT: + err := G2DB.checkTinyint(float64(val.Int64())) + + if err != nil { + return nil, err + } + + ret = Dm_build_650.Dm_build_828(byte(val.Int64())) + case SMALLINT: + err := G2DB.checkSmallint(float64(val.Int64())) + + if err != nil { + return nil, err + } + + ret = Dm_build_650.Dm_build_834(int16(val.Int64())) + case INT: + err := G2DB.checkInt(float64(val.Int64())) + + if err != nil { + return nil, err + } + + ret = Dm_build_650.Dm_build_837(int32(val.Int64())) + case BIGINT: + err := G2DB.checkBigint(float64(val.Int64())) + + if err != nil { + return nil, err + } + + ret = Dm_build_650.Dm_build_840(val.Int64()) + case REAL: + err := G2DB.checkReal(float64(val.Int64())) + + if err != nil { + return nil, err + } + + ret = Dm_build_650.Dm_build_843(float32(val.Int64())) + case DOUBLE: + ret = Dm_build_650.Dm_build_846(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_650.Dm_build_866(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_650.Dm_build_828(0) + } else { + ret = Dm_build_650.Dm_build_828(1) + } + case TINYINT: + f, _ := val.Float64() + + err := G2DB.checkTinyint(f) + + if err != nil { + return nil, err + } + + ret = Dm_build_650.Dm_build_828(byte(f)) + case SMALLINT: + f, _ := val.Float64() + + err := G2DB.checkSmallint(f) + + if err != nil { + return nil, err + } + + ret = Dm_build_650.Dm_build_834(int16(f)) + case INT: + f, _ := val.Float64() + + err := G2DB.checkInt(f) + + if err != nil { + return nil, err + } + + ret = Dm_build_650.Dm_build_837(int32(f)) + case BIGINT: + f, _ := val.Float64() + + err := G2DB.checkBigint(f) + + if err != nil { + return nil, err + } + + ret = Dm_build_650.Dm_build_840(int64(f)) + case REAL: + f, _ := val.Float64() + + err := G2DB.checkReal(f) + + if err != nil { + return nil, err + } + + ret = Dm_build_650.Dm_build_843(float32(f)) + case DOUBLE: + f, _ := val.Float64() + ret = Dm_build_650.Dm_build_846(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_650.Dm_build_866(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_650.Dm_build_828(0) + } else { + ret = Dm_build_650.Dm_build_828(1) + } + case TINYINT: + if err := G2DB.checkTinyint(val); err != nil { + return nil, err + } + ret = Dm_build_650.Dm_build_828(byte(val.ToBigInt().Int64())) + case SMALLINT: + if err := G2DB.checkSmallint(val); err != nil { + return nil, err + } + ret = Dm_build_650.Dm_build_834(int16(val.ToBigInt().Int64())) + case INT: + if err := G2DB.checkInt(val); err != nil { + return nil, err + } + ret = Dm_build_650.Dm_build_837(int32(val.ToBigInt().Int64())) + case BIGINT: + if err := G2DB.checkBigint(val); err != nil { + return nil, err + } + ret = Dm_build_650.Dm_build_840(int64(val.ToBigInt().Int64())) + case REAL: + if err := G2DB.checkReal(val); err != nil { + return nil, err + } + f, _ := val.ToBigFloat().Float32() + ret = Dm_build_650.Dm_build_843(f) + case DOUBLE: + f, _ := val.ToBigFloat().Float64() + ret = Dm_build_650.Dm_build_846(f) + case DECIMAL: + var err error + ret, err = val.encodeDecimal() + if err != nil { + return nil, err + } + case CHAR, VARCHAR2, VARCHAR, CLOB: + ret = Dm_build_650.Dm_build_866(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, DATETIME2, DATETIME2_TZ: + return encodeByTime(val, param.column, *conn) + case CHAR, VARCHAR2, VARCHAR, CLOB: + return Dm_build_650.Dm_build_866(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_650.Dm_build_866(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_650.Dm_build_866(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_650.Dm_build_866(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_650.Dm_build_866(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_650.Dm_build_866(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_124 +} + +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 string: + val, err := G2DB.fromString(v, param, conn) + if err != nil { + return nil, err + } + 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 int32: + 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_650.Dm_build_866(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_650.Dm_build_666(bytes, 0, val) + return bytes +} + +func (G2DB g2db) toInt64(val int64) []byte { + bytes := make([]byte, 8) + Dm_build_650.Dm_build_671(bytes, 0, val) + return bytes +} + +func (G2DB g2db) toFloat32(val float32) []byte { + bytes := make([]byte, 4) + Dm_build_650.Dm_build_676(bytes, 0, val) + return bytes +} + +func (G2DB g2db) toFloat64(val float64) []byte { + bytes := make([]byte, 8) + Dm_build_650.Dm_build_681(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 isValidBFileStr(s string) bool { + strs := strings.Split(strings.TrimSpace(s), ":") + if len(strs) != 2 { + return false + } + if len(strs[0]) > Dm_build_52 || len(strs[1]) > Dm_build_53 { + return false + } + return true +} diff --git a/vendor/gitee.com/chunanyong/dm/zn.go b/vendor/gitee.com/chunanyong/dm/zn.go new file mode 100644 index 0000000000..8bd0f0c666 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zn.go @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +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_1508(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_650.Dm_build_752(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_650.Dm_build_651(bytes, NBLOB_HEAD_IN_ROW_FLAG, LOB_OFF_ROW) + Dm_build_650.Dm_build_671(bytes, NBLOB_HEAD_BLOBID, lob.blobId) + Dm_build_650.Dm_build_666(bytes, NBLOB_HEAD_BLOB_LEN, -1) + + Dm_build_650.Dm_build_661(bytes, NBLOB_HEAD_OUTROW_GROUPID, lob.groupId) + Dm_build_650.Dm_build_661(bytes, NBLOB_HEAD_OUTROW_FILEID, lob.fileId) + Dm_build_650.Dm_build_666(bytes, NBLOB_HEAD_OUTROW_PAGENO, lob.pageNo) + + if lob.connection.NewLobFlag { + Dm_build_650.Dm_build_666(bytes, NBLOB_EX_HEAD_TABLE_ID, lob.tabId) + Dm_build_650.Dm_build_661(bytes, NBLOB_EX_HEAD_COL_ID, lob.colId) + Dm_build_650.Dm_build_671(bytes, NBLOB_EX_HEAD_ROW_ID, lob.rowId) + Dm_build_650.Dm_build_661(bytes, NBLOB_EX_HEAD_FPA_GRPID, lob.exGroupId) + Dm_build_650.Dm_build_661(bytes, NBLOB_EX_HEAD_FPA_FILEID, lob.exFileId) + Dm_build_650.Dm_build_666(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/vendor/gitee.com/chunanyong/dm/zo.go b/vendor/gitee.com/chunanyong/dm/zo.go new file mode 100644 index 0000000000..14e6c07cc2 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zo.go @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +const ( + ParamDataEnum_Null = 0 + /** + * 只有大字段才有行内数据、行外数据的概念 + */ + ParamDataEnum_OFF_ROW = 1 +) + +// JDBC中的Data +type lobCtl struct { + value []byte +} + +// lob数据返回信息,自bug610335后,服务器不光返回字节数组,还返回字符数 +type lobRetInfo struct { + charLen int64 // 字符长度 + data []byte //lob数据 +} diff --git a/vendor/gitee.com/chunanyong/dm/zp.go b/vendor/gitee.com/chunanyong/dm/zp.go new file mode 100644 index 0000000000..840da3d48c --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zp.go @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "fmt" + "os" + "strconv" + "strings" + "time" + + "gitee.com/chunanyong/dm/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_931 +} + +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_957(ibytes, 0, len(ibytes)) + i++ + } + } + case <-time.After(time.Duration(LogFlushFreq) * time.Millisecond): + if LogLevel != LOG_OFF && lw.buffer.Dm_build_936() > 0 { + lw.doFlush(lw.buffer) + i = 0 + } + + } + + } +} + +func (lw *logWriter) doFlush(buffer *Dm_build_931) { + if lw.needCreateNewFile() { + lw.closeCurrentFile() + lw.logFile = lw.createNewFile() + } + if lw.logFile != nil { + buffer.Dm_build_951(lw.logFile, buffer.Dm_build_936()) + } +} +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 { + fmt.Println(err) + return nil + } + 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_957(ibytes, 0, len(ibytes)) + if lw.buffer.Dm_build_936() >= LogBufferSize { + lw.doFlush(lw.buffer) + } + } + if lw.buffer.Dm_build_936() > 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/vendor/gitee.com/chunanyong/dm/zq.go b/vendor/gitee.com/chunanyong/dm/zq.go new file mode 100644 index 0000000000..05832cca3e --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zq.go @@ -0,0 +1,2949 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "fmt" + "math" + "os" + "strconv" + "strings" + + "gitee.com/chunanyong/dm/util" +) + +const ( + Dm_build_0 = "7.6.0.0" + + Dm_build_1 = "7.0.0.9" + + Dm_build_2 = "8.0.0.73" + + Dm_build_3 = "7.1.2.128" + + Dm_build_4 = "7.1.5.144" + + Dm_build_5 = "7.1.6.123" + + Dm_build_6 = 1 + + Dm_build_7 = 2 + + Dm_build_8 = 3 + + Dm_build_9 = 4 + + Dm_build_10 = 5 + + Dm_build_11 = 6 + + Dm_build_12 = 8 + + Dm_build_13 = Dm_build_12 + + Dm_build_14 = 32768 - 128 + + Dm_build_15 = 0x20000000 + + Dm_build_16 int16 = 1 + + Dm_build_17 int16 = 2 + + Dm_build_18 int16 = 3 + + Dm_build_19 int16 = 4 + + Dm_build_20 int16 = 5 + + Dm_build_21 int16 = 6 + + Dm_build_22 int16 = 7 + + Dm_build_23 int16 = 8 + + Dm_build_24 int16 = 9 + + Dm_build_25 int16 = 13 + + Dm_build_26 int16 = 14 + + Dm_build_27 int16 = 15 + + Dm_build_28 int16 = 17 + + Dm_build_29 int16 = 21 + + Dm_build_30 int16 = 24 + + Dm_build_31 int16 = 27 + + Dm_build_32 int16 = 29 + + Dm_build_33 int16 = 30 + + Dm_build_34 int16 = 31 + + Dm_build_35 int16 = 32 + + Dm_build_36 int16 = 44 + + Dm_build_37 int16 = 52 + + Dm_build_38 int16 = 60 + + Dm_build_39 int16 = 71 + + Dm_build_40 int16 = 90 + + Dm_build_41 int16 = 91 + + Dm_build_42 int16 = 200 + + Dm_build_43 = 64 + + Dm_build_44 = 20 + + Dm_build_45 = 0 + + Dm_build_46 = 4 + + Dm_build_47 = 6 + + Dm_build_48 = 10 + + Dm_build_49 = 14 + + Dm_build_50 = 18 + + Dm_build_51 = 19 + + Dm_build_52 = 128 + + Dm_build_53 = 256 + + Dm_build_54 int32 = 2 + + Dm_build_55 int32 = 5 + + Dm_build_56 = -1 + + Dm_build_57 int32 = 0xFF00 + + Dm_build_58 int32 = 0xFFFE - 3 + + Dm_build_59 int32 = 0xFFFE - 4 + + Dm_build_60 int32 = 0xFFFE + + Dm_build_61 int32 = 0xFFFF + + Dm_build_62 int32 = 0x80 + + Dm_build_63 byte = 0x60 + + Dm_build_64 uint16 = uint16(Dm_build_60) + + Dm_build_65 uint16 = uint16(Dm_build_61) + + Dm_build_66 int16 = 0x00 + + Dm_build_67 int16 = 0x03 + + Dm_build_68 int32 = 0x80 + + Dm_build_69 byte = 0 + + Dm_build_70 byte = 1 + + Dm_build_71 byte = 2 + + Dm_build_72 byte = 3 + + Dm_build_73 byte = 4 + + Dm_build_74 byte = Dm_build_69 + + Dm_build_75 int = 10 + + Dm_build_76 int32 = 32 + + Dm_build_77 int32 = 65536 + + Dm_build_78 byte = 0 + + Dm_build_79 byte = 1 + + Dm_build_80 int32 = 0x00000000 + + Dm_build_81 int32 = 0x00000020 + + Dm_build_82 int32 = 0x00000040 + + Dm_build_83 int32 = 0x00000FFF + + Dm_build_84 int32 = 0 + + Dm_build_85 int32 = 1 + + Dm_build_86 int32 = 2 + + Dm_build_87 int32 = 3 + + Dm_build_88 = 8192 + + Dm_build_89 = 1 + + Dm_build_90 = 2 + + Dm_build_91 = 0 + + Dm_build_92 = 0 + + Dm_build_93 = 1 + + Dm_build_94 = -1 + + Dm_build_95 int16 = 0 + + Dm_build_96 int16 = 1 + + Dm_build_97 int16 = 2 + + Dm_build_98 int16 = 3 + + Dm_build_99 int16 = 4 + + Dm_build_100 int16 = 127 + + Dm_build_101 int16 = Dm_build_100 + 20 + + Dm_build_102 int16 = Dm_build_100 + 21 + + Dm_build_103 int16 = Dm_build_100 + 22 + + Dm_build_104 int16 = Dm_build_100 + 24 + + Dm_build_105 int16 = Dm_build_100 + 25 + + Dm_build_106 int16 = Dm_build_100 + 26 + + Dm_build_107 int16 = Dm_build_100 + 30 + + Dm_build_108 int16 = Dm_build_100 + 31 + + Dm_build_109 int16 = Dm_build_100 + 32 + + Dm_build_110 int16 = Dm_build_100 + 33 + + Dm_build_111 int16 = Dm_build_100 + 35 + + Dm_build_112 int16 = Dm_build_100 + 38 + + Dm_build_113 int16 = Dm_build_100 + 39 + + Dm_build_114 int16 = Dm_build_100 + 51 + + Dm_build_115 int16 = Dm_build_100 + 71 + + Dm_build_116 int16 = Dm_build_100 + 124 + + Dm_build_117 int16 = Dm_build_100 + 125 + + Dm_build_118 int16 = Dm_build_100 + 126 + + Dm_build_119 int16 = Dm_build_100 + 127 + + Dm_build_120 int16 = Dm_build_100 + 128 + + Dm_build_121 int16 = Dm_build_100 + 129 + + Dm_build_122 byte = 0 + + Dm_build_123 byte = 2 + + Dm_build_124 = 2048 + + Dm_build_125 = -1 + + Dm_build_126 = 0 + + Dm_build_127 = 16000 + + Dm_build_128 = 32000 + + Dm_build_129 = 0x00000000 + + Dm_build_130 = 0x00000020 + + Dm_build_131 = 0x00000040 + + Dm_build_132 = 0x00000FFF + + Dm_build_133 = 4 +) + +var Dm_build_134 = [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_135 interface { + dm_build_136() + dm_build_137() error + dm_build_138() + dm_build_139(imsg dm_build_135) error + dm_build_140() error + dm_build_141() (interface{}, error) + dm_build_142() + dm_build_143(imsg dm_build_135) (interface{}, error) + dm_build_144() + dm_build_145() error + dm_build_146() byte + dm_build_147(buffer *Dm_build_1009, startOff int32, endOff int32) uint32 + dm_build_148() int32 + dm_build_149(length int32) + dm_build_150() int16 +} + +type dm_build_151 struct { + dm_build_152 *dm_build_1345 + + dm_build_153 int16 + + dm_build_154 int32 + + dm_build_155 *DmStatement +} + +func (dm_build_157 *dm_build_151) dm_build_156(dm_build_158 *dm_build_1345, dm_build_159 int16) *dm_build_151 { + dm_build_157.dm_build_152 = dm_build_158 + dm_build_157.dm_build_153 = dm_build_159 + return dm_build_157 +} + +func (dm_build_161 *dm_build_151) dm_build_160(dm_build_162 *dm_build_1345, dm_build_163 int16, dm_build_164 *DmStatement) *dm_build_151 { + dm_build_161.dm_build_156(dm_build_162, dm_build_163).dm_build_155 = dm_build_164 + return dm_build_161 +} + +func dm_build_165(dm_build_166 *dm_build_1345, dm_build_167 int16) *dm_build_151 { + return new(dm_build_151).dm_build_156(dm_build_166, dm_build_167) +} + +func dm_build_168(dm_build_169 *dm_build_1345, dm_build_170 int16, dm_build_171 *DmStatement) *dm_build_151 { + return new(dm_build_151).dm_build_160(dm_build_169, dm_build_170, dm_build_171) +} + +func (dm_build_173 *dm_build_151) dm_build_136() { + dm_build_173.dm_build_152.dm_build_1348.Dm_build_1023(0) + dm_build_173.dm_build_152.dm_build_1348.Dm_build_1034(Dm_build_43, true, true) +} + +func (dm_build_175 *dm_build_151) dm_build_137() error { + return nil +} + +func (dm_build_177 *dm_build_151) dm_build_138() { + if dm_build_177.dm_build_155 == nil { + dm_build_177.dm_build_152.dm_build_1348.Dm_build_1204(Dm_build_45, 0) + } else { + dm_build_177.dm_build_152.dm_build_1348.Dm_build_1204(Dm_build_45, dm_build_177.dm_build_155.id) + } + + dm_build_177.dm_build_152.dm_build_1348.Dm_build_1200(Dm_build_46, dm_build_177.dm_build_153) + dm_build_177.dm_build_152.dm_build_1348.Dm_build_1204(Dm_build_47, int32(dm_build_177.dm_build_152.dm_build_1348.Dm_build_1021()-Dm_build_43)) +} + +func (dm_build_179 *dm_build_151) dm_build_140() error { + dm_build_179.dm_build_152.dm_build_1348.Dm_build_1026(0) + dm_build_179.dm_build_152.dm_build_1348.Dm_build_1034(Dm_build_43, false, true) + return dm_build_179.dm_build_184() +} + +func (dm_build_181 *dm_build_151) dm_build_141() (interface{}, error) { + return nil, nil +} + +func (dm_build_183 *dm_build_151) dm_build_142() { +} + +func (dm_build_185 *dm_build_151) dm_build_184() error { + dm_build_185.dm_build_154 = dm_build_185.dm_build_152.dm_build_1348.Dm_build_1282(Dm_build_48) + if dm_build_185.dm_build_154 < 0 && dm_build_185.dm_build_154 != EC_RN_EXCEED_ROWSET_SIZE.ErrCode { + return (&DmError{dm_build_185.dm_build_154, dm_build_185.dm_build_186(), nil, ""}).throw() + } else if dm_build_185.dm_build_154 > 0 { + + } else if dm_build_185.dm_build_153 == Dm_build_42 || dm_build_185.dm_build_153 == Dm_build_16 { + dm_build_185.dm_build_186() + } + + return nil +} + +func (dm_build_187 *dm_build_151) dm_build_186() string { + + dm_build_188 := dm_build_187.dm_build_152.dm_build_1349.getServerEncoding() + + if Locale != LANGUAGE_EN && dm_build_188 == ENCODING_EUCKR { + dm_build_188 = ENCODING_GB18030 + } + + if Locale == LANGUAGE_CNT_HK && dm_build_188 != ENCODING_UTF8 { + dm_build_188 = ENCODING_BIG5 + } + + dm_build_187.dm_build_152.dm_build_1348.Dm_build_1034(int(dm_build_187.dm_build_152.dm_build_1348.Dm_build_1138()), false, true) + + dm_build_187.dm_build_152.dm_build_1348.Dm_build_1034(int(dm_build_187.dm_build_152.dm_build_1348.Dm_build_1138()), false, true) + + dm_build_187.dm_build_152.dm_build_1348.Dm_build_1034(int(dm_build_187.dm_build_152.dm_build_1348.Dm_build_1138()), false, true) + + return dm_build_187.dm_build_152.dm_build_1348.Dm_build_1180(dm_build_188, dm_build_187.dm_build_152.dm_build_1349) +} + +func (dm_build_190 *dm_build_151) dm_build_139(dm_build_191 dm_build_135) (dm_build_192 error) { + dm_build_191.dm_build_136() + if dm_build_192 = dm_build_191.dm_build_137(); dm_build_192 != nil { + return dm_build_192 + } + dm_build_191.dm_build_138() + return nil +} + +func (dm_build_194 *dm_build_151) dm_build_143(dm_build_195 dm_build_135) (dm_build_196 interface{}, dm_build_197 error) { + dm_build_197 = dm_build_195.dm_build_140() + if dm_build_197 != nil { + return nil, dm_build_197 + } + dm_build_196, dm_build_197 = dm_build_195.dm_build_141() + if dm_build_197 != nil { + return nil, dm_build_197 + } + dm_build_195.dm_build_142() + return dm_build_196, nil +} + +func (dm_build_199 *dm_build_151) dm_build_144() { + if dm_build_199.dm_build_152.dm_build_1354 { + + var orgLen = dm_build_199.dm_build_148() + + dm_build_199.dm_build_149(orgLen + Dm_build_133) + var crc = dm_build_199.dm_build_147(dm_build_199.dm_build_152.dm_build_1348, 0, Dm_build_43+orgLen) + dm_build_199.dm_build_152.dm_build_1348.Dm_build_1076(crc) + } else { + dm_build_199.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_51, dm_build_199.dm_build_146()) + } +} + +func (dm_build_201 *dm_build_151) dm_build_145() error { + if dm_build_201.dm_build_152.dm_build_1354 { + + var bodyLen = dm_build_201.dm_build_148() - Dm_build_133 + var msgLen = Dm_build_43 + bodyLen + var recv = dm_build_201.dm_build_152.dm_build_1348.Dm_build_1300(int(msgLen)) + var calc = dm_build_201.dm_build_147(dm_build_201.dm_build_152.dm_build_1348, 0, msgLen) + if recv != calc { + return ECGO_MSG_CHECK_ERROR.throw() + } + + dm_build_201.dm_build_149(bodyLen) + dm_build_201.dm_build_152.dm_build_1348.Dm_build_1023(int(msgLen)) + return nil + } else { + var recv = dm_build_201.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_51) + var calc = dm_build_201.dm_build_146() + if recv != calc { + return ECGO_MSG_CHECK_ERROR.throw() + } + return nil + } +} + +func (dm_build_203 *dm_build_151) dm_build_146() byte { + dm_build_204 := dm_build_203.dm_build_152.dm_build_1348.Dm_build_1276(0) + + for i := 1; i < Dm_build_51; i++ { + dm_build_204 ^= dm_build_203.dm_build_152.dm_build_1348.Dm_build_1276(i) + } + + return dm_build_204 +} + +func (dm_build_206 *dm_build_151) dm_build_147(dm_build_207 *Dm_build_1009, dm_build_208 int32, dm_build_209 int32) uint32 { + + var dm_build_210 uint32 = 0xFFFFFFFF + var dm_build_211 = dm_build_208 + var dm_build_212 = dm_build_209 - dm_build_208 + var dm_build_213, dm_build_214 uint32 + + for dm_build_212 >= 8 { + dm_build_213 = dm_build_207.Dm_build_1300(int(dm_build_211)) ^ dm_build_210 + dm_build_211 += ULINT_SIZE + + dm_build_214 = dm_build_207.Dm_build_1300(int(dm_build_211)) + dm_build_211 += ULINT_SIZE + + dm_build_210 = Dm_build_134[7][dm_build_213&0xFF] ^ Dm_build_134[6][(dm_build_213>>8)&0xFF] ^ + Dm_build_134[5][(dm_build_213>>16)&0xFF] ^ Dm_build_134[4][(dm_build_213>>24)&0xFF] ^ + Dm_build_134[3][dm_build_214&0xFF] ^ Dm_build_134[2][(dm_build_214>>8)&0xFF] ^ + Dm_build_134[1][(dm_build_214>>16)&0xFF] ^ Dm_build_134[0][(dm_build_214>>24)&0xFF] + dm_build_212 -= 8 + } + + for dm_build_212 > 0 { + dm_build_210 = ((dm_build_210 >> 8) & 0x00FFFFFF) ^ Dm_build_134[0][(dm_build_210&0xFF)^uint32(dm_build_207.Dm_build_1294(int(dm_build_211)))] + dm_build_211++ + dm_build_212-- + } + return ^dm_build_210 +} + +func (dm_build_216 *dm_build_151) dm_build_148() int32 { + return dm_build_216.dm_build_152.dm_build_1348.Dm_build_1282(Dm_build_47) +} + +func (dm_build_218 *dm_build_151) dm_build_149(dm_build_219 int32) { + dm_build_218.dm_build_152.dm_build_1348.Dm_build_1204(Dm_build_47, dm_build_219) +} + +func (dm_build_221 *dm_build_151) dm_build_150() int16 { + return dm_build_221.dm_build_153 +} + +type dm_build_222 struct { + dm_build_151 +} + +func dm_build_223(dm_build_224 *dm_build_1345) *dm_build_222 { + dm_build_225 := new(dm_build_222) + dm_build_225.dm_build_156(dm_build_224, Dm_build_23) + return dm_build_225 +} + +type dm_build_226 struct { + dm_build_151 + dm_build_227 string +} + +func dm_build_228(dm_build_229 *dm_build_1345, dm_build_230 *DmStatement, dm_build_231 string) *dm_build_226 { + dm_build_232 := new(dm_build_226) + dm_build_232.dm_build_160(dm_build_229, Dm_build_31, dm_build_230) + dm_build_232.dm_build_227 = dm_build_231 + dm_build_232.dm_build_155.cursorName = dm_build_231 + return dm_build_232 +} + +func (dm_build_234 *dm_build_226) dm_build_137() error { + dm_build_234.dm_build_152.dm_build_1348.Dm_build_1126(dm_build_234.dm_build_227, dm_build_234.dm_build_152.dm_build_1349.getServerEncoding(), dm_build_234.dm_build_152.dm_build_1349) + dm_build_234.dm_build_152.dm_build_1348.Dm_build_1064(1) + return nil +} + +const Dm_build_235 = 62 + +type Dm_build_236 struct { + dm_build_259 + dm_build_237 []OptParameter +} + +func dm_build_238(dm_build_239 *dm_build_1345, dm_build_240 *DmStatement, dm_build_241 []OptParameter) *Dm_build_236 { + dm_build_242 := new(Dm_build_236) + dm_build_242.dm_build_160(dm_build_239, Dm_build_41, dm_build_240) + dm_build_242.dm_build_237 = dm_build_241 + return dm_build_242 +} + +func (dm_build_244 *Dm_build_236) dm_build_137() error { + dm_build_245 := len(dm_build_244.dm_build_237) + + if err := dm_build_244.dm_build_275(int32(dm_build_245), 1); err != nil { + return err + } + dm_build_244.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_235, 0) + + if dm_build_244.dm_build_152.dm_build_1349.MsgVersion >= Dm_build_8 { + dm_build_244.dm_build_290() + dm_build_244.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_257, byte(dm_build_244.dm_build_262)) + } + + dm_build_244.dm_build_152.dm_build_1348.Dm_build_1126(dm_build_244.dm_build_155.nativeSql, dm_build_244.dm_build_155.dmConn.getServerEncoding(), dm_build_244.dm_build_155.dmConn) + + for _, param := range dm_build_244.dm_build_237 { + dm_build_244.dm_build_152.dm_build_1348.Dm_build_1052(param.ioType) + dm_build_244.dm_build_152.dm_build_1348.Dm_build_1064(int32(param.tp)) + dm_build_244.dm_build_152.dm_build_1348.Dm_build_1064(int32(param.prec)) + dm_build_244.dm_build_152.dm_build_1348.Dm_build_1064(int32(param.scale)) + } + + for _, param := range dm_build_244.dm_build_237 { + if param.bytes == nil { + dm_build_244.dm_build_152.dm_build_1348.Dm_build_1072(uint16(Dm_build_60)) + } else { + var dataBytes = param.bytes[:len(param.bytes)] + if len(dataBytes) > int(Dm_build_57) { + if dm_build_244.dm_build_152.dm_build_1349.MsgVersion >= Dm_build_11 && len(dataBytes) < 0xffffffff && + isComplexType(param.tp, param.scale) { + dm_build_244.dm_build_152.dm_build_1348.Dm_build_1072(uint16(Dm_build_61)) + dm_build_244.dm_build_152.dm_build_1348.Dm_build_1096(dataBytes) + continue + } + return ECGO_DATA_TOO_LONG.throw() + } + dm_build_244.dm_build_152.dm_build_1348.Dm_build_1102(dataBytes) + } + } + return nil +} + +func (dm_build_247 *Dm_build_236) dm_build_141() (interface{}, error) { + return dm_build_247.dm_build_259.dm_build_141() +} + +const ( + Dm_build_248 int = 0x01 + + Dm_build_249 int = 0x02 + + Dm_build_250 int = 0x04 + + Dm_build_251 int = 0x08 + + Dm_build_252 int = 0x0100 + + Dm_build_253 int32 = 0x00 + + Dm_build_254 int32 = 0x01 + + Dm_build_255 int32 = 0x02 + + Dm_build_256 int32 = 0x03 + + Dm_build_257 = 48 + + Dm_build_258 = 59 +) + +type dm_build_259 struct { + dm_build_151 + dm_build_260 [][]interface{} + dm_build_261 []parameter + + dm_build_262 int32 + dm_build_263 int32 + dm_build_264 int32 +} + +func dm_build_265(dm_build_266 *dm_build_1345, dm_build_267 int16, dm_build_268 *DmStatement) *dm_build_259 { + dm_build_269 := new(dm_build_259) + dm_build_269.dm_build_160(dm_build_266, dm_build_267, dm_build_268) + + return dm_build_269 +} + +func dm_build_270(dm_build_271 *dm_build_1345, dm_build_272 *DmStatement, dm_build_273 [][]interface{}) *dm_build_259 { + dm_build_274 := new(dm_build_259) + + if dm_build_271.dm_build_1349.Execute2 { + dm_build_274.dm_build_160(dm_build_271, Dm_build_25, dm_build_272) + } else { + dm_build_274.dm_build_160(dm_build_271, Dm_build_21, dm_build_272) + } + + dm_build_274.dm_build_261 = dm_build_272.bindParams + dm_build_274.dm_build_260 = dm_build_273 + + return dm_build_274 +} + +func (dm_build_276 *dm_build_259) dm_build_275(dm_build_277 int32, dm_build_278 int64) error { + + dm_build_279 := Dm_build_44 + + if dm_build_276.dm_build_152.dm_build_1349.autoCommit { + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_279, 1) + } else { + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_279, 0) + } + + if dm_build_277 > PARAM_COUNT_LIMIT { + return ECGO_PARAM_COUNT_LIMIT.throw() + } + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1224(dm_build_279, uint16(dm_build_277)) + + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_279, 1) + + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1208(dm_build_279, dm_build_278) + + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1208(dm_build_279, dm_build_276.dm_build_155.cursorUpdateRow) + + if dm_build_276.dm_build_155.maxRows <= 0 || dm_build_276.dm_build_155.dmConn.dmConnector.enRsCache { + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1208(dm_build_279, INT64_MAX) + } else { + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1208(dm_build_279, dm_build_276.dm_build_155.maxRows) + } + + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_279, 1) + + if dm_build_276.dm_build_152.dm_build_1349.dmConnector.continueBatchOnError { + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_279, 1) + } else { + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_279, 0) + } + + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_279, 0) + + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_279, 0) + + if dm_build_276.dm_build_155.queryTimeout == 0 { + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1204(dm_build_279, -1) + } else { + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1204(dm_build_279, dm_build_276.dm_build_155.queryTimeout) + } + + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1204(dm_build_279, dm_build_276.dm_build_152.dm_build_1349.dmConnector.batchAllowMaxErrors) + + if dm_build_276.dm_build_155.innerExec { + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_279, 1) + } else { + dm_build_279 += dm_build_276.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_279, 0) + } + return nil +} + +func (dm_build_281 *dm_build_259) dm_build_137() error { + var dm_build_282 int32 + var dm_build_283 int64 + + if dm_build_281.dm_build_261 != nil { + dm_build_282 = int32(len(dm_build_281.dm_build_261)) + } else { + dm_build_282 = 0 + } + + if dm_build_281.dm_build_260 != nil { + dm_build_283 = int64(len(dm_build_281.dm_build_260)) + } else { + dm_build_283 = 0 + } + + if err := dm_build_281.dm_build_275(dm_build_282, dm_build_283); err != nil { + return err + } + + if dm_build_281.dm_build_152.dm_build_1349.MsgVersion >= Dm_build_8 { + dm_build_281.dm_build_290() + dm_build_281.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_257, byte(dm_build_281.dm_build_262)) + } + + if dm_build_282 > 0 { + err := dm_build_281.dm_build_284(dm_build_281.dm_build_261) + if err != nil { + return err + } + if dm_build_281.dm_build_260 != nil && len(dm_build_281.dm_build_260) > 0 { + for _, paramObject := range dm_build_281.dm_build_260 { + if err := dm_build_281.dm_build_287(paramObject); err != nil { + return err + } + } + } + } + + return nil +} + +func (dm_build_285 *dm_build_259) dm_build_284(dm_build_286 []parameter) error { + for _, param := range dm_build_286 { + if param.mask == MASK_ORACLE_DATE { + + param.scale = param.scale | ORACLE_DATE_SCALE_MASK + } else if param.mask == MASK_LOCAL_DATETIME { + + param.scale = param.scale | LOCAL_DATETIME_SCALE_MASK + } else if param.mask == MASK_ORACLE_FLOAT { + + param.prec = int32(math.Round(float64(param.prec) * 3.32193)) + param.scale = ORACLE_FLOAT_SCALE_MASK + } + + if param.colType == CURSOR && param.ioType == IO_TYPE_OUT { + dm_build_285.dm_build_152.dm_build_1348.Dm_build_1056(IO_TYPE_INOUT) + } else { + dm_build_285.dm_build_152.dm_build_1348.Dm_build_1056(param.ioType) + } + + dm_build_285.dm_build_152.dm_build_1348.Dm_build_1064(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_285.dm_build_152.dm_build_1348.Dm_build_1064(lprec) + + dm_build_285.dm_build_152.dm_build_1348.Dm_build_1064(lscale) + + switch param.colType { + case ARRAY, SARRAY: + err := packArray(typeDesc, dm_build_285.dm_build_152.dm_build_1348) + if err != nil { + return err + } + + case PLTYPE_RECORD: + err := packRecord(typeDesc, dm_build_285.dm_build_152.dm_build_1348) + if err != nil { + return err + } + + case CLASS: + err := packClass(typeDesc, dm_build_285.dm_build_152.dm_build_1348) + if err != nil { + return err + } + + } + } + + return nil +} + +func (dm_build_288 *dm_build_259) dm_build_287(dm_build_289 []interface{}) error { + for i := 0; i < len(dm_build_288.dm_build_261); i++ { + + if dm_build_288.dm_build_261[i].colType == CURSOR { + dm_build_288.dm_build_152.dm_build_1348.Dm_build_1060(ULINT_SIZE) + dm_build_288.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_288.dm_build_261[i].cursorStmt.id) + continue + } + + if dm_build_288.dm_build_261[i].ioType == IO_TYPE_OUT { + continue + } + + if dm_build_289[i] == nil { + dm_build_288.dm_build_152.dm_build_1348.Dm_build_1072(uint16(Dm_build_60)) + } else { + switch dm_build_289[i].(type) { + case []byte: + if dataBytes, ok := dm_build_289[i].([]byte); ok { + if len(dataBytes) > int(Dm_build_57) { + if dm_build_288.dm_build_152.dm_build_1349.MsgVersion >= Dm_build_11 && len(dataBytes) < 0xffffffff && + isComplexType(int(dm_build_288.dm_build_261[i].colType), int(dm_build_288.dm_build_261[i].scale)) { + dm_build_288.dm_build_152.dm_build_1348.Dm_build_1072(uint16(Dm_build_61)) + dm_build_288.dm_build_152.dm_build_1348.Dm_build_1096(dataBytes) + continue + } + return ECGO_DATA_TOO_LONG.throw() + } + dm_build_288.dm_build_152.dm_build_1348.Dm_build_1102(dataBytes) + } + case int: + if dm_build_289[i] == ParamDataEnum_Null { + dm_build_288.dm_build_152.dm_build_1348.Dm_build_1072(uint16(Dm_build_60)) + } else if dm_build_289[i] == ParamDataEnum_OFF_ROW { + dm_build_288.dm_build_152.dm_build_1348.Dm_build_1060(0) + } + case lobCtl: + dm_build_288.dm_build_152.dm_build_1348.Dm_build_1072(uint16(Dm_build_58)) + dm_build_288.dm_build_152.dm_build_1348.Dm_build_1092(dm_build_289[i].(lobCtl).value) + default: + return fmt.Errorf("Bind param data failed by invalid param data type: ") + } + } + } + + return nil +} + +func (dm_build_291 *dm_build_259) dm_build_290() int32 { + dm_build_291.dm_build_262 = Dm_build_254 + dm_build_291.dm_build_263 = 1 + return dm_build_291.dm_build_262 +} + +func (dm_build_293 *dm_build_259) dm_build_141() (interface{}, error) { + dm_build_294 := execRetInfo{} + dm_build_295 := dm_build_293.dm_build_155.dmConn + + dm_build_296 := Dm_build_44 + + dm_build_294.retSqlType = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1279(dm_build_296) + dm_build_296 += USINT_SIZE + + dm_build_297 := dm_build_293.dm_build_152.dm_build_1348.Dm_build_1279(dm_build_296) + dm_build_296 += USINT_SIZE + + dm_build_294.updateCount = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1285(dm_build_296) + dm_build_296 += DDWORD_SIZE + + dm_build_298 := dm_build_293.dm_build_152.dm_build_1348.Dm_build_1297(dm_build_296) + dm_build_296 += USINT_SIZE + + dm_build_294.rsUpdatable = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1276(dm_build_296) != 0 + dm_build_296 += BYTE_SIZE + + dm_build_299 := dm_build_293.dm_build_152.dm_build_1348.Dm_build_1279(dm_build_296) + dm_build_296 += ULINT_SIZE + + dm_build_294.printLen = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1282(dm_build_296) + dm_build_296 += ULINT_SIZE + + var dm_build_300 int16 = -1 + if dm_build_294.retSqlType == Dm_build_110 || dm_build_294.retSqlType == Dm_build_111 { + dm_build_294.rowid = 0 + + dm_build_294.rsBdta = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1276(dm_build_296) == Dm_build_123 + dm_build_296 += BYTE_SIZE + + dm_build_300 = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1279(dm_build_296) + dm_build_296 += USINT_SIZE + dm_build_296 += 5 + } else { + dm_build_294.rowid = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1285(dm_build_296) + dm_build_296 += DDWORD_SIZE + } + + dm_build_294.execId = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1282(dm_build_296) + dm_build_296 += ULINT_SIZE + + dm_build_294.rsCacheOffset = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1282(dm_build_296) + dm_build_296 += ULINT_SIZE + + dm_build_301 := dm_build_293.dm_build_152.dm_build_1348.Dm_build_1276(dm_build_296) + dm_build_296 += BYTE_SIZE + dm_build_302 := (dm_build_301 & 0x01) == 0x01 + + dm_build_295.TrxStatus = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1282(dm_build_296) + dm_build_295.setTrxFinish(dm_build_295.TrxStatus) + dm_build_296 += ULINT_SIZE + + if dm_build_294.printLen > 0 { + bytes := dm_build_293.dm_build_152.dm_build_1348.Dm_build_1159(int(dm_build_294.printLen)) + dm_build_294.printMsg = Dm_build_650.Dm_build_807(bytes, 0, len(bytes), dm_build_295.getServerEncoding(), dm_build_295) + } + + if dm_build_298 > 0 { + dm_build_294.outParamDatas = dm_build_293.dm_build_303(int(dm_build_298)) + } + + switch dm_build_294.retSqlType { + case Dm_build_112: + dm_build_295.dmConnector.localTimezone = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1135() + case Dm_build_110: + dm_build_294.hasResultSet = true + if dm_build_297 > 0 { + dm_build_293.dm_build_155.columns = dm_build_293.dm_build_312(int(dm_build_297), dm_build_294.rsBdta) + } + dm_build_293.dm_build_322(&dm_build_294, len(dm_build_293.dm_build_155.columns), int(dm_build_299), int(dm_build_300)) + case Dm_build_111: + if dm_build_297 > 0 || dm_build_299 > 0 { + dm_build_294.hasResultSet = true + } + if dm_build_297 > 0 { + dm_build_293.dm_build_155.columns = dm_build_293.dm_build_312(int(dm_build_297), dm_build_294.rsBdta) + } + dm_build_293.dm_build_322(&dm_build_294, len(dm_build_293.dm_build_155.columns), int(dm_build_299), int(dm_build_300)) + case Dm_build_113: + dm_build_295.IsoLevel = int32(dm_build_293.dm_build_152.dm_build_1348.Dm_build_1135()) + dm_build_295.ReadOnly = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1132() == 1 + case Dm_build_106: + dm_build_295.Schema = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1180(dm_build_295.getServerEncoding(), dm_build_295) + case Dm_build_103: + dm_build_294.explain = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1180(dm_build_295.getServerEncoding(), dm_build_295) + + case Dm_build_107, Dm_build_109, Dm_build_108: + if dm_build_302 { + + counts := dm_build_293.dm_build_152.dm_build_1348.Dm_build_1138() + rowCounts := make([]int64, counts) + for i := 0; i < int(counts); i++ { + rowCounts[i] = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1141() + } + dm_build_294.updateCounts = rowCounts + } + + dm_build_293.dm_build_334(&dm_build_294) + + if dm_build_293.dm_build_154 == EC_BP_WITH_ERROR.ErrCode { + dm_build_293.dm_build_328(dm_build_294.updateCounts) + } + case Dm_build_116: + len := dm_build_293.dm_build_152.dm_build_1348.Dm_build_1150() + dm_build_295.FormatDate = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1175(int(len), dm_build_295.getServerEncoding(), dm_build_295) + case Dm_build_118: + + len := dm_build_293.dm_build_152.dm_build_1348.Dm_build_1150() + dm_build_295.FormatTimestamp = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1175(int(len), dm_build_295.getServerEncoding(), dm_build_295) + case Dm_build_119: + + len := dm_build_293.dm_build_152.dm_build_1348.Dm_build_1150() + dm_build_295.FormatTimestampTZ = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1175(int(len), dm_build_295.getServerEncoding(), dm_build_295) + case Dm_build_117: + len := dm_build_293.dm_build_152.dm_build_1348.Dm_build_1150() + dm_build_295.FormatTime = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1175(int(len), dm_build_295.getServerEncoding(), dm_build_295) + case Dm_build_120: + len := dm_build_293.dm_build_152.dm_build_1348.Dm_build_1150() + dm_build_295.FormatTimeTZ = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1175(int(len), dm_build_295.getServerEncoding(), dm_build_295) + case Dm_build_121: + dm_build_295.OracleDateLanguage = dm_build_293.dm_build_152.dm_build_1348.Dm_build_1150() + } + + return &dm_build_294, nil +} + +func (dm_build_304 *dm_build_259) dm_build_303(dm_build_305 int) [][]byte { + dm_build_306 := make([]int, dm_build_305) + + dm_build_307 := 0 + for i := 0; i < len(dm_build_304.dm_build_261); i++ { + if dm_build_304.dm_build_261[i].ioType == IO_TYPE_INOUT || dm_build_304.dm_build_261[i].ioType == IO_TYPE_OUT { + dm_build_306[dm_build_307] = i + dm_build_307++ + } + } + + dm_build_308 := make([][]byte, len(dm_build_304.dm_build_261)) + var dm_build_309 int32 + var dm_build_310 bool + var dm_build_311 []byte = nil + for i := 0; i < dm_build_305; i++ { + dm_build_310 = false + dm_build_309 = int32(dm_build_304.dm_build_152.dm_build_1348.Dm_build_1153()) + + if dm_build_309 == int32(Dm_build_60) { + dm_build_309 = 0 + dm_build_310 = true + } else if dm_build_309 == int32(Dm_build_61) { + dm_build_309 = dm_build_304.dm_build_152.dm_build_1348.Dm_build_1138() + } + + if dm_build_310 { + dm_build_308[dm_build_306[i]] = nil + } else { + dm_build_311 = dm_build_304.dm_build_152.dm_build_1348.Dm_build_1159(int(dm_build_309)) + dm_build_308[dm_build_306[i]] = dm_build_311 + } + } + + return dm_build_308 +} + +func (dm_build_313 *dm_build_259) dm_build_312(dm_build_314 int, dm_build_315 bool) []column { + dm_build_316 := dm_build_313.dm_build_152.dm_build_1349.getServerEncoding() + var dm_build_317, dm_build_318, dm_build_319, dm_build_320 int16 + dm_build_321 := make([]column, dm_build_314) + for i := 0; i < dm_build_314; i++ { + dm_build_321[i].InitColumn() + + dm_build_321[i].colType = dm_build_313.dm_build_152.dm_build_1348.Dm_build_1138() + + dm_build_321[i].prec = dm_build_313.dm_build_152.dm_build_1348.Dm_build_1138() + + dm_build_321[i].scale = dm_build_313.dm_build_152.dm_build_1348.Dm_build_1138() + + dm_build_321[i].nullable = dm_build_313.dm_build_152.dm_build_1348.Dm_build_1138() != 0 + + itemFlag := dm_build_313.dm_build_152.dm_build_1348.Dm_build_1135() + dm_build_321[i].lob = int(itemFlag)&Dm_build_249 != 0 + dm_build_321[i].identity = int(itemFlag)&Dm_build_248 != 0 + dm_build_321[i].readonly = int(itemFlag)&Dm_build_250 != 0 + + dm_build_313.dm_build_152.dm_build_1348.Dm_build_1034(4, false, true) + + dm_build_313.dm_build_152.dm_build_1348.Dm_build_1034(2, false, true) + + dm_build_317 = dm_build_313.dm_build_152.dm_build_1348.Dm_build_1135() + + dm_build_318 = dm_build_313.dm_build_152.dm_build_1348.Dm_build_1135() + + dm_build_319 = dm_build_313.dm_build_152.dm_build_1348.Dm_build_1135() + + dm_build_320 = dm_build_313.dm_build_152.dm_build_1348.Dm_build_1135() + dm_build_321[i].name = dm_build_313.dm_build_152.dm_build_1348.Dm_build_1175(int(dm_build_317), dm_build_316, dm_build_313.dm_build_152.dm_build_1349) + dm_build_321[i].typeName = dm_build_313.dm_build_152.dm_build_1348.Dm_build_1175(int(dm_build_318), dm_build_316, dm_build_313.dm_build_152.dm_build_1349) + dm_build_321[i].tableName = dm_build_313.dm_build_152.dm_build_1348.Dm_build_1175(int(dm_build_319), dm_build_316, dm_build_313.dm_build_152.dm_build_1349) + dm_build_321[i].schemaName = dm_build_313.dm_build_152.dm_build_1348.Dm_build_1175(int(dm_build_320), dm_build_316, dm_build_313.dm_build_152.dm_build_1349) + + if dm_build_313.dm_build_155.readBaseColName { + dm_build_321[i].baseName = dm_build_313.dm_build_152.dm_build_1348.Dm_build_1188(dm_build_316, dm_build_313.dm_build_152.dm_build_1349) + } + + if dm_build_321[i].lob { + dm_build_321[i].lobTabId = dm_build_313.dm_build_152.dm_build_1348.Dm_build_1138() + dm_build_321[i].lobColId = dm_build_313.dm_build_152.dm_build_1348.Dm_build_1135() + } + + if dm_build_321[i].colType == DATETIME || dm_build_321[i].colType == DATETIME2 { + if (dm_build_321[i].scale & LOCAL_DATETIME_SCALE_MASK) != 0 { + + dm_build_321[i].scale = dm_build_321[i].scale & ^LOCAL_DATETIME_SCALE_MASK + dm_build_321[i].mask = MASK_LOCAL_DATETIME + } else if (dm_build_321[i].scale & ORACLE_DATE_SCALE_MASK) != 0 { + + dm_build_321[i].scale = dm_build_321[i].scale & ^ORACLE_DATE_SCALE_MASK + dm_build_321[i].mask = MASK_ORACLE_DATE + } + } + + if dm_build_321[i].colType == DECIMAL && dm_build_321[i].scale == ORACLE_FLOAT_SCALE_MASK { + dm_build_321[i].prec = int32(math.Round(float64(dm_build_321[i].prec)*0.30103) + 1) + dm_build_321[i].scale = -1 + dm_build_321[i].mask = MASK_ORACLE_FLOAT + } + + if dm_build_321[i].colType == VARCHAR && dm_build_321[i].prec == BFILE_PREC && dm_build_321[i].scale == BFILE_SCALE { + dm_build_321[i].mask = MASK_BFILE + } + } + + for i := 0; i < dm_build_314; i++ { + + if isComplexType(int(dm_build_321[i].colType), int(dm_build_321[i].scale)) { + strDesc := newTypeDescriptor(dm_build_313.dm_build_152.dm_build_1349) + strDesc.unpack(dm_build_313.dm_build_152.dm_build_1348) + dm_build_321[i].typeDescriptor = strDesc + } + } + + return dm_build_321 +} + +func (dm_build_323 *dm_build_259) dm_build_322(dm_build_324 *execRetInfo, dm_build_325 int, dm_build_326 int, dm_build_327 int) { + if dm_build_326 > 0 { + startOffset := dm_build_323.dm_build_152.dm_build_1348.Dm_build_1029() + if dm_build_324.rsBdta { + dm_build_324.rsDatas = dm_build_323.dm_build_347(dm_build_323.dm_build_155.columns, dm_build_327) + } else { + datas := make([][][]byte, dm_build_326) + + for i := 0; i < dm_build_326; i++ { + + datas[i] = make([][]byte, dm_build_325+1) + + dm_build_323.dm_build_152.dm_build_1348.Dm_build_1034(2, false, true) + + datas[i][0] = dm_build_323.dm_build_152.dm_build_1348.Dm_build_1159(LINT64_SIZE) + + dm_build_323.dm_build_152.dm_build_1348.Dm_build_1034(2*dm_build_325, false, true) + + for j := 1; j < dm_build_325+1; j++ { + + colLen := dm_build_323.dm_build_152.dm_build_1348.Dm_build_1153() + if colLen == Dm_build_64 { + datas[i][j] = nil + } else if colLen != Dm_build_65 { + datas[i][j] = dm_build_323.dm_build_152.dm_build_1348.Dm_build_1159(int(colLen)) + } else { + datas[i][j] = dm_build_323.dm_build_152.dm_build_1348.Dm_build_1163() + } + } + } + + dm_build_324.rsDatas = datas + } + dm_build_324.rsSizeof = dm_build_323.dm_build_152.dm_build_1348.Dm_build_1029() - startOffset + } + + if dm_build_324.rsCacheOffset > 0 { + tbCount := dm_build_323.dm_build_152.dm_build_1348.Dm_build_1135() + + ids := make([]int32, tbCount) + tss := make([]int64, tbCount) + + for i := 0; i < int(tbCount); i++ { + ids[i] = dm_build_323.dm_build_152.dm_build_1348.Dm_build_1138() + tss[i] = dm_build_323.dm_build_152.dm_build_1348.Dm_build_1141() + } + + dm_build_324.tbIds = ids[:] + dm_build_324.tbTss = tss[:] + } +} + +func (dm_build_329 *dm_build_259) dm_build_328(dm_build_330 []int64) error { + + dm_build_329.dm_build_152.dm_build_1348.Dm_build_1034(4, false, true) + + dm_build_331 := dm_build_329.dm_build_152.dm_build_1348.Dm_build_1138() + + dm_build_332 := dm_build_329.dm_build_152.dm_build_1349.getServerEncoding() + + if Locale != LANGUAGE_EN && dm_build_332 == ENCODING_EUCKR { + dm_build_332 = ENCODING_GB18030 + } + + if Locale == LANGUAGE_CNT_HK && dm_build_332 != ENCODING_UTF8 { + dm_build_332 = ENCODING_BIG5 + } + + dm_build_333 := make([]string, 0, 8) + for i := 0; i < int(dm_build_331); i++ { + irow := dm_build_329.dm_build_152.dm_build_1348.Dm_build_1138() + + dm_build_330[irow] = -3 + + code := dm_build_329.dm_build_152.dm_build_1348.Dm_build_1138() + + errStr := dm_build_329.dm_build_152.dm_build_1348.Dm_build_1188(dm_build_332, dm_build_329.dm_build_152.dm_build_1349) + + dm_build_333 = append(dm_build_333, "row["+strconv.Itoa(int(irow))+"]:"+strconv.Itoa(int(code))+", "+errStr) + } + + if len(dm_build_333) > 0 { + builder := &strings.Builder{} + for _, str := range dm_build_333 { + builder.WriteString(util.LINE_SEPARATOR) + builder.WriteString(str) + } + EC_BP_WITH_ERROR.ErrText += builder.String() + return EC_BP_WITH_ERROR.throw() + } + return nil +} + +func (dm_build_335 *dm_build_259) dm_build_334(dm_build_336 *execRetInfo) error { + dm_build_337 := dm_build_335.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_258) + dm_build_338 := (dm_build_337 & 0x02) == 0x02 + if !dm_build_338 { + + if dm_build_336.updateCount == 1 { + + dm_build_336.lastInsertId = dm_build_336.rowid + } + return nil + } + + if dm_build_335.dm_build_152.dm_build_1349.MsgVersion < Dm_build_8 || dm_build_335.dm_build_262 == Dm_build_254 { + + rows := dm_build_335.dm_build_152.dm_build_1348.Dm_build_1138() + var lastInsertId int64 + for i := 0; i < int(rows); i++ { + lastInsertId = dm_build_335.dm_build_152.dm_build_1348.Dm_build_1141() + } + dm_build_336.lastInsertId = lastInsertId + } else { + + } + + return nil +} + +const ( + Dm_build_339 = 0 + + Dm_build_340 = Dm_build_339 + ULINT_SIZE + + Dm_build_341 = Dm_build_340 + USINT_SIZE + + Dm_build_342 = Dm_build_341 + ULINT_SIZE + + Dm_build_343 = Dm_build_342 + ULINT_SIZE + + Dm_build_344 = Dm_build_343 + BYTE_SIZE + + Dm_build_345 = -2 + + Dm_build_346 = -3 +) + +func (dm_build_348 *dm_build_259) dm_build_347(dm_build_349 []column, dm_build_350 int) [][][]byte { + + dm_build_351 := dm_build_348.dm_build_152.dm_build_1348.Dm_build_1156() + + dm_build_352 := dm_build_348.dm_build_152.dm_build_1348.Dm_build_1153() + + var dm_build_353 bool + + if dm_build_350 >= 0 && int(dm_build_352) == len(dm_build_349)+1 { + dm_build_353 = true + } else { + dm_build_353 = false + } + + dm_build_348.dm_build_152.dm_build_1348.Dm_build_1034(ULINT_SIZE, false, true) + + dm_build_348.dm_build_152.dm_build_1348.Dm_build_1034(ULINT_SIZE, false, true) + + dm_build_348.dm_build_152.dm_build_1348.Dm_build_1034(BYTE_SIZE, false, true) + + dm_build_354 := make([]uint16, dm_build_352) + for icol := 0; icol < int(dm_build_352); icol++ { + dm_build_354[icol] = dm_build_348.dm_build_152.dm_build_1348.Dm_build_1153() + } + + dm_build_355 := make([]uint32, dm_build_352) + dm_build_356 := make([][][]byte, dm_build_351) + + for i := uint32(0); i < dm_build_351; i++ { + dm_build_356[i] = make([][]byte, len(dm_build_349)+1) + } + + for icol := 0; icol < int(dm_build_352); icol++ { + dm_build_355[icol] = dm_build_348.dm_build_152.dm_build_1348.Dm_build_1156() + } + + for icol := 0; icol < int(dm_build_352); icol++ { + + dataCol := icol + 1 + if dm_build_353 && icol == dm_build_350 { + dataCol = 0 + } else if dm_build_353 && icol > dm_build_350 { + dataCol = icol + } + + allNotNull := dm_build_348.dm_build_152.dm_build_1348.Dm_build_1138() == 1 + var isNull []bool = nil + if !allNotNull { + isNull = make([]bool, dm_build_351) + for irow := uint32(0); irow < dm_build_351; irow++ { + isNull[irow] = dm_build_348.dm_build_152.dm_build_1348.Dm_build_1132() == 0 + } + } + + for irow := uint32(0); irow < dm_build_351; irow++ { + if allNotNull || !isNull[irow] { + dm_build_356[irow][dataCol] = dm_build_348.dm_build_357(int(dm_build_354[icol])) + } + } + } + + if !dm_build_353 && dm_build_350 >= 0 { + for irow := uint32(0); irow < dm_build_351; irow++ { + dm_build_356[irow][0] = dm_build_356[irow][dm_build_350+1] + } + } + + return dm_build_356 +} + +func (dm_build_358 *dm_build_259) dm_build_357(dm_build_359 int) []byte { + + dm_build_360 := dm_build_358.dm_build_363(dm_build_359) + + dm_build_361 := int32(0) + if dm_build_360 == Dm_build_345 { + dm_build_361 = dm_build_358.dm_build_152.dm_build_1348.Dm_build_1138() + dm_build_360 = int(dm_build_358.dm_build_152.dm_build_1348.Dm_build_1138()) + } else if dm_build_360 == Dm_build_346 { + dm_build_360 = int(dm_build_358.dm_build_152.dm_build_1348.Dm_build_1138()) + } + + dm_build_362 := dm_build_358.dm_build_152.dm_build_1348.Dm_build_1159(dm_build_360 + int(dm_build_361)) + if dm_build_361 == 0 { + return dm_build_362 + } + + for i := dm_build_360; i < len(dm_build_362); i++ { + dm_build_362[i] = ' ' + } + return dm_build_362 +} + +func (dm_build_364 *dm_build_259) dm_build_363(dm_build_365 int) int { + + dm_build_366 := 0 + switch dm_build_365 { + case INT, BIT, TINYINT, SMALLINT, BOOLEAN, NULL: + dm_build_366 = 4 + + case BIGINT: + + dm_build_366 = 8 + + case CHAR, VARCHAR2, VARCHAR, BINARY, VARBINARY, BLOB, CLOB: + dm_build_366 = Dm_build_345 + + case DECIMAL: + dm_build_366 = Dm_build_346 + + case REAL: + dm_build_366 = 4 + + case DOUBLE: + dm_build_366 = 8 + + case DATE, TIME, DATETIME, TIME_TZ, DATETIME_TZ: + dm_build_366 = 12 + + case DATETIME2, DATETIME2_TZ: + dm_build_366 = 13 + + case INTERVAL_YM: + dm_build_366 = 12 + + case INTERVAL_DT: + dm_build_366 = 24 + + default: + dm_build_366 = 0 + } + return dm_build_366 +} + +const ( + Dm_build_367 = Dm_build_44 + + Dm_build_368 = Dm_build_367 + DDWORD_SIZE + + Dm_build_369 = Dm_build_368 + LINT64_SIZE + + Dm_build_370 = Dm_build_369 + USINT_SIZE + + Dm_build_371 = Dm_build_44 + + Dm_build_372 = Dm_build_371 + DDWORD_SIZE +) + +type dm_build_373 struct { + dm_build_259 + dm_build_374 *innerRows + dm_build_375 int64 + dm_build_376 int64 +} + +func dm_build_377(dm_build_378 *dm_build_1345, dm_build_379 *innerRows, dm_build_380 int64, dm_build_381 int64) *dm_build_373 { + dm_build_382 := new(dm_build_373) + dm_build_382.dm_build_160(dm_build_378, Dm_build_22, dm_build_379.dmStmt) + dm_build_382.dm_build_374 = dm_build_379 + dm_build_382.dm_build_375 = dm_build_380 + dm_build_382.dm_build_376 = dm_build_381 + return dm_build_382 +} + +func (dm_build_384 *dm_build_373) dm_build_137() error { + + dm_build_384.dm_build_152.dm_build_1348.Dm_build_1208(Dm_build_367, dm_build_384.dm_build_375) + + dm_build_384.dm_build_152.dm_build_1348.Dm_build_1208(Dm_build_368, dm_build_384.dm_build_376) + + dm_build_384.dm_build_152.dm_build_1348.Dm_build_1200(Dm_build_369, dm_build_384.dm_build_374.id) + + dm_build_385 := dm_build_384.dm_build_374.dmStmt.dmConn.dmConnector.bufPrefetch + var dm_build_386 int32 + if dm_build_384.dm_build_374.sizeOfRow != 0 && dm_build_384.dm_build_374.fetchSize != 0 { + if dm_build_384.dm_build_374.sizeOfRow*dm_build_384.dm_build_374.fetchSize > int(INT32_MAX) { + dm_build_386 = INT32_MAX + } else { + dm_build_386 = int32(dm_build_384.dm_build_374.sizeOfRow * dm_build_384.dm_build_374.fetchSize) + } + + if dm_build_386 < Dm_build_76 { + dm_build_385 = int(Dm_build_76) + } else if dm_build_386 > Dm_build_77 { + dm_build_385 = int(Dm_build_77) + } else { + dm_build_385 = int(dm_build_386) + } + + dm_build_384.dm_build_152.dm_build_1348.Dm_build_1204(Dm_build_370, int32(dm_build_385)) + } + + return nil +} + +func (dm_build_388 *dm_build_373) dm_build_141() (interface{}, error) { + dm_build_389 := execRetInfo{} + dm_build_389.rsBdta = dm_build_388.dm_build_374.isBdta + + dm_build_389.updateCount = dm_build_388.dm_build_152.dm_build_1348.Dm_build_1285(Dm_build_371) + dm_build_390 := dm_build_388.dm_build_152.dm_build_1348.Dm_build_1282(Dm_build_372) + + dm_build_388.dm_build_322(&dm_build_389, len(dm_build_388.dm_build_374.columns), int(dm_build_390), -1) + + return &dm_build_389, nil +} + +type dm_build_391 struct { + dm_build_151 + dm_build_392 *lob + dm_build_393 int + dm_build_394 int +} + +func dm_build_395(dm_build_396 *dm_build_1345, dm_build_397 *lob, dm_build_398 int, dm_build_399 int) *dm_build_391 { + dm_build_400 := new(dm_build_391) + dm_build_400.dm_build_156(dm_build_396, Dm_build_35) + dm_build_400.dm_build_392 = dm_build_397 + dm_build_400.dm_build_393 = dm_build_398 + dm_build_400.dm_build_394 = dm_build_399 + return dm_build_400 +} + +func (dm_build_402 *dm_build_391) dm_build_137() error { + + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1052(byte(dm_build_402.dm_build_392.lobFlag)) + + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_402.dm_build_392.tabId) + + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_402.dm_build_392.colId) + + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1080(uint64(dm_build_402.dm_build_392.blobId)) + + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_402.dm_build_392.groupId) + + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_402.dm_build_392.fileId) + + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_402.dm_build_392.pageNo) + + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_402.dm_build_392.curFileId) + + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_402.dm_build_392.curPageNo) + + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_402.dm_build_392.totalOffset) + + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1064(int32(dm_build_402.dm_build_393)) + + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1064(int32(dm_build_402.dm_build_394)) + + if dm_build_402.dm_build_152.dm_build_1349.NewLobFlag { + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1080(uint64(dm_build_402.dm_build_392.rowId)) + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_402.dm_build_392.exGroupId) + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_402.dm_build_392.exFileId) + dm_build_402.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_402.dm_build_392.exPageNo) + } + + return nil +} + +func (dm_build_404 *dm_build_391) dm_build_141() (interface{}, error) { + + dm_build_404.dm_build_392.readOver = dm_build_404.dm_build_152.dm_build_1348.Dm_build_1132() == 1 + var dm_build_405 = dm_build_404.dm_build_152.dm_build_1348.Dm_build_1156() + if dm_build_405 <= 0 { + return &lobRetInfo{0, []byte{}}, nil + } + dm_build_404.dm_build_392.curFileId = dm_build_404.dm_build_152.dm_build_1348.Dm_build_1135() + dm_build_404.dm_build_392.curPageNo = dm_build_404.dm_build_152.dm_build_1348.Dm_build_1138() + dm_build_404.dm_build_392.totalOffset = dm_build_404.dm_build_152.dm_build_1348.Dm_build_1138() + + var dm_build_406 = dm_build_404.dm_build_152.dm_build_1348.Dm_build_1169(int(dm_build_405)) + var dm_build_407 int64 = -1 + if dm_build_404.dm_build_152.dm_build_1348.Dm_build_1031(false) > 0 { + dm_build_407 = int64(dm_build_404.dm_build_152.dm_build_1348.Dm_build_1156()) + } + return &lobRetInfo{dm_build_407, dm_build_406}, nil +} + +type dm_build_408 struct { + dm_build_151 + dm_build_409 *lob +} + +func dm_build_410(dm_build_411 *dm_build_1345, dm_build_412 *lob) *dm_build_408 { + dm_build_413 := new(dm_build_408) + dm_build_413.dm_build_156(dm_build_411, Dm_build_32) + dm_build_413.dm_build_409 = dm_build_412 + return dm_build_413 +} + +func (dm_build_415 *dm_build_408) dm_build_137() error { + + dm_build_415.dm_build_152.dm_build_1348.Dm_build_1052(byte(dm_build_415.dm_build_409.lobFlag)) + + dm_build_415.dm_build_152.dm_build_1348.Dm_build_1080(uint64(dm_build_415.dm_build_409.blobId)) + + dm_build_415.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_415.dm_build_409.groupId) + + dm_build_415.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_415.dm_build_409.fileId) + + dm_build_415.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_415.dm_build_409.pageNo) + + if dm_build_415.dm_build_152.dm_build_1349.NewLobFlag { + dm_build_415.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_415.dm_build_409.tabId) + dm_build_415.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_415.dm_build_409.colId) + dm_build_415.dm_build_152.dm_build_1348.Dm_build_1080(uint64(dm_build_415.dm_build_409.rowId)) + + dm_build_415.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_415.dm_build_409.exGroupId) + dm_build_415.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_415.dm_build_409.exFileId) + dm_build_415.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_415.dm_build_409.exPageNo) + } + + return nil +} + +func (dm_build_417 *dm_build_408) dm_build_141() (interface{}, error) { + + if dm_build_417.dm_build_152.dm_build_1348.Dm_build_1031(false) == 8 { + return dm_build_417.dm_build_152.dm_build_1348.Dm_build_1141(), nil + } else { + return int64(dm_build_417.dm_build_152.dm_build_1348.Dm_build_1156()), nil + } +} + +type dm_build_418 struct { + dm_build_151 + dm_build_419 *lob + dm_build_420 int +} + +func dm_build_421(dm_build_422 *dm_build_1345, dm_build_423 *lob, dm_build_424 int) *dm_build_418 { + dm_build_425 := new(dm_build_418) + dm_build_425.dm_build_156(dm_build_422, Dm_build_34) + dm_build_425.dm_build_419 = dm_build_423 + dm_build_425.dm_build_420 = dm_build_424 + return dm_build_425 +} + +func (dm_build_427 *dm_build_418) dm_build_137() error { + + dm_build_427.dm_build_152.dm_build_1348.Dm_build_1052(byte(dm_build_427.dm_build_419.lobFlag)) + + dm_build_427.dm_build_152.dm_build_1348.Dm_build_1080(uint64(dm_build_427.dm_build_419.blobId)) + + dm_build_427.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_427.dm_build_419.groupId) + + dm_build_427.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_427.dm_build_419.fileId) + + dm_build_427.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_427.dm_build_419.pageNo) + + dm_build_427.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_427.dm_build_419.tabId) + dm_build_427.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_427.dm_build_419.colId) + dm_build_427.dm_build_152.dm_build_1348.Dm_build_1080(uint64(dm_build_427.dm_build_419.rowId)) + dm_build_427.dm_build_152.dm_build_1348.Dm_build_1092(Dm_build_650.Dm_build_855(uint32(dm_build_427.dm_build_420))) + + if dm_build_427.dm_build_152.dm_build_1349.NewLobFlag { + dm_build_427.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_427.dm_build_419.exGroupId) + dm_build_427.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_427.dm_build_419.exFileId) + dm_build_427.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_427.dm_build_419.exPageNo) + } + return nil +} + +func (dm_build_429 *dm_build_418) dm_build_141() (interface{}, error) { + + dm_build_430 := dm_build_429.dm_build_152.dm_build_1348.Dm_build_1156() + dm_build_429.dm_build_419.blobId = dm_build_429.dm_build_152.dm_build_1348.Dm_build_1141() + dm_build_429.dm_build_419.resetCurrentInfo() + return int64(dm_build_430), nil +} + +const ( + Dm_build_431 = Dm_build_44 + + Dm_build_432 = Dm_build_431 + ULINT_SIZE + + Dm_build_433 = Dm_build_432 + ULINT_SIZE + + Dm_build_434 = Dm_build_433 + ULINT_SIZE + + Dm_build_435 = Dm_build_434 + BYTE_SIZE + + Dm_build_436 = Dm_build_435 + USINT_SIZE + + Dm_build_437 = Dm_build_436 + ULINT_SIZE + + Dm_build_438 = Dm_build_437 + BYTE_SIZE + + Dm_build_439 = Dm_build_438 + BYTE_SIZE + + Dm_build_440 = Dm_build_439 + BYTE_SIZE + + Dm_build_441 = Dm_build_44 + + Dm_build_442 = Dm_build_441 + ULINT_SIZE + + Dm_build_443 = Dm_build_442 + ULINT_SIZE + + Dm_build_444 = Dm_build_443 + BYTE_SIZE + + Dm_build_445 = Dm_build_444 + ULINT_SIZE + + Dm_build_446 = Dm_build_445 + BYTE_SIZE + + Dm_build_447 = Dm_build_446 + BYTE_SIZE + + Dm_build_448 = Dm_build_447 + USINT_SIZE + + Dm_build_449 = Dm_build_448 + USINT_SIZE + + Dm_build_450 = Dm_build_449 + BYTE_SIZE + + Dm_build_451 = Dm_build_450 + USINT_SIZE + + Dm_build_452 = Dm_build_451 + BYTE_SIZE + + Dm_build_453 = Dm_build_452 + BYTE_SIZE + + Dm_build_454 = Dm_build_453 + ULINT_SIZE + + Dm_build_455 = Dm_build_454 + USINT_SIZE +) + +type dm_build_456 struct { + dm_build_151 + + dm_build_457 *DmConnection + + dm_build_458 bool +} + +func dm_build_459(dm_build_460 *dm_build_1345) *dm_build_456 { + dm_build_461 := new(dm_build_456) + dm_build_461.dm_build_156(dm_build_460, Dm_build_16) + dm_build_461.dm_build_457 = dm_build_460.dm_build_1349 + return dm_build_461 +} + +func (dm_build_463 *dm_build_456) dm_build_137() error { + + if dm_build_463.dm_build_457.dmConnector.newClientType { + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1204(Dm_build_431, Dm_build_55) + } else { + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1204(Dm_build_431, Dm_build_54) + } + + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1204(Dm_build_432, g2dbIsoLevel(dm_build_463.dm_build_457.IsoLevel)) + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1204(Dm_build_433, int32(Locale)) + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1200(Dm_build_435, dm_build_463.dm_build_457.dmConnector.localTimezone) + + if dm_build_463.dm_build_457.ReadOnly { + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_434, Dm_build_79) + } else { + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_434, Dm_build_78) + } + + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1204(Dm_build_436, int32(dm_build_463.dm_build_457.dmConnector.sessionTimeout)) + + if dm_build_463.dm_build_457.dmConnector.mppLocal { + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_437, 1) + } else { + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_437, 0) + } + + if dm_build_463.dm_build_457.dmConnector.rwSeparate { + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_438, 1) + } else { + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_438, 0) + } + + if dm_build_463.dm_build_457.NewLobFlag { + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_439, 1) + } else { + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_439, 0) + } + + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_440, dm_build_463.dm_build_457.dmConnector.osAuthType) + + dm_build_464 := dm_build_463.dm_build_457.getServerEncoding() + + if dm_build_463.dm_build_152.dm_build_1355 != "" { + + } + + dm_build_465 := Dm_build_650.Dm_build_866(dm_build_463.dm_build_457.dmConnector.user, dm_build_464, dm_build_463.dm_build_152.dm_build_1349) + dm_build_466 := Dm_build_650.Dm_build_866(dm_build_463.dm_build_457.dmConnector.password, dm_build_464, dm_build_463.dm_build_152.dm_build_1349) + if len(dm_build_465) > Dm_build_52 { + return ECGO_USERNAME_TOO_LONG.throw() + } + if len(dm_build_466) > Dm_build_52 { + return ECGO_PASSWORD_TOO_LONG.throw() + } + + if dm_build_463.dm_build_152.dm_build_1351 && dm_build_463.dm_build_457.dmConnector.loginCertificate != "" { + + } else if dm_build_463.dm_build_152.dm_build_1351 { + dm_build_465 = dm_build_463.dm_build_152.dm_build_1350.Encrypt(dm_build_465, false) + dm_build_466 = dm_build_463.dm_build_152.dm_build_1350.Encrypt(dm_build_466, false) + } + + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1096(dm_build_465) + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1096(dm_build_466) + + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1108(dm_build_463.dm_build_457.dmConnector.appName, dm_build_464, dm_build_463.dm_build_152.dm_build_1349) + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1108(dm_build_463.dm_build_457.dmConnector.osName, dm_build_464, dm_build_463.dm_build_152.dm_build_1349) + + if hostName, err := os.Hostname(); err != nil { + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1108(hostName, dm_build_464, dm_build_463.dm_build_152.dm_build_1349) + } else { + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1108("", dm_build_464, dm_build_463.dm_build_152.dm_build_1349) + } + + if dm_build_463.dm_build_457.dmConnector.rwStandby { + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1052(1) + } else { + dm_build_463.dm_build_152.dm_build_1348.Dm_build_1052(0) + } + + return nil +} + +func (dm_build_468 *dm_build_456) dm_build_141() (interface{}, error) { + + dm_build_468.dm_build_457.MaxRowSize = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1282(Dm_build_441) + dm_build_468.dm_build_457.DDLAutoCommit = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_443) == 1 + dm_build_468.dm_build_457.IsoLevel = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1282(Dm_build_444) + dm_build_468.dm_build_457.dmConnector.caseSensitive = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_445) == 1 + dm_build_468.dm_build_457.BackslashEscape = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_446) == 1 + dm_build_468.dm_build_457.SvrStat = int32(dm_build_468.dm_build_152.dm_build_1348.Dm_build_1279(Dm_build_448)) + dm_build_468.dm_build_457.SvrMode = int32(dm_build_468.dm_build_152.dm_build_1348.Dm_build_1279(Dm_build_447)) + dm_build_468.dm_build_457.ConstParaOpt = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_449) == 1 + dm_build_468.dm_build_457.DbTimezone = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1279(Dm_build_450) + dm_build_468.dm_build_457.NewLobFlag = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_452) == 1 + + if dm_build_468.dm_build_457.dmConnector.bufPrefetch == 0 { + dm_build_468.dm_build_457.dmConnector.bufPrefetch = int(dm_build_468.dm_build_152.dm_build_1348.Dm_build_1282(Dm_build_453)) + } + + dm_build_468.dm_build_457.LifeTimeRemainder = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1279(Dm_build_454) + dm_build_468.dm_build_457.dscControl = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_455) == 1 + + dm_build_469 := dm_build_468.dm_build_457.getServerEncoding() + + dm_build_468.dm_build_457.InstanceName = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1180(dm_build_469, dm_build_468.dm_build_152.dm_build_1349) + + var dm_build_470 = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1138() + if dm_build_470 == 0 && dm_build_468.dm_build_457.MsgVersion > 0 { + dm_build_468.dm_build_457.Schema = strings.ToUpper(dm_build_468.dm_build_457.dmConnector.user) + } else { + dm_build_468.dm_build_457.Schema = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1175(int(dm_build_470), dm_build_469, dm_build_468.dm_build_152.dm_build_1349) + } + + dm_build_468.dm_build_457.LastLoginIP = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1180(dm_build_469, dm_build_468.dm_build_152.dm_build_1349) + dm_build_468.dm_build_457.LastLoginTime = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1180(dm_build_469, dm_build_468.dm_build_152.dm_build_1349) + dm_build_468.dm_build_457.FailedAttempts = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1138() + dm_build_468.dm_build_457.LoginWarningID = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1138() + dm_build_468.dm_build_457.GraceTimeRemainder = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1138() + dm_build_468.dm_build_457.Guid = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1180(dm_build_469, dm_build_468.dm_build_152.dm_build_1349) + dm_build_468.dm_build_457.DbName = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1180(dm_build_469, dm_build_468.dm_build_152.dm_build_1349) + + if dm_build_468.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_451) == 1 { + dm_build_468.dm_build_457.StandbyHost = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1180(dm_build_469, dm_build_468.dm_build_152.dm_build_1349) + dm_build_468.dm_build_457.StandbyPort = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1138() + dm_build_468.dm_build_457.StandbyCount = int32(dm_build_468.dm_build_152.dm_build_1348.Dm_build_1153()) + } + + if dm_build_468.dm_build_152.dm_build_1348.Dm_build_1031(false) > 0 { + dm_build_468.dm_build_457.SessionID = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1141() + } + + if dm_build_468.dm_build_152.dm_build_1348.Dm_build_1031(false) > 0 { + if dm_build_468.dm_build_152.dm_build_1348.Dm_build_1132() == 1 { + + dm_build_468.dm_build_457.FormatDate = "DD-MON-YY" + + dm_build_468.dm_build_457.FormatTime = "HH12.MI.SS.FF6 AM" + + dm_build_468.dm_build_457.FormatTimestamp = "DD-MON-YY HH12.MI.SS.FF6 AM" + + dm_build_468.dm_build_457.FormatTimestampTZ = "DD-MON-YY HH12.MI.SS.FF6 AM +TZH:TZM" + + dm_build_468.dm_build_457.FormatTimeTZ = "HH12.MI.SS.FF6 AM +TZH:TZM" + } + } + + if dm_build_468.dm_build_152.dm_build_1348.Dm_build_1031(false) > 0 { + + format := dm_build_468.dm_build_152.dm_build_1348.Dm_build_1184(dm_build_469, dm_build_468.dm_build_152.dm_build_1349) + if format != "" { + dm_build_468.dm_build_457.FormatDate = format + } + format = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1184(dm_build_469, dm_build_468.dm_build_152.dm_build_1349) + if format != "" { + dm_build_468.dm_build_457.FormatTime = format + } + format = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1184(dm_build_469, dm_build_468.dm_build_152.dm_build_1349) + if format != "" { + dm_build_468.dm_build_457.FormatTimestamp = format + } + format = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1184(dm_build_469, dm_build_468.dm_build_152.dm_build_1349) + if format != "" { + dm_build_468.dm_build_457.FormatTimestampTZ = format + } + format = dm_build_468.dm_build_152.dm_build_1348.Dm_build_1184(dm_build_469, dm_build_468.dm_build_152.dm_build_1349) + if format != "" { + dm_build_468.dm_build_457.FormatTimeTZ = format + } + } + + return nil, nil +} + +const ( + Dm_build_471 = Dm_build_44 +) + +type dm_build_472 struct { + dm_build_259 + dm_build_473 int16 +} + +func dm_build_474(dm_build_475 *dm_build_1345, dm_build_476 *DmStatement, dm_build_477 int16) *dm_build_472 { + dm_build_478 := new(dm_build_472) + dm_build_478.dm_build_160(dm_build_475, Dm_build_36, dm_build_476) + dm_build_478.dm_build_473 = dm_build_477 + return dm_build_478 +} + +func (dm_build_480 *dm_build_472) dm_build_137() error { + dm_build_480.dm_build_152.dm_build_1348.Dm_build_1200(Dm_build_471, dm_build_480.dm_build_473) + return nil +} + +func (dm_build_482 *dm_build_472) dm_build_141() (interface{}, error) { + return dm_build_482.dm_build_259.dm_build_141() +} + +const ( + Dm_build_483 = Dm_build_44 + Dm_build_484 = Dm_build_483 + USINT_SIZE +) + +type dm_build_485 struct { + dm_build_495 + dm_build_486 []parameter +} + +func dm_build_487(dm_build_488 *dm_build_1345, dm_build_489 *DmStatement, dm_build_490 []parameter) *dm_build_485 { + dm_build_491 := new(dm_build_485) + dm_build_491.dm_build_160(dm_build_488, Dm_build_40, dm_build_489) + dm_build_491.dm_build_486 = dm_build_490 + return dm_build_491 +} + +func (dm_build_493 *dm_build_485) dm_build_137() error { + + if dm_build_493.dm_build_486 == nil { + dm_build_493.dm_build_152.dm_build_1348.Dm_build_1200(Dm_build_483, 0) + } else { + dm_build_493.dm_build_152.dm_build_1348.Dm_build_1200(Dm_build_483, int16(len(dm_build_493.dm_build_486))) + } + + dm_build_493.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_484, 0) + + return dm_build_493.dm_build_284(dm_build_493.dm_build_486) +} + +const Dm_build_494 = 38 + +type dm_build_495 struct { + dm_build_259 + dm_build_496 bool + dm_build_497 int16 +} + +func dm_build_498(dm_build_499 *dm_build_1345, dm_build_500 *DmStatement, dm_build_501 bool, dm_build_502 int16) *dm_build_495 { + dm_build_503 := new(dm_build_495) + dm_build_503.dm_build_160(dm_build_499, Dm_build_20, dm_build_500) + dm_build_503.dm_build_496 = dm_build_501 + dm_build_503.dm_build_497 = dm_build_502 + return dm_build_503 +} + +func (dm_build_505 *dm_build_495) dm_build_137() error { + + dm_build_506 := Dm_build_44 + + if dm_build_505.dm_build_152.dm_build_1349.autoCommit { + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_506, 1) + } else { + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_506, 0) + } + + if dm_build_505.dm_build_496 { + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_506, 1) + } else { + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_506, 0) + } + + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_506, 0) + + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_506, 1) + + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_506, 0) + + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1200(dm_build_506, Dm_build_95) + + if dm_build_505.dm_build_155.maxRows <= 0 || dm_build_505.dm_build_152.dm_build_1349.dmConnector.enRsCache { + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1208(dm_build_506, INT64_MAX) + } else { + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1208(dm_build_506, dm_build_505.dm_build_155.maxRows) + } + + if dm_build_505.dm_build_152.dm_build_1349.dmConnector.isBdtaRS { + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_506, Dm_build_123) + } else { + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_506, Dm_build_122) + } + + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1200(dm_build_506, 0) + + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_506, 1) + + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_506, 0) + + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_506, 0) + + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1204(dm_build_506, dm_build_505.dm_build_155.queryTimeout) + + if dm_build_505.dm_build_155.innerExec { + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_506, 1) + } else { + dm_build_506 += dm_build_505.dm_build_152.dm_build_1348.Dm_build_1196(dm_build_506, 0) + } + + if dm_build_505.dm_build_152.dm_build_1349.MsgVersion >= Dm_build_8 { + if dm_build_505.dm_build_496 { + dm_build_505.dm_build_262 = dm_build_505.dm_build_290() + } else { + dm_build_505.dm_build_262 = Dm_build_253 + } + dm_build_505.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_494, byte(dm_build_505.dm_build_262)) + } + + dm_build_505.dm_build_152.dm_build_1348.Dm_build_1126(dm_build_505.dm_build_155.nativeSql, dm_build_505.dm_build_152.dm_build_1349.getServerEncoding(), dm_build_505.dm_build_152.dm_build_1349) + + return nil +} + +func (dm_build_508 *dm_build_495) dm_build_141() (interface{}, error) { + + if dm_build_508.dm_build_496 { + return dm_build_508.dm_build_259.dm_build_141() + } + + dm_build_509 := NewExceInfo() + dm_build_510 := Dm_build_44 + + dm_build_509.retSqlType = dm_build_508.dm_build_152.dm_build_1348.Dm_build_1279(dm_build_510) + dm_build_510 += USINT_SIZE + + dm_build_511 := dm_build_508.dm_build_152.dm_build_1348.Dm_build_1297(dm_build_510) + dm_build_510 += USINT_SIZE + + dm_build_512 := dm_build_508.dm_build_152.dm_build_1348.Dm_build_1279(dm_build_510) + dm_build_510 += USINT_SIZE + + dm_build_508.dm_build_152.dm_build_1348.Dm_build_1285(dm_build_510) + dm_build_510 += DDWORD_SIZE + + dm_build_508.dm_build_152.dm_build_1349.TrxStatus = dm_build_508.dm_build_152.dm_build_1348.Dm_build_1282(dm_build_510) + dm_build_510 += ULINT_SIZE + + if dm_build_511 > 0 { + dm_build_508.dm_build_155.serverParams = dm_build_508.dm_build_513(int(dm_build_511)) + dm_build_508.dm_build_155.bindParams = make([]parameter, dm_build_511) + for i := 0; i < int(dm_build_511); i++ { + dm_build_508.dm_build_155.bindParams[i].InitParameter() + dm_build_508.dm_build_155.bindParams[i].colType = dm_build_508.dm_build_155.serverParams[i].colType + dm_build_508.dm_build_155.bindParams[i].prec = dm_build_508.dm_build_155.serverParams[i].prec + dm_build_508.dm_build_155.bindParams[i].scale = dm_build_508.dm_build_155.serverParams[i].scale + dm_build_508.dm_build_155.bindParams[i].nullable = dm_build_508.dm_build_155.serverParams[i].nullable + dm_build_508.dm_build_155.bindParams[i].hasDefault = dm_build_508.dm_build_155.serverParams[i].hasDefault + dm_build_508.dm_build_155.bindParams[i].typeFlag = dm_build_508.dm_build_155.serverParams[i].typeFlag + dm_build_508.dm_build_155.bindParams[i].lob = dm_build_508.dm_build_155.serverParams[i].lob + dm_build_508.dm_build_155.bindParams[i].ioType = dm_build_508.dm_build_155.serverParams[i].ioType + dm_build_508.dm_build_155.bindParams[i].name = dm_build_508.dm_build_155.serverParams[i].name + dm_build_508.dm_build_155.bindParams[i].typeName = dm_build_508.dm_build_155.serverParams[i].typeName + dm_build_508.dm_build_155.bindParams[i].tableName = dm_build_508.dm_build_155.serverParams[i].tableName + dm_build_508.dm_build_155.bindParams[i].schemaName = dm_build_508.dm_build_155.serverParams[i].schemaName + dm_build_508.dm_build_155.bindParams[i].lobTabId = dm_build_508.dm_build_155.serverParams[i].lobTabId + dm_build_508.dm_build_155.bindParams[i].lobColId = dm_build_508.dm_build_155.serverParams[i].lobColId + dm_build_508.dm_build_155.bindParams[i].mask = dm_build_508.dm_build_155.serverParams[i].mask + dm_build_508.dm_build_155.bindParams[i].typeDescriptor = dm_build_508.dm_build_155.serverParams[i].typeDescriptor + } + + dm_build_508.dm_build_155.paramCount = int32(dm_build_511) + } else { + dm_build_508.dm_build_155.serverParams = make([]parameter, 0) + dm_build_508.dm_build_155.bindParams = make([]parameter, 0) + dm_build_508.dm_build_155.paramCount = 0 + } + + if dm_build_512 > 0 { + dm_build_508.dm_build_155.columns = dm_build_508.dm_build_312(int(dm_build_512), dm_build_509.rsBdta) + } else { + dm_build_508.dm_build_155.columns = make([]column, 0) + } + + return dm_build_509, nil +} + +func (dm_build_514 *dm_build_495) dm_build_513(dm_build_515 int) []parameter { + + var dm_build_516, dm_build_517, dm_build_518, dm_build_519 int16 + + dm_build_520 := make([]parameter, dm_build_515) + for i := 0; i < dm_build_515; i++ { + + dm_build_520[i].InitParameter() + + dm_build_520[i].colType = dm_build_514.dm_build_152.dm_build_1348.Dm_build_1138() + + dm_build_520[i].prec = dm_build_514.dm_build_152.dm_build_1348.Dm_build_1138() + + dm_build_520[i].scale = dm_build_514.dm_build_152.dm_build_1348.Dm_build_1138() + + dm_build_520[i].nullable = dm_build_514.dm_build_152.dm_build_1348.Dm_build_1138() != 0 + + itemFlag := dm_build_514.dm_build_152.dm_build_1348.Dm_build_1135() + + dm_build_520[i].hasDefault = int(itemFlag)&Dm_build_252 != 0 + + if int(itemFlag)&Dm_build_251 != 0 { + dm_build_520[i].typeFlag = TYPE_FLAG_RECOMMEND + } else { + dm_build_520[i].typeFlag = TYPE_FLAG_EXACT + } + + dm_build_520[i].lob = int(itemFlag)&Dm_build_249 != 0 + + dm_build_514.dm_build_152.dm_build_1348.Dm_build_1138() + + dm_build_520[i].ioType = int8(dm_build_514.dm_build_152.dm_build_1348.Dm_build_1135()) + + dm_build_516 = dm_build_514.dm_build_152.dm_build_1348.Dm_build_1135() + + dm_build_517 = dm_build_514.dm_build_152.dm_build_1348.Dm_build_1135() + + dm_build_518 = dm_build_514.dm_build_152.dm_build_1348.Dm_build_1135() + + dm_build_519 = dm_build_514.dm_build_152.dm_build_1348.Dm_build_1135() + dm_build_520[i].name = dm_build_514.dm_build_152.dm_build_1348.Dm_build_1175(int(dm_build_516), dm_build_514.dm_build_152.dm_build_1349.getServerEncoding(), dm_build_514.dm_build_152.dm_build_1349) + dm_build_520[i].typeName = dm_build_514.dm_build_152.dm_build_1348.Dm_build_1175(int(dm_build_517), dm_build_514.dm_build_152.dm_build_1349.getServerEncoding(), dm_build_514.dm_build_152.dm_build_1349) + dm_build_520[i].tableName = dm_build_514.dm_build_152.dm_build_1348.Dm_build_1175(int(dm_build_518), dm_build_514.dm_build_152.dm_build_1349.getServerEncoding(), dm_build_514.dm_build_152.dm_build_1349) + dm_build_520[i].schemaName = dm_build_514.dm_build_152.dm_build_1348.Dm_build_1175(int(dm_build_519), dm_build_514.dm_build_152.dm_build_1349.getServerEncoding(), dm_build_514.dm_build_152.dm_build_1349) + + if dm_build_520[i].lob { + dm_build_520[i].lobTabId = dm_build_514.dm_build_152.dm_build_1348.Dm_build_1138() + dm_build_520[i].lobColId = dm_build_514.dm_build_152.dm_build_1348.Dm_build_1135() + } + + if dm_build_520[i].colType == DATETIME || dm_build_520[i].colType == DATETIME2 { + if (dm_build_520[i].scale & LOCAL_DATETIME_SCALE_MASK) != 0 { + + dm_build_520[i].scale = dm_build_520[i].scale & ^LOCAL_DATETIME_SCALE_MASK + dm_build_520[i].mask = MASK_LOCAL_DATETIME + } else if (dm_build_520[i].scale & ORACLE_DATE_SCALE_MASK) != 0 { + + dm_build_520[i].scale = dm_build_520[i].scale & ^ORACLE_DATE_SCALE_MASK + dm_build_520[i].mask = MASK_ORACLE_DATE + } + } + + if dm_build_520[i].colType == DECIMAL && dm_build_520[i].scale == ORACLE_FLOAT_SCALE_MASK { + dm_build_520[i].prec = int32(math.Round(float64(dm_build_520[i].prec)*0.30103) + 1) + dm_build_520[i].scale = -1 + dm_build_520[i].mask = MASK_ORACLE_FLOAT + } + + if dm_build_520[i].colType == VARCHAR && dm_build_520[i].prec == BFILE_PREC && dm_build_520[i].scale == BFILE_SCALE { + dm_build_520[i].mask = MASK_BFILE + } + } + + for i := 0; i < dm_build_515; i++ { + + if isComplexType(int(dm_build_520[i].colType), int(dm_build_520[i].scale)) { + + strDesc := newTypeDescriptor(dm_build_514.dm_build_152.dm_build_1349) + strDesc.unpack(dm_build_514.dm_build_152.dm_build_1348) + dm_build_520[i].typeDescriptor = strDesc + } + } + + return dm_build_520 +} + +const ( + Dm_build_521 = Dm_build_44 +) + +type dm_build_522 struct { + dm_build_151 + dm_build_523 int16 + dm_build_524 *Dm_build_931 + dm_build_525 int32 +} + +func dm_build_526(dm_build_527 *dm_build_1345, dm_build_528 *DmStatement, dm_build_529 int16, dm_build_530 *Dm_build_931, dm_build_531 int32) *dm_build_522 { + dm_build_532 := new(dm_build_522) + dm_build_532.dm_build_160(dm_build_527, Dm_build_26, dm_build_528) + dm_build_532.dm_build_523 = dm_build_529 + dm_build_532.dm_build_524 = dm_build_530 + dm_build_532.dm_build_525 = dm_build_531 + return dm_build_532 +} + +func (dm_build_534 *dm_build_522) dm_build_137() error { + dm_build_534.dm_build_152.dm_build_1348.Dm_build_1200(Dm_build_521, dm_build_534.dm_build_523) + + dm_build_534.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_534.dm_build_525) + + if dm_build_534.dm_build_152.dm_build_1349.NewLobFlag { + dm_build_534.dm_build_152.dm_build_1348.Dm_build_1064(-1) + } + dm_build_534.dm_build_524.Dm_build_938(dm_build_534.dm_build_152.dm_build_1348, int(dm_build_534.dm_build_525)) + return nil +} + +type dm_build_535 struct { + dm_build_151 +} + +func dm_build_536(dm_build_537 *dm_build_1345) *dm_build_535 { + dm_build_538 := new(dm_build_535) + dm_build_538.dm_build_156(dm_build_537, Dm_build_24) + return dm_build_538 +} + +type dm_build_539 struct { + dm_build_151 + dm_build_540 int32 +} + +func dm_build_541(dm_build_542 *dm_build_1345, dm_build_543 int32) *dm_build_539 { + dm_build_544 := new(dm_build_539) + dm_build_544.dm_build_156(dm_build_542, Dm_build_37) + dm_build_544.dm_build_540 = dm_build_543 + return dm_build_544 +} + +func (dm_build_546 *dm_build_539) dm_build_137() error { + + dm_build_547 := Dm_build_44 + dm_build_547 += dm_build_546.dm_build_152.dm_build_1348.Dm_build_1204(dm_build_547, g2dbIsoLevel(dm_build_546.dm_build_540)) + return nil +} + +type dm_build_548 struct { + dm_build_151 + dm_build_549 *lob + dm_build_550 byte + dm_build_551 int + dm_build_552 []byte + dm_build_553 int + dm_build_554 int +} + +func dm_build_555(dm_build_556 *dm_build_1345, dm_build_557 *lob, dm_build_558 byte, dm_build_559 int, dm_build_560 []byte, + dm_build_561 int, dm_build_562 int) *dm_build_548 { + dm_build_563 := new(dm_build_548) + dm_build_563.dm_build_156(dm_build_556, Dm_build_33) + dm_build_563.dm_build_549 = dm_build_557 + dm_build_563.dm_build_550 = dm_build_558 + dm_build_563.dm_build_551 = dm_build_559 + dm_build_563.dm_build_552 = dm_build_560 + dm_build_563.dm_build_553 = dm_build_561 + dm_build_563.dm_build_554 = dm_build_562 + return dm_build_563 +} + +func (dm_build_565 *dm_build_548) dm_build_137() error { + + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1052(byte(dm_build_565.dm_build_549.lobFlag)) + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1052(dm_build_565.dm_build_550) + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1080(uint64(dm_build_565.dm_build_549.blobId)) + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_565.dm_build_549.groupId) + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_565.dm_build_549.fileId) + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_565.dm_build_549.pageNo) + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_565.dm_build_549.curFileId) + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_565.dm_build_549.curPageNo) + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_565.dm_build_549.totalOffset) + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_565.dm_build_549.tabId) + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_565.dm_build_549.colId) + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1080(uint64(dm_build_565.dm_build_549.rowId)) + + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1064(int32(dm_build_565.dm_build_551)) + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1064(int32(dm_build_565.dm_build_554)) + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1092(dm_build_565.dm_build_552) + + if dm_build_565.dm_build_152.dm_build_1349.NewLobFlag { + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_565.dm_build_549.exGroupId) + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1060(dm_build_565.dm_build_549.exFileId) + dm_build_565.dm_build_152.dm_build_1348.Dm_build_1064(dm_build_565.dm_build_549.exPageNo) + } + return nil +} + +func (dm_build_567 *dm_build_548) dm_build_141() (interface{}, error) { + + var dm_build_568 = dm_build_567.dm_build_152.dm_build_1348.Dm_build_1138() + dm_build_567.dm_build_549.blobId = dm_build_567.dm_build_152.dm_build_1348.Dm_build_1141() + dm_build_567.dm_build_549.fileId = dm_build_567.dm_build_152.dm_build_1348.Dm_build_1135() + dm_build_567.dm_build_549.pageNo = dm_build_567.dm_build_152.dm_build_1348.Dm_build_1138() + dm_build_567.dm_build_549.curFileId = dm_build_567.dm_build_152.dm_build_1348.Dm_build_1135() + dm_build_567.dm_build_549.curPageNo = dm_build_567.dm_build_152.dm_build_1348.Dm_build_1138() + dm_build_567.dm_build_549.totalOffset = dm_build_567.dm_build_152.dm_build_1348.Dm_build_1138() + return dm_build_568, nil +} + +const ( + Dm_build_569 = Dm_build_44 + + Dm_build_570 = Dm_build_569 + ULINT_SIZE + + Dm_build_571 = Dm_build_570 + ULINT_SIZE + + Dm_build_572 = Dm_build_571 + BYTE_SIZE + + Dm_build_573 = Dm_build_572 + BYTE_SIZE + + Dm_build_574 = Dm_build_573 + BYTE_SIZE + + Dm_build_575 = Dm_build_574 + BYTE_SIZE + + Dm_build_576 = Dm_build_575 + BYTE_SIZE + + Dm_build_577 = Dm_build_576 + BYTE_SIZE + + Dm_build_578 = Dm_build_577 + BYTE_SIZE + + Dm_build_579 = Dm_build_44 + + Dm_build_580 = Dm_build_579 + ULINT_SIZE + + Dm_build_581 = Dm_build_580 + ULINT_SIZE + + Dm_build_582 = Dm_build_581 + ULINT_SIZE + + Dm_build_583 = Dm_build_582 + ULINT_SIZE + + Dm_build_584 = Dm_build_583 + ULINT_SIZE + + Dm_build_585 = Dm_build_584 + BYTE_SIZE + + Dm_build_586 = Dm_build_585 + BYTE_SIZE + + Dm_build_587 = Dm_build_586 + BYTE_SIZE + + Dm_build_588 = Dm_build_587 + BYTE_SIZE + + Dm_build_589 = Dm_build_588 + BYTE_SIZE + + Dm_build_590 = Dm_build_589 + USINT_SIZE + + Dm_build_591 = Dm_build_590 + BYTE_SIZE +) + +type dm_build_592 struct { + dm_build_151 + dm_build_593 *DmConnection + dm_build_594 int + Dm_build_595 int32 + Dm_build_596 []byte + dm_build_597 byte +} + +func dm_build_598(dm_build_599 *dm_build_1345) *dm_build_592 { + dm_build_600 := new(dm_build_592) + dm_build_600.dm_build_156(dm_build_599, Dm_build_42) + dm_build_600.dm_build_593 = dm_build_599.dm_build_1349 + return dm_build_600 +} + +func dm_build_601(dm_build_602 string, dm_build_603 string) int { + dm_build_604 := strings.Split(dm_build_602, ".") + dm_build_605 := strings.Split(dm_build_603, ".") + + for i, serStr := range dm_build_604 { + ser, _ := strconv.ParseInt(serStr, 10, 32) + global, _ := strconv.ParseInt(dm_build_605[i], 10, 32) + if ser < global { + return -1 + } else if ser == global { + continue + } else { + return 1 + } + } + + return 0 +} + +func (dm_build_607 *dm_build_592) dm_build_137() error { + + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1204(Dm_build_569, int32(0)) + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1204(Dm_build_570, int32(dm_build_607.dm_build_593.dmConnector.compress)) + + if dm_build_607.dm_build_593.dmConnector.loginEncrypt { + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_572, 2) + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_571, 1) + } else { + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_572, 0) + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_571, 0) + } + + if dm_build_607.dm_build_593.dmConnector.isBdtaRS { + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_573, Dm_build_123) + } else { + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_573, Dm_build_122) + } + + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_574, byte(dm_build_607.dm_build_593.dmConnector.compressID)) + + if dm_build_607.dm_build_593.dmConnector.loginCertificate != "" { + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_575, 1) + } else { + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_575, 0) + } + + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_576, 0) + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_577, 1) + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1224(Dm_build_578, uint16(dm_build_607.dm_build_593.MsgVersion)) + + dm_build_608 := dm_build_607.dm_build_593.getServerEncoding() + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1108(Dm_build_0, dm_build_608, dm_build_607.dm_build_152.dm_build_1349) + + var dm_build_609 byte + if dm_build_607.dm_build_593.dmConnector.uKeyName != "" { + dm_build_609 = 1 + } else { + dm_build_609 = 0 + } + + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1052(0) + + if dm_build_609 == 1 { + + } + + if dm_build_607.dm_build_593.dmConnector.loginEncrypt { + clientPubKey, err := dm_build_607.dm_build_152.dm_build_1596() + if err != nil { + return err + } + dm_build_607.dm_build_152.dm_build_1348.Dm_build_1096(clientPubKey) + } + + return nil +} + +func (dm_build_611 *dm_build_592) dm_build_140() error { + dm_build_611.dm_build_152.dm_build_1348.Dm_build_1026(0) + dm_build_611.dm_build_152.dm_build_1348.Dm_build_1034(Dm_build_43, false, true) + return nil +} + +func (dm_build_613 *dm_build_592) dm_build_141() (interface{}, error) { + + dm_build_613.dm_build_593.sslEncrypt = int(dm_build_613.dm_build_152.dm_build_1348.Dm_build_1282(Dm_build_579)) + dm_build_613.dm_build_593.GlobalServerSeries = int(dm_build_613.dm_build_152.dm_build_1348.Dm_build_1282(Dm_build_580)) + + switch dm_build_613.dm_build_152.dm_build_1348.Dm_build_1282(Dm_build_581) { + case 1: + dm_build_613.dm_build_593.serverEncoding = ENCODING_UTF8 + case 2: + dm_build_613.dm_build_593.serverEncoding = ENCODING_EUCKR + default: + dm_build_613.dm_build_593.serverEncoding = ENCODING_GB18030 + } + + dm_build_613.dm_build_593.dmConnector.compress = int(dm_build_613.dm_build_152.dm_build_1348.Dm_build_1282(Dm_build_582)) + dm_build_614 := dm_build_613.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_584) + dm_build_615 := dm_build_613.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_585) + dm_build_613.dm_build_593.dmConnector.isBdtaRS = dm_build_613.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_586) > 0 + dm_build_613.dm_build_593.dmConnector.compressID = int8(dm_build_613.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_587)) + + dm_build_613.dm_build_152.dm_build_1354 = dm_build_613.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_589) == 1 + dm_build_613.dm_build_593.dmConnector.newClientType = dm_build_613.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_590) == 1 + dm_build_613.dm_build_593.MsgVersion = int32(dm_build_613.dm_build_152.dm_build_1348.Dm_build_1297(Dm_build_591)) + + dm_build_616 := dm_build_613.dm_build_184() + if dm_build_616 != nil { + return nil, dm_build_616 + } + + dm_build_617 := dm_build_613.dm_build_152.dm_build_1348.Dm_build_1180(dm_build_613.dm_build_593.getServerEncoding(), dm_build_613.dm_build_152.dm_build_1349) + if dm_build_601(dm_build_617, Dm_build_1) < 0 { + return nil, ECGO_ERROR_SERVER_VERSION.throw() + } + + dm_build_613.dm_build_593.ServerVersion = dm_build_617 + dm_build_613.dm_build_593.Malini2 = dm_build_601(dm_build_617, Dm_build_2) > 0 + dm_build_613.dm_build_593.Execute2 = dm_build_601(dm_build_617, Dm_build_3) > 0 + dm_build_613.dm_build_593.LobEmptyCompOrcl = dm_build_601(dm_build_617, Dm_build_4) > 0 + + if dm_build_613.dm_build_152.dm_build_1349.dmConnector.uKeyName != "" { + dm_build_613.dm_build_597 = 1 + } else { + dm_build_613.dm_build_597 = 0 + } + + if dm_build_613.dm_build_597 == 1 { + dm_build_613.dm_build_152.dm_build_1355 = dm_build_613.dm_build_152.dm_build_1348.Dm_build_1175(16, dm_build_613.dm_build_593.getServerEncoding(), dm_build_613.dm_build_152.dm_build_1349) + } + + dm_build_613.dm_build_594 = -1 + dm_build_618 := false + dm_build_619 := false + dm_build_613.Dm_build_595 = -1 + if dm_build_615 > 0 { + dm_build_613.dm_build_594 = int(dm_build_613.dm_build_152.dm_build_1348.Dm_build_1138()) + } + + if dm_build_614 > 0 { + + if dm_build_613.dm_build_594 == -1 { + dm_build_618 = true + } else { + dm_build_619 = true + } + + dm_build_613.Dm_build_596 = dm_build_613.dm_build_152.dm_build_1348.Dm_build_1163() + } + + if dm_build_615 == 2 { + dm_build_613.Dm_build_595 = dm_build_613.dm_build_152.dm_build_1348.Dm_build_1138() + } + dm_build_613.dm_build_152.dm_build_1351 = dm_build_618 + dm_build_613.dm_build_152.dm_build_1352 = dm_build_619 + + return nil, nil +} + +type dm_build_620 struct { + dm_build_151 +} + +func dm_build_621(dm_build_622 *dm_build_1345, dm_build_623 *DmStatement) *dm_build_620 { + dm_build_624 := new(dm_build_620) + dm_build_624.dm_build_160(dm_build_622, Dm_build_18, dm_build_623) + return dm_build_624 +} + +func (dm_build_626 *dm_build_620) dm_build_137() error { + + dm_build_626.dm_build_152.dm_build_1348.Dm_build_1196(Dm_build_44, 1) + return nil +} + +func (dm_build_628 *dm_build_620) dm_build_141() (interface{}, error) { + + dm_build_628.dm_build_155.id = dm_build_628.dm_build_152.dm_build_1348.Dm_build_1282(Dm_build_45) + + dm_build_628.dm_build_155.readBaseColName = dm_build_628.dm_build_152.dm_build_1348.Dm_build_1276(Dm_build_44) == 1 + return nil, nil +} + +type dm_build_629 struct { + dm_build_151 + dm_build_630 int32 +} + +func dm_build_631(dm_build_632 *dm_build_1345, dm_build_633 int32) *dm_build_629 { + dm_build_634 := new(dm_build_629) + dm_build_634.dm_build_156(dm_build_632, Dm_build_19) + dm_build_634.dm_build_630 = dm_build_633 + return dm_build_634 +} + +func (dm_build_636 *dm_build_629) dm_build_138() { + dm_build_636.dm_build_151.dm_build_138() + dm_build_636.dm_build_152.dm_build_1348.Dm_build_1204(Dm_build_45, dm_build_636.dm_build_630) +} + +type dm_build_637 struct { + dm_build_151 + dm_build_638 []uint32 +} + +func dm_build_639(dm_build_640 *dm_build_1345, dm_build_641 []uint32) *dm_build_637 { + dm_build_642 := new(dm_build_637) + dm_build_642.dm_build_156(dm_build_640, Dm_build_39) + dm_build_642.dm_build_638 = dm_build_641 + return dm_build_642 +} + +func (dm_build_644 *dm_build_637) dm_build_137() error { + + dm_build_644.dm_build_152.dm_build_1348.Dm_build_1224(Dm_build_44, uint16(len(dm_build_644.dm_build_638))) + + for _, tableID := range dm_build_644.dm_build_638 { + dm_build_644.dm_build_152.dm_build_1348.Dm_build_1076(uint32(tableID)) + } + + return nil +} + +func (dm_build_646 *dm_build_637) dm_build_141() (interface{}, error) { + dm_build_647 := dm_build_646.dm_build_152.dm_build_1348.Dm_build_1297(Dm_build_44) + if dm_build_647 <= 0 { + return nil, nil + } + + dm_build_648 := make([]int64, dm_build_647) + for i := 0; i < int(dm_build_647); i++ { + dm_build_648[i] = dm_build_646.dm_build_152.dm_build_1348.Dm_build_1141() + } + + return dm_build_648, nil +} diff --git a/vendor/gitee.com/chunanyong/dm/zr.go b/vendor/gitee.com/chunanyong/dm/zr.go new file mode 100644 index 0000000000..9db4559a29 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zr.go @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "io" +) + +const ( + READ_LEN = Dm_build_127 +) + +type iOffRowBinder interface { + read(buf *Dm_build_931) + isReadOver() bool + getObj() interface{} +} + +type offRowBinder struct { + obj interface{} + encoding string + readOver bool + buffer *Dm_build_931 + 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_935(), + 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_936() > Dm_build_124 + return binder +} + +func (b *offRowBytesBinder) read(buf *Dm_build_931) { + if b.buffer.Dm_build_936() > 0 { + buf.Dm_build_968(b.buffer) + } else if !b.readOver { + var obj = b.obj.([]byte) + buf.Dm_build_957(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_936() > Dm_build_124 + return binder +} + +func (b *offRowBlobBinder) read(buf *Dm_build_931) { + if b.buffer.Dm_build_936() > 0 { + buf.Dm_build_968(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_957(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_936() > Dm_build_124 + return binder +} + +func (b *offRowClobBinder) read(buf *Dm_build_931) { + if b.buffer.Dm_build_936() > 0 { + buf.Dm_build_968(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_650.Dm_build_866(str, b.encoding, nil) + b.position += readLen + if b.position == int32(totalLen) { + b.readOver = true + } + buf.Dm_build_957(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_936() > Dm_build_124 + return binder +} + +func (b *offRowReaderBinder) read(buf *Dm_build_931) { + if b.buffer.Dm_build_936() > 0 { + buf.Dm_build_968(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_957(bytes[0:readLen], 0, readLen) + } +} + +func (b *offRowReaderBinder) readAll() []byte { + var byteArray = Dm_build_935() + b.read(byteArray) + for !b.readOver { + b.read(byteArray) + } + return byteArray.Dm_build_978() +} + +func (b *offRowReaderBinder) isReadOver() bool { + return b.readOver +} + +func (b *offRowReaderBinder) getObj() interface{} { + return b.obj +} diff --git a/vendor/gitee.com/chunanyong/dm/zs.go b/vendor/gitee.com/chunanyong/dm/zs.go new file mode 100644 index 0000000000..316b431018 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zs.go @@ -0,0 +1,882 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +import ( + "fmt" + "math" + "strconv" + "strings" + "time" + "unicode" + "unicode/utf8" + + "gitee.com/chunanyong/dm/util" +) + +type oracleDateFormat struct { + PM bool + TZNegative bool + pattern string + language int + scale int32 + 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 + maxLen := 0 + if FElement.len > 0 { + maxLen = FElement.len + } else { + maxLen = NANOSECOND_DIGITS + } + for i := offset; i < offset+maxLen && 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 < NANOSECOND_DIGITS { + ms *= int64(math.Pow10(NANOSECOND_DIGITS - strLen)) + } else { + ms /= int64(math.Pow10(strLen - NANOSECOND_DIGITS)) + } + + dt[OFFSET_NANOSECOND] = int(ms) + return offset + strLen, nil +} + +func (FElement fElement) format(dt []int) string { + msgLen := 0 + if FElement.len > 0 { + msgLen = FElement.len + } else { + msgLen = int(FElement.OracleDateFormat.scale) + } + return FElement.OracleDateFormat.formatMilliSecond(dt[OFFSET_NANOSECOND], msgLen) +} + +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, -1} + 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, scale int32, language int) string { + f := getFormat() + f.setPattern(pattern) + f.language = language + f.scale = scale + 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 = -1 + } + + OracleDateFormat.FElement.len = int(count) + return OracleDateFormat.FElement, nil + } + + return nil, nil +} diff --git a/vendor/gitee.com/chunanyong/dm/zv.go b/vendor/gitee.com/chunanyong/dm/zv.go new file mode 100644 index 0000000000..3029be0a73 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zv.go @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +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/vendor/gitee.com/chunanyong/dm/zw.go b/vendor/gitee.com/chunanyong/dm/zw.go new file mode 100644 index 0000000000..d84d81d1a7 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zw.go @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +import ( + "math/rand" + "strconv" + "time" + + "gitee.com/chunanyong/dm/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/vendor/gitee.com/chunanyong/dm/zx.go b/vendor/gitee.com/chunanyong/dm/zx.go new file mode 100644 index 0000000000..881118b89f --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zx.go @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "context" + "database/sql" + "database/sql/driver" + "errors" + "io" + "regexp" + "strings" + "time" + + "gitee.com/chunanyong/dm/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_101, Dm_build_102, Dm_build_106, Dm_build_113, Dm_build_112, Dm_build_104: + { + + if otherConn != nil { + execute2(otherConn) + } + } + case Dm_build_111: + { + + 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_110: + { + + 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_101, Dm_build_102, Dm_build_106, Dm_build_113, Dm_build_112, Dm_build_104: + { + + if otherStmt != nil { + RWUtil.copyStatement(curStmt, otherStmt) + execute2(otherStmt) + } + } + case Dm_build_111: + { + + 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_110: + { + + 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.serverParams = srcStmt.serverParams + destStmt.bindParams = srcStmt.bindParams + destStmt.paramCount = srcStmt.paramCount +} diff --git a/vendor/gitee.com/chunanyong/dm/zzj.go b/vendor/gitee.com/chunanyong/dm/zzj.go new file mode 100644 index 0000000000..6a5d85946c --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zzj.go @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +import ( + "database/sql" + "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 { + query := "SELECT NAME INTO ? FROM SYS.SYSOBJECTS WHERE ID=?" + + params := make([]driver.Value, 2) + var v string + params[0] = sql.Out{Dest: &v} + if SqlName.m_packId != 0 { + params[1] = SqlName.m_packId + } else { + params[1] = SqlName.m_schId + } + + rs, err := SqlName.m_conn.query(query, 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/vendor/gitee.com/chunanyong/dm/zzk.go b/vendor/gitee.com/chunanyong/dm/zzk.go new file mode 100644 index 0000000000..1dc2279873 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zzk.go @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "bytes" + "strconv" + "strings" + + "gitee.com/chunanyong/dm/parser" + + "gitee.com/chunanyong/dm/util" +) + +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_650.Dm_build_866(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/vendor/gitee.com/chunanyong/dm/zzl.go b/vendor/gitee.com/chunanyong/dm/zzl.go new file mode 100644 index 0000000000..e28795b4d6 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zzl.go @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +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/vendor/gitee.com/chunanyong/dm/zzm.go b/vendor/gitee.com/chunanyong/dm/zzm.go new file mode 100644 index 0000000000..c745ff3304 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zzm.go @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ + +package dm + +import ( + "bufio" + "io" + "os" + "runtime" + "strconv" + "strings" + + "gitee.com/chunanyong/dm/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" + + ENCODING_BIG5 string = "BIG5" + + DbAliveCheckFreqDef = 0 + + LocaleDef = LANGUAGE_CN + + // 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 { + key = strings.ToUpper(key) + if key == "ADDRESS_REMAP" { + tmp := props.GetString(AddressRemapKey, "") + props.Set(AddressRemapKey, tmp+"("+value+")") + } else if key == "ALWAYS_ALLOW_COMMIT" { + props.Set(AlwayseAllowCommitKey, value) + } else if key == "APP_NAME" { + props.Set(AppNameKey, value) + } else if key == "AUTO_COMMIT" { + props.Set(AutoCommitKey, value) + } else if key == "BATCH_ALLOW_MAX_ERRORS" { + props.Set(BatchAllowMaxErrorsKey, value) + } else if key == "BATCH_CONTINUE_ON_ERROR" || + key == "CONTINUE_BATCH_ON_ERROR" { + props.Set(ContinueBatchOnErrorKey, value) + } else if key == "BATCH_NOT_ON_CALL" { + props.Set(BatchNotOnCallKey, value) + } else if key == "BATCH_TYPE" { + props.Set(BatchTypeKey, value) + } else if key == "BUF_PREFETCH" { + props.Set(BufPrefetchKey, value) + } else if key == "CIPHER_PATH" { + props.Set(CipherPathKey, value) + } else if key == "CLUSTER" { + props.Set(ClusterKey, value) + } else if key == "COLUMN_NAME_UPPER_CASE" { + props.Set(ColumnNameUpperCaseKey, value) + } else if key == "COLUMN_NAME_CASE" { + props.Set(ColumnNameCaseKey, value) + } else if key == "COMPATIBLE_MODE" { + props.Set(CompatibleModeKey, value) + } else if key == "COMPRESS" || + key == "COMPRESS_MSG" { + props.Set(CompressKey, value) + } else if key == "COMPRESS_ID" { + props.Set(CompressIdKey, value) + } else if key == "CONNECT_TIMEOUT" { + props.Set(ConnectTimeoutKey, value) + } else if key == "DO_SWITCH" || + key == "AUTO_RECONNECT" { + props.Set(DoSwitchKey, value) + } else if key == "ENABLE_RS_CACHE" { + props.Set(EnRsCacheKey, value) + } else if key == "EP_SELECTION" { + props.Set(EpSelectorKey, value) + } else if key == "ESCAPE_PROCESS" { + props.Set(EscapeProcessKey, value) + } else if key == "IS_BDTA_RS" { + props.Set(IsBdtaRSKey, value) + } else if key == "KEY_WORDS" || + key == "KEYWORDS" { + props.Set(KeywordsKey, value) + } else if key == "LANGUAGE" { + props.Set(LanguageKey, value) + } else if key == "LOB_MODE" { + props.Set(LobModeKey, value) + } else if key == "LOG_BUFFER_SIZE" { + props.Set(LogBufferSizeKey, value) + } else if key == "LOG_DIR" { + props.Set(LogDirKey, value) + } else if key == "LOG_FLUSH_FREQ" { + props.Set(LogFlushFreqKey, value) + } else if key == "LOG_FLUSHER_QUEUESIZE" { + props.Set(LogFlusherQueueSizeKey, value) + } else if key == "LOG_LEVEL" { + props.Set(LogLevelKey, value) + } else if key == "LOGIN_DSC_CTRL" { + props.Set(LoginDscCtrlKey, value) + } else if key == "LOGIN_ENCRYPT" { + props.Set(LoginEncryptKey, value) + } else if key == "LOGIN_MODE" { + props.Set(LoginModeKey, value) + } else if key == "LOGIN_STATUS" { + props.Set(LoginStatusKey, value) + } else if key == "MAX_ROWS" { + props.Set(MaxRowsKey, value) + } else if key == "MPP_LOCAL" { + props.Set(MppLocalKey, value) + } else if key == "OS_NAME" { + props.Set(OsNameKey, value) + } else if key == "RS_CACHE_SIZE" { + props.Set(RsCacheSizeKey, value) + } else if key == "RS_REFRESH_FREQ" { + props.Set(RsRefreshFreqKey, value) + } else if key == "RW_HA" { + props.Set(RwHAKey, value) + } else if key == "RW_IGNORE_SQL" { + props.Set(RwIgnoreSqlKey, value) + } else if key == "RW_PERCENT" { + props.Set(RwPercentKey, value) + } else if key == "RW_SEPARATE" { + props.Set(RwSeparateKey, value) + } else if key == "RW_STANDBY_RECOVER_TIME" { + props.Set(RwStandbyRecoverTimeKey, value) + } else if key == "SCHEMA" { + props.Set(SchemaKey, value) + } else if key == "SESS_ENCODE" { + if IsSupportedCharset(value) { + props.Set("sessEncode", value) + } + } else if key == "SESSION_TIMEOUT" { + props.Set(SessionTimeoutKey, value) + } else if key == "SOCKET_TIMEOUT" { + props.Set(SocketTimeoutKey, value) + } else if key == "SSL_CERT_PATH" { + props.Set(SslCertPathKey, value) + } else if key == "SSL_FILES_PATH" { + props.Set(SslFilesPathKey, value) + } else if key == "SSL_KEY_PATH" { + props.Set(SslKeyPathKey, value) + } else if key == "STAT_DIR" { + props.Set(StatDirKey, value) + } else if key == "STAT_ENABLE" { + props.Set(StatEnableKey, value) + } else if key == "STAT_FLUSH_FREQ" { + props.Set(StatFlushFreqKey, value) + } else if key == "STAT_HIGH_FREQ_SQL_COUNT" { + props.Set(StatHighFreqSqlCountKey, value) + } else if key == "STAT_SLOW_SQL_COUNT" { + props.Set(StatSlowSqlCountKey, value) + } else if key == "STAT_SQL_MAX_COUNT" { + props.Set(StatSqlMaxCountKey, value) + } else if key == "STAT_SQL_REMOVE_MODE" { + props.Set(StatSqlRemoveModeKey, value) + } else if key == "SWITCH_INTERVAL" { + props.Set(SwitchIntervalKey, value) + } else if key == "SWITCH_TIME" || + key == "SWITCH_TIMES" { + props.Set(SwitchTimesKey, value) + } else if key == "TIME_ZONE" { + props.Set(TimeZoneKey, value) + props.Set("localTimezone", value) + } else if 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 + } else if util.StringUtil.EqualsIgnoreCase("cnt_hk", value) || + util.StringUtil.EqualsIgnoreCase("hk", value) || + util.StringUtil.EqualsIgnoreCase("tw", value) { + Locale = 2 + } +} + +func IsSupportedCharset(charset string) bool { + if util.StringUtil.EqualsIgnoreCase(ENCODING_UTF8, charset) || + util.StringUtil.EqualsIgnoreCase(ENCODING_GB18030, charset) || + util.StringUtil.EqualsIgnoreCase(ENCODING_EUCKR, charset) || + util.StringUtil.EqualsIgnoreCase(ENCODING_BIG5, 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/vendor/gitee.com/chunanyong/dm/zzn.go b/vendor/gitee.com/chunanyong/dm/zzn.go new file mode 100644 index 0000000000..c9c41e23c8 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zzn.go @@ -0,0 +1,442 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +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 + + XDEC_INT32 = 24 + + XDEC_INT64 = 25 + + DATETIME2 = 26 + + DATETIME2_TZ = 27 + + NULL = 28 + + 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 + + DATETIME2_PREC = 9 + + TIME_TZ_PREC = TIME_PREC + 2 + + DATETIME_TZ_PREC = DATETIME_PREC + 2 + + DATETIME2_TZ_PREC = DATETIME2_PREC + 2 + + INTERVAL_YM_PREC = 3 * ULINT_SIZE + + INTERVAL_DT_PREC = 6 * ULINT_SIZE + + 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 + + LOCAL_DATETIME_SCALE_MASK int32 = 0x00001000 + + ORACLE_FLOAT_SCALE_MASK int32 = 0x81 + + ORACLE_DATE_SCALE_MASK int32 = 0x00002000 +) + +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 || colType == DATETIME2) && (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 == int(ORACLE_FLOAT_SCALE_MASK) +} + +func getFloatPrec(prec int) int { + return int(math.Round(float64(prec)*0.30103)) + 1 +} + +func getFloatScale(scale int) int { + return scale & (^int(ORACLE_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, TIME_TZ, DATETIME, DATETIME_TZ, DATETIME2, DATETIME2_TZ: + 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, VARBINARY, BLOB, CHAR, VARCHAR2, VARCHAR, CLOB: + return int64(column.prec), true + } + + return int64(0), false +} + +func (column *column) PrecisionScale() (precision, scale int64, ok bool) { + switch column.colType { + case DECIMAL: + if column.prec == 0 { + return 38, int64(column.scale), true + } else { + 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_650.Dm_build_747(bytes, 0), nil + case INT: + return Dm_build_650.Dm_build_752(bytes, 0), nil + case BIGINT: + return Dm_build_650.Dm_build_757(bytes, 0), nil + case REAL: + return Dm_build_650.Dm_build_762(bytes, 0), nil + case DOUBLE: + + return Dm_build_650.Dm_build_766(bytes, 0), nil + case DATE, TIME, DATETIME, TIME_TZ, DATETIME_TZ, DATETIME2, DATETIME2_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: + if isComplexType(int(column.colType), int(column.scale)) { + return DB2G.toComplexType(bytes, column, conn) + } + blob := DB2G.toDmBlob(bytes, column, conn) + + l, err := blob.GetLength() + if err != nil { + return nil, err + } + return blob.getBytes(1, int32(l)) + + case CHAR, VARCHAR2, VARCHAR: + return Dm_build_650.Dm_build_807(bytes, 0, len(bytes), conn.getServerEncoding(), conn), nil + case CLOB: + clob := DB2G.toDmClob(bytes, conn, column) + + l, err := clob.GetLength() + if err != nil { + return nil, err + } + return clob.getSubString(1, int32(l)) + + } + + 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, DATETIME2, DATETIME2_TZ: + return true + default: + return false + } +} diff --git a/vendor/gitee.com/chunanyong/dm/zzo.go b/vendor/gitee.com/chunanyong/dm/zzo.go new file mode 100644 index 0000000000..9f3abea822 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zzo.go @@ -0,0 +1,1389 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +import ( + "strconv" + + "gitee.com/chunanyong/dm/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_650.Dm_build_866(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_650.Dm_build_651(innerData, 0, byte(0)) + Dm_build_650.Dm_build_651(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_650.Dm_build_651(result, 0, byte(0)) + offset = 1 + + Dm_build_650.Dm_build_651(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_650.Dm_build_651(result, 0, byte(0)) + offset = 1 + + Dm_build_650.Dm_build_651(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_650.Dm_build_651(result, 0, byte(0)) + offset = 1 + + Dm_build_650.Dm_build_651(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_650.Dm_build_651(result, 0, byte(0)) + offset = 1 + + Dm_build_650.Dm_build_651(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_650.Dm_build_651(result, 0, byte(0)) + offset = 1 + + Dm_build_650.Dm_build_651(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_650.Dm_build_651(innerData, 0, byte(0)) + if data.m_dataBuf != nil && len(data.m_dataBuf) > 0 { + Dm_build_650.Dm_build_651(innerData, 1, data.m_dataBuf[0]) + } else { + Dm_build_650.Dm_build_651(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_650.Dm_build_651(result, 0, byte(0)) + offset = 1 + + Dm_build_650.Dm_build_651(result, offset, byte(1)) + offset += 1 + + Dm_build_650.Dm_build_661(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_650.Dm_build_666(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_650.Dm_build_866(subString, serverEncoding, nil) + ret = make([]byte, len(tmp)+ULINT_SIZE) + Dm_build_650.Dm_build_666(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_650.Dm_build_666(rdata, off, int32(totalLen)) + off += ULINT_SIZE + + Dm_build_650.Dm_build_666(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_650.Dm_build_651(rdata, offset, byte(0)) + offset += BYTE_SIZE + + offset += ULINT_SIZE + + Dm_build_650.Dm_build_661(rdata, offset, int16(desc.getCltnType())) + offset += USINT_SIZE + + Dm_build_650.Dm_build_661(rdata, offset, int16(desc.m_arrObj.getDType())) + offset += USINT_SIZE + + Dm_build_650.Dm_build_666(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_650.Dm_build_666(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_650.Dm_build_666(rdata, 0, int32(totalLen)) + offset := ULINT_SIZE + + Dm_build_650.Dm_build_666(rdata, offset, int32(len(data.m_arrData))) + offset += ULINT_SIZE + + Dm_build_650.Dm_build_666(rdata, offset, 0) + offset += ULINT_SIZE + + Dm_build_650.Dm_build_666(rdata, offset, int32(data.m_objCount)) + offset += ULINT_SIZE + + Dm_build_650.Dm_build_666(rdata, offset, int32(data.m_strCount)) + offset += ULINT_SIZE + + for i := 0; i < total; i++ { + Dm_build_650.Dm_build_666(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_650.Dm_build_651(rdata, offset, byte(0)) + offset += BYTE_SIZE + + Dm_build_650.Dm_build_666(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_650.Dm_build_666(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_650.Dm_build_752(val, offset) + offset += ULINT_SIZE + + tmp := Dm_build_650.Dm_build_801(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_650.Dm_build_752(val, offset) + offset += ULINT_SIZE + + tmp := Dm_build_650.Dm_build_801(val, offset, int(l)) + offset += int(l) + out.m_offset = offset + + return newTypeData(newClobOfLocal(Dm_build_650.Dm_build_807(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_650.Dm_build_743(val, offset) + offset += 1 + + out.m_offset = offset + + if desc.getDType() == BOOLEAN { + b := false + if null_flag != byte(0) { + b = true + } + + tmp := Dm_build_650.Dm_build_801(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_650.Dm_build_801(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_650.Dm_build_801(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_650.Dm_build_801(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_650.Dm_build_801(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_650.Dm_build_743(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_650.Dm_build_752(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_650.Dm_build_801(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_650.Dm_build_752(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_650.Dm_build_801(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_650.Dm_build_747(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_650.Dm_build_752(val, offset)) + offset += 4 + + arrOut.m_itemCount = int(Dm_build_650.Dm_build_752(val, offset)) + offset += ULINT_SIZE + + arrOut.m_itemSize = int(Dm_build_650.Dm_build_752(val, offset)) + offset += ULINT_SIZE + + arrOut.m_objCount = int(Dm_build_650.Dm_build_752(val, offset)) + offset += ULINT_SIZE + + arrOut.m_strCount = int(Dm_build_650.Dm_build_752(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_650.Dm_build_752(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_650.Dm_build_801(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_650.Dm_build_752(val, offset)) + offset += ULINT_SIZE + + arrOut.m_itemCount = int(Dm_build_650.Dm_build_752(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_650.Dm_build_801(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_650.Dm_build_752(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_fieldsObj[i]) + if err != nil { + return nil, err + } + strOut.m_attribs[i] = *tmp + } + + strOut.m_dataBuf = Dm_build_650.Dm_build_801(val, offset, out.m_offset-offset) + + return strOut, nil +} + +func (sv TypeData) objBlob_GetChkBuf(buf []byte, typeData *TypeData) { + + offset := 4 + + l := int(Dm_build_650.Dm_build_752(buf, offset)) + offset += ULINT_SIZE + + typeData.m_objBlobDescBuf = Dm_build_650.Dm_build_801(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_650.Dm_build_752(lobBuf, offset) + offset += ULINT_SIZE + + if OBJ_BLOB_MAGIC != magic { + return nil, ECGO_INVALID_OBJ_BLOB.throw() + } + + descLen := int(Dm_build_650.Dm_build_752(lobBuf, offset)) + offset += ULINT_SIZE + descBuf := Dm_build_650.Dm_build_801(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_650.Dm_build_774(val, offset)) + offset += USINT_SIZE + + if valueLen == int(Dm_build_60) { + valueLen = 0 + isNull = true + } + + if -1 == valueLen { + valueLen = int(Dm_build_650.Dm_build_752(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_650.Dm_build_801(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, DATETIME2, DATETIME2_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_650.Dm_build_666(ret, 0, OBJ_BLOB_MAGIC) + Dm_build_650.Dm_build_666(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+len(desc):ULINT_SIZE+ULINT_SIZE+len(desc)+len(data)], data[: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_650.Dm_build_666(ret, 0, OBJ_BLOB_MAGIC) + Dm_build_650.Dm_build_666(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+len(desc):ULINT_SIZE+ULINT_SIZE+len(desc)+len(data)], data[:len(data)]) + return ret, nil +} diff --git a/vendor/gitee.com/chunanyong/dm/zzp.go b/vendor/gitee.com/chunanyong/dm/zzp.go new file mode 100644 index 0000000000..449e308248 --- /dev/null +++ b/vendor/gitee.com/chunanyong/dm/zzp.go @@ -0,0 +1,763 @@ +/* + * Copyright (c) 2000-2018, 达梦数据库有限公司. + * All rights reserved. + */ +package dm + +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_1014(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_1009) 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_1064(typeDesc.column.colType) + + msg.Dm_build_1064(typeDesc.column.prec) + + msg.Dm_build_1064(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_650.Dm_build_866(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_1009) error { + + msg.Dm_build_1064(arrDesc.column.colType) + + msg.Dm_build_1120(arrDesc.m_sqlName.m_name, arrDesc.getServerEncoding(), arrDesc.m_conn) + + msg.Dm_build_1064(int32(arrDesc.m_objId)) + + msg.Dm_build_1064(int32(arrDesc.m_objVersion)) + + msg.Dm_build_1064(int32(arrDesc.m_length)) + + return pack(arrDesc.m_arrObj, msg) +} + +func packRecord(strctDesc *TypeDescriptor, msg *Dm_build_1009) error { + + msg.Dm_build_1064(strctDesc.column.colType) + + msg.Dm_build_1120(strctDesc.m_sqlName.m_name, strctDesc.getServerEncoding(), strctDesc.m_conn) + + msg.Dm_build_1064(int32(strctDesc.m_objId)) + + msg.Dm_build_1064(int32(strctDesc.m_objVersion)) + + msg.Dm_build_1060(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_650.Dm_build_866(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_650.Dm_build_866(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_1009) error { + + msg.Dm_build_1064(strctDesc.column.colType) + + msg.Dm_build_1120(strctDesc.m_sqlName.m_name, strctDesc.getServerEncoding(), strctDesc.m_conn) + + msg.Dm_build_1064(int32(strctDesc.m_objId)) + + msg.Dm_build_1064(int32(strctDesc.m_objVersion)) + + if strctDesc.m_objId == 4 { + + msg.Dm_build_1064(int32(strctDesc.m_outerId)) + + msg.Dm_build_1064(int32(strctDesc.m_outerVer)) + + msg.Dm_build_1064(int32(strctDesc.m_subId)) + + } + + return nil +} + +func (typeDescriptor *TypeDescriptor) unpack(buffer *Dm_build_1009) error { + + typeDescriptor.column.colType = buffer.Dm_build_1138() + + 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_1138() + + typeDescriptor.column.scale = buffer.Dm_build_1138() + return nil +} + +func (typeDescriptor *TypeDescriptor) unpackArray(buffer *Dm_build_1009) error { + + typeDescriptor.m_sqlName.m_name = buffer.Dm_build_1188(typeDescriptor.getServerEncoding(), typeDescriptor.m_conn) + + typeDescriptor.m_sqlName.m_schId = int(buffer.Dm_build_1138()) + + typeDescriptor.m_sqlName.m_packId = int(buffer.Dm_build_1138()) + + typeDescriptor.m_objId = int(buffer.Dm_build_1138()) + + typeDescriptor.m_objVersion = int(buffer.Dm_build_1138()) + + typeDescriptor.m_length = int(buffer.Dm_build_1138()) + 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_1009) error { + + typeDescriptor.m_sqlName.m_name = buffer.Dm_build_1188(typeDescriptor.getServerEncoding(), typeDescriptor.m_conn) + + typeDescriptor.m_sqlName.m_schId = int(buffer.Dm_build_1138()) + + typeDescriptor.m_sqlName.m_packId = int(buffer.Dm_build_1138()) + + typeDescriptor.m_objId = int(buffer.Dm_build_1138()) + + typeDescriptor.m_objVersion = int(buffer.Dm_build_1138()) + + typeDescriptor.m_size = int(buffer.Dm_build_1153()) + + 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_1009) error { + + typeDescriptor.m_maxCnt = int(buffer.Dm_build_1138()) + + typeDescriptor.m_arrObj = newTypeDescriptor(typeDescriptor.m_conn) + + typeDescriptor.m_arrObj.unpack(buffer) + + return nil +} + +func (typeDescriptor *TypeDescriptor) unpackClnt(buffer *Dm_build_1009) error { + + typeDescriptor.m_outerId = int(buffer.Dm_build_1138()) + + typeDescriptor.m_outerVer = int(buffer.Dm_build_1138()) + + typeDescriptor.m_subId = int(buffer.Dm_build_1153()) + + typeDescriptor.m_cltnType = int(buffer.Dm_build_1153()) + + 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_1009) error { + + typeDescriptor.m_sqlName.m_name = buffer.Dm_build_1188(typeDescriptor.getServerEncoding(), typeDescriptor.m_conn) + + typeDescriptor.m_sqlName.m_schId = int(buffer.Dm_build_1138()) + + typeDescriptor.m_sqlName.m_packId = int(buffer.Dm_build_1138()) + + typeDescriptor.m_objId = int(buffer.Dm_build_1138()) + + typeDescriptor.m_objVersion = int(buffer.Dm_build_1138()) + + if typeDescriptor.m_objId == 4 { + return typeDescriptor.unpackClnt(buffer) + } else { + + typeDescriptor.m_size = int(buffer.Dm_build_1153()) + + 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_650.Dm_build_661(typeDescriptor.m_descBuf, offset, ARRAY) + offset += USINT_SIZE + + Dm_build_650.Dm_build_666(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_650.Dm_build_661(typeDescriptor.m_descBuf, offset, PLTYPE_RECORD) + offset += USINT_SIZE + + Dm_build_650.Dm_build_661(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_650.Dm_build_661(typeDescriptor.m_descBuf, offset, dtype) + offset += USINT_SIZE + + Dm_build_650.Dm_build_661(typeDescriptor.m_descBuf, offset, int16(prec)) + offset += USINT_SIZE + + Dm_build_650.Dm_build_661(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_650.Dm_build_661(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_650.Dm_build_661(typeDescriptor.m_descBuf, offset, int16(desc.m_cltnType)) + offset += USINT_SIZE + + Dm_build_650.Dm_build_666(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_650.Dm_build_661(typeDescriptor.m_descBuf, offset, CLASS) + offset += USINT_SIZE + + isClnt := false + if desc.m_objId == 4 { + isClnt = true + } + + if isClnt { + Dm_build_650.Dm_build_651(typeDescriptor.m_descBuf, offset, byte(1)) + } else { + Dm_build_650.Dm_build_651(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/vendor/golang.org/x/text/encoding/ianaindex/ascii.go b/vendor/golang.org/x/text/encoding/ianaindex/ascii.go new file mode 100644 index 0000000000..2b9824f826 --- /dev/null +++ b/vendor/golang.org/x/text/encoding/ianaindex/ascii.go @@ -0,0 +1,74 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ianaindex + +import ( + "unicode" + "unicode/utf8" + + "golang.org/x/text/encoding" + "golang.org/x/text/encoding/internal" + "golang.org/x/text/encoding/internal/identifier" + "golang.org/x/text/transform" +) + +type asciiDecoder struct { + transform.NopResetter +} + +func (d asciiDecoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { + for _, c := range src { + if c > unicode.MaxASCII { + r := unicode.ReplacementChar + if nDst+utf8.RuneLen(r) > len(dst) { + err = transform.ErrShortDst + break + } + nDst += utf8.EncodeRune(dst[nDst:], r) + nSrc++ + continue + } + + if nDst >= len(dst) { + err = transform.ErrShortDst + break + } + dst[nDst] = c + nDst++ + nSrc++ + } + return nDst, nSrc, err +} + +type asciiEncoder struct { + transform.NopResetter +} + +func (d asciiEncoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { + for _, c := range src { + if c > unicode.MaxASCII { + err = internal.RepertoireError(encoding.ASCIISub) + break + } + + if nDst >= len(dst) { + err = transform.ErrShortDst + break + } + dst[nDst] = c + nDst++ + nSrc++ + } + return nDst, nSrc, err +} + +var asciiEnc = &internal.Encoding{ + Encoding: &internal.SimpleEncoding{ + asciiDecoder{}, + asciiEncoder{}, + }, + Name: "US-ASCII", + MIB: identifier.ASCII, +} diff --git a/vendor/golang.org/x/text/encoding/ianaindex/ianaindex.go b/vendor/golang.org/x/text/encoding/ianaindex/ianaindex.go new file mode 100644 index 0000000000..f4b18875c8 --- /dev/null +++ b/vendor/golang.org/x/text/encoding/ianaindex/ianaindex.go @@ -0,0 +1,214 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:generate go run gen.go + +// Package ianaindex maps names to Encodings as specified by the IANA registry. +// This includes both the MIME and IANA names. +// +// See http://www.iana.org/assignments/character-sets/character-sets.xhtml for +// more details. +package ianaindex + +import ( + "errors" + "sort" + "strings" + + "golang.org/x/text/encoding" + "golang.org/x/text/encoding/charmap" + "golang.org/x/text/encoding/internal/identifier" + "golang.org/x/text/encoding/japanese" + "golang.org/x/text/encoding/korean" + "golang.org/x/text/encoding/simplifiedchinese" + "golang.org/x/text/encoding/traditionalchinese" + "golang.org/x/text/encoding/unicode" +) + +// TODO: remove the "Status... incomplete" in the package doc comment. +// TODO: allow users to specify their own aliases? +// TODO: allow users to specify their own indexes? +// TODO: allow canonicalizing names + +// NOTE: only use these top-level variables if we can get the linker to drop +// the indexes when they are not used. Make them a function or perhaps only +// support MIME otherwise. + +var ( + // MIME is an index to map MIME names. + MIME *Index = mime + + // IANA is an index that supports all names and aliases using IANA names as + // the canonical identifier. + IANA *Index = iana + + // MIB is an index that associates the MIB display name with an Encoding. + MIB *Index = mib + + mime = &Index{mimeName, ianaToMIB, ianaAliases, encodings[:]} + iana = &Index{ianaName, ianaToMIB, ianaAliases, encodings[:]} + mib = &Index{mibName, ianaToMIB, ianaAliases, encodings[:]} +) + +// Index maps names registered by IANA to Encodings. +// Currently different Indexes only differ in the names they return for +// encodings. In the future they may also differ in supported aliases. +type Index struct { + names func(i int) string + toMIB []identifier.MIB // Sorted slice of supported MIBs + alias map[string]int + enc []encoding.Encoding +} + +var ( + errInvalidName = errors.New("ianaindex: invalid encoding name") + errUnknown = errors.New("ianaindex: unknown Encoding") + errUnsupported = errors.New("ianaindex: unsupported Encoding") +) + +// Encoding returns an Encoding for IANA-registered names. Matching is +// case-insensitive. +// +// If the provided name doesn't match a IANA-registered charset, an error is +// returned. If the name matches a IANA-registered charset but isn't supported, +// a nil encoding and a nil error are returned. +func (x *Index) Encoding(name string) (encoding.Encoding, error) { + name = strings.TrimSpace(name) + // First try without lowercasing (possibly creating an allocation). + i, ok := x.alias[name] + if !ok { + i, ok = x.alias[strings.ToLower(name)] + if !ok { + return nil, errInvalidName + } + } + return x.enc[i], nil +} + +// Name reports the canonical name of the given Encoding. It will return an +// error if the e is not associated with a known encoding scheme. +func (x *Index) Name(e encoding.Encoding) (string, error) { + id, ok := e.(identifier.Interface) + if !ok { + return "", errUnknown + } + mib, _ := id.ID() + if mib == 0 { + return "", errUnknown + } + v := findMIB(x.toMIB, mib) + if v == -1 { + return "", errUnsupported + } + return x.names(v), nil +} + +// TODO: the coverage of this index is rather spotty. Allowing users to set +// encodings would allow: +// - users to increase coverage +// - allow a partially loaded set of encodings in case the user doesn't need to +// them all. +// - write an OS-specific wrapper for supported encodings and set them. +// The exact definition of Set depends a bit on if and how we want to let users +// write their own Encoding implementations. Also, it is not possible yet to +// only partially load the encodings without doing some refactoring. Until this +// is solved, we might as well not support Set. +// // Set sets the e to be used for the encoding scheme identified by name. Only +// // canonical names may be used. An empty name assigns e to its internally +// // associated encoding scheme. +// func (x *Index) Set(name string, e encoding.Encoding) error { +// panic("TODO: implement") +// } + +func findMIB(x []identifier.MIB, mib identifier.MIB) int { + i := sort.Search(len(x), func(i int) bool { return x[i] >= mib }) + if i < len(x) && x[i] == mib { + return i + } + return -1 +} + +const maxMIMENameLen = '0' - 1 // officially 40, but we leave some buffer. + +func mimeName(x int) string { + n := ianaNames[x] + // See gen.go for a description of the encoding. + if n[0] <= maxMIMENameLen { + return n[1:n[0]] + } + return n +} + +func ianaName(x int) string { + n := ianaNames[x] + // See gen.go for a description of the encoding. + if n[0] <= maxMIMENameLen { + return n[n[0]:] + } + return n +} + +func mibName(x int) string { + return mibNames[x] +} + +var encodings = [numIANA]encoding.Encoding{ + enc3: asciiEnc, + enc106: unicode.UTF8, + enc1015: unicode.UTF16(unicode.BigEndian, unicode.UseBOM), + enc1013: unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM), + enc1014: unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM), + enc2028: charmap.CodePage037, + enc2011: charmap.CodePage437, + enc2009: charmap.CodePage850, + enc2010: charmap.CodePage852, + enc2046: charmap.CodePage855, + enc2089: charmap.CodePage858, + enc2048: charmap.CodePage860, + enc2013: charmap.CodePage862, + enc2050: charmap.CodePage863, + enc2052: charmap.CodePage865, + enc2086: charmap.CodePage866, + enc2102: charmap.CodePage1047, + enc2091: charmap.CodePage1140, + enc4: charmap.ISO8859_1, + enc5: charmap.ISO8859_2, + enc6: charmap.ISO8859_3, + enc7: charmap.ISO8859_4, + enc8: charmap.ISO8859_5, + enc9: charmap.ISO8859_6, + enc81: charmap.ISO8859_6E, + enc82: charmap.ISO8859_6I, + enc10: charmap.ISO8859_7, + enc11: charmap.ISO8859_8, + enc84: charmap.ISO8859_8E, + enc85: charmap.ISO8859_8I, + enc12: charmap.ISO8859_9, + enc13: charmap.ISO8859_10, + enc109: charmap.ISO8859_13, + enc110: charmap.ISO8859_14, + enc111: charmap.ISO8859_15, + enc112: charmap.ISO8859_16, + enc2084: charmap.KOI8R, + enc2088: charmap.KOI8U, + enc2027: charmap.Macintosh, + enc2109: charmap.Windows874, + enc2250: charmap.Windows1250, + enc2251: charmap.Windows1251, + enc2252: charmap.Windows1252, + enc2253: charmap.Windows1253, + enc2254: charmap.Windows1254, + enc2255: charmap.Windows1255, + enc2256: charmap.Windows1256, + enc2257: charmap.Windows1257, + enc2258: charmap.Windows1258, + enc18: japanese.EUCJP, + enc39: japanese.ISO2022JP, + enc17: japanese.ShiftJIS, + enc38: korean.EUCKR, + enc114: simplifiedchinese.GB18030, + enc113: simplifiedchinese.GBK, + enc2085: simplifiedchinese.HZGB2312, + enc2026: traditionalchinese.Big5, +} diff --git a/vendor/golang.org/x/text/encoding/ianaindex/tables.go b/vendor/golang.org/x/text/encoding/ianaindex/tables.go new file mode 100644 index 0000000000..921bb3b4b3 --- /dev/null +++ b/vendor/golang.org/x/text/encoding/ianaindex/tables.go @@ -0,0 +1,2355 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package ianaindex + +import "golang.org/x/text/encoding/internal/identifier" + +const ( + enc3 = iota + enc4 + enc5 + enc6 + enc7 + enc8 + enc9 + enc10 + enc11 + enc12 + enc13 + enc14 + enc15 + enc16 + enc17 + enc18 + enc19 + enc20 + enc21 + enc22 + enc23 + enc24 + enc25 + enc26 + enc27 + enc28 + enc29 + enc30 + enc31 + enc32 + enc33 + enc34 + enc35 + enc36 + enc37 + enc38 + enc39 + enc40 + enc41 + enc42 + enc43 + enc44 + enc45 + enc46 + enc47 + enc48 + enc49 + enc50 + enc51 + enc52 + enc53 + enc54 + enc55 + enc56 + enc57 + enc58 + enc59 + enc60 + enc61 + enc62 + enc63 + enc64 + enc65 + enc66 + enc67 + enc68 + enc69 + enc70 + enc71 + enc72 + enc73 + enc74 + enc75 + enc76 + enc77 + enc78 + enc79 + enc80 + enc81 + enc82 + enc83 + enc84 + enc85 + enc86 + enc87 + enc88 + enc89 + enc90 + enc91 + enc92 + enc93 + enc94 + enc95 + enc96 + enc97 + enc98 + enc99 + enc100 + enc101 + enc102 + enc103 + enc104 + enc105 + enc106 + enc109 + enc110 + enc111 + enc112 + enc113 + enc114 + enc115 + enc116 + enc117 + enc118 + enc119 + enc1000 + enc1001 + enc1002 + enc1003 + enc1004 + enc1005 + enc1006 + enc1007 + enc1008 + enc1009 + enc1010 + enc1011 + enc1012 + enc1013 + enc1014 + enc1015 + enc1016 + enc1017 + enc1018 + enc1019 + enc1020 + enc1021 + enc2000 + enc2001 + enc2002 + enc2003 + enc2004 + enc2005 + enc2006 + enc2007 + enc2008 + enc2009 + enc2010 + enc2011 + enc2012 + enc2013 + enc2014 + enc2015 + enc2016 + enc2017 + enc2018 + enc2019 + enc2020 + enc2021 + enc2022 + enc2023 + enc2024 + enc2025 + enc2026 + enc2027 + enc2028 + enc2029 + enc2030 + enc2031 + enc2032 + enc2033 + enc2034 + enc2035 + enc2036 + enc2037 + enc2038 + enc2039 + enc2040 + enc2041 + enc2042 + enc2043 + enc2044 + enc2045 + enc2046 + enc2047 + enc2048 + enc2049 + enc2050 + enc2051 + enc2052 + enc2053 + enc2054 + enc2055 + enc2056 + enc2057 + enc2058 + enc2059 + enc2060 + enc2061 + enc2062 + enc2063 + enc2064 + enc2065 + enc2066 + enc2067 + enc2068 + enc2069 + enc2070 + enc2071 + enc2072 + enc2073 + enc2074 + enc2075 + enc2076 + enc2077 + enc2078 + enc2079 + enc2080 + enc2081 + enc2082 + enc2083 + enc2084 + enc2085 + enc2086 + enc2087 + enc2088 + enc2089 + enc2090 + enc2091 + enc2092 + enc2093 + enc2094 + enc2095 + enc2096 + enc2097 + enc2098 + enc2099 + enc2100 + enc2101 + enc2102 + enc2103 + enc2104 + enc2105 + enc2106 + enc2107 + enc2108 + enc2109 + enc2250 + enc2251 + enc2252 + enc2253 + enc2254 + enc2255 + enc2256 + enc2257 + enc2258 + enc2259 + enc2260 + numIANA +) + +var ianaToMIB = []identifier.MIB{ // 258 elements + // Entry 0 - 3F + 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, + 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, + 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, + 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, + 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, + 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, + 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, + 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, + // Entry 40 - 7F + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, + 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x03e8, 0x03e9, 0x03ea, 0x03eb, 0x03ec, + 0x03ed, 0x03ee, 0x03ef, 0x03f0, 0x03f1, 0x03f2, 0x03f3, 0x03f4, + // Entry 80 - BF + 0x03f5, 0x03f6, 0x03f7, 0x03f8, 0x03f9, 0x03fa, 0x03fb, 0x03fc, + 0x03fd, 0x07d0, 0x07d1, 0x07d2, 0x07d3, 0x07d4, 0x07d5, 0x07d6, + 0x07d7, 0x07d8, 0x07d9, 0x07da, 0x07db, 0x07dc, 0x07dd, 0x07de, + 0x07df, 0x07e0, 0x07e1, 0x07e2, 0x07e3, 0x07e4, 0x07e5, 0x07e6, + 0x07e7, 0x07e8, 0x07e9, 0x07ea, 0x07eb, 0x07ec, 0x07ed, 0x07ee, + 0x07ef, 0x07f0, 0x07f1, 0x07f2, 0x07f3, 0x07f4, 0x07f5, 0x07f6, + 0x07f7, 0x07f8, 0x07f9, 0x07fa, 0x07fb, 0x07fc, 0x07fd, 0x07fe, + 0x07ff, 0x0800, 0x0801, 0x0802, 0x0803, 0x0804, 0x0805, 0x0806, + // Entry C0 - FF + 0x0807, 0x0808, 0x0809, 0x080a, 0x080b, 0x080c, 0x080d, 0x080e, + 0x080f, 0x0810, 0x0811, 0x0812, 0x0813, 0x0814, 0x0815, 0x0816, + 0x0817, 0x0818, 0x0819, 0x081a, 0x081b, 0x081c, 0x081d, 0x081e, + 0x081f, 0x0820, 0x0821, 0x0822, 0x0823, 0x0824, 0x0825, 0x0826, + 0x0827, 0x0828, 0x0829, 0x082a, 0x082b, 0x082c, 0x082d, 0x082e, + 0x082f, 0x0830, 0x0831, 0x0832, 0x0833, 0x0834, 0x0835, 0x0836, + 0x0837, 0x0838, 0x0839, 0x083a, 0x083b, 0x083c, 0x083d, 0x08ca, + 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x08cf, 0x08d0, 0x08d1, 0x08d2, + // Entry 100 - 13F + 0x08d3, 0x08d4, +} // Size: 540 bytes + +var ianaNames = []string{ // 258 elements + "US-ASCII", + "\vISO-8859-1ISO_8859-1:1987", + "\vISO-8859-2ISO_8859-2:1987", + "\vISO-8859-3ISO_8859-3:1988", + "\vISO-8859-4ISO_8859-4:1988", + "\vISO-8859-5ISO_8859-5:1988", + "\vISO-8859-6ISO_8859-6:1987", + "\vISO-8859-7ISO_8859-7:1987", + "\vISO-8859-8ISO_8859-8:1988", + "\vISO-8859-9ISO_8859-9:1989", + "ISO-8859-10", + "ISO_6937-2-add", + "JIS_X0201", + "JIS_Encoding", + "Shift_JIS", + "\x07EUC-JPExtended_UNIX_Code_Packed_Format_for_Japanese", + "Extended_UNIX_Code_Fixed_Width_for_Japanese", + "BS_4730", + "SEN_850200_C", + "IT", + "ES", + "DIN_66003", + "NS_4551-1", + "NF_Z_62-010", + "ISO-10646-UTF-1", + "ISO_646.basic:1983", + "INVARIANT", + "ISO_646.irv:1983", + "NATS-SEFI", + "NATS-SEFI-ADD", + "NATS-DANO", + "NATS-DANO-ADD", + "SEN_850200_B", + "KS_C_5601-1987", + "ISO-2022-KR", + "EUC-KR", + "ISO-2022-JP", + "ISO-2022-JP-2", + "JIS_C6220-1969-jp", + "JIS_C6220-1969-ro", + "PT", + "greek7-old", + "latin-greek", + "NF_Z_62-010_(1973)", + "Latin-greek-1", + "ISO_5427", + "JIS_C6226-1978", + "BS_viewdata", + "INIS", + "INIS-8", + "INIS-cyrillic", + "ISO_5427:1981", + "ISO_5428:1980", + "GB_1988-80", + "GB_2312-80", + "NS_4551-2", + "videotex-suppl", + "PT2", + "ES2", + "MSZ_7795.3", + "JIS_C6226-1983", + "greek7", + "ASMO_449", + "iso-ir-90", + "JIS_C6229-1984-a", + "JIS_C6229-1984-b", + "JIS_C6229-1984-b-add", + "JIS_C6229-1984-hand", + "JIS_C6229-1984-hand-add", + "JIS_C6229-1984-kana", + "ISO_2033-1983", + "ANSI_X3.110-1983", + "T.61-7bit", + "T.61-8bit", + "ECMA-cyrillic", + "CSA_Z243.4-1985-1", + "CSA_Z243.4-1985-2", + "CSA_Z243.4-1985-gr", + "\rISO-8859-6-EISO_8859-6-E", + "\rISO-8859-6-IISO_8859-6-I", + "T.101-G2", + "\rISO-8859-8-EISO_8859-8-E", + "\rISO-8859-8-IISO_8859-8-I", + "CSN_369103", + "JUS_I.B1.002", + "IEC_P27-1", + "JUS_I.B1.003-serb", + "JUS_I.B1.003-mac", + "greek-ccitt", + "NC_NC00-10:81", + "ISO_6937-2-25", + "GOST_19768-74", + "ISO_8859-supp", + "ISO_10367-box", + "latin-lap", + "JIS_X0212-1990", + "DS_2089", + "us-dk", + "dk-us", + "KSC5636", + "UNICODE-1-1-UTF-7", + "ISO-2022-CN", + "ISO-2022-CN-EXT", + "UTF-8", + "ISO-8859-13", + "ISO-8859-14", + "ISO-8859-15", + "ISO-8859-16", + "GBK", + "GB18030", + "OSD_EBCDIC_DF04_15", + "OSD_EBCDIC_DF03_IRV", + "OSD_EBCDIC_DF04_1", + "ISO-11548-1", + "KZ-1048", + "ISO-10646-UCS-2", + "ISO-10646-UCS-4", + "ISO-10646-UCS-Basic", + "ISO-10646-Unicode-Latin1", + "ISO-10646-J-1", + "ISO-Unicode-IBM-1261", + "ISO-Unicode-IBM-1268", + "ISO-Unicode-IBM-1276", + "ISO-Unicode-IBM-1264", + "ISO-Unicode-IBM-1265", + "UNICODE-1-1", + "SCSU", + "UTF-7", + "UTF-16BE", + "UTF-16LE", + "UTF-16", + "CESU-8", + "UTF-32", + "UTF-32BE", + "UTF-32LE", + "BOCU-1", + "UTF-7-IMAP", + "ISO-8859-1-Windows-3.0-Latin-1", + "ISO-8859-1-Windows-3.1-Latin-1", + "ISO-8859-2-Windows-Latin-2", + "ISO-8859-9-Windows-Latin-5", + "hp-roman8", + "Adobe-Standard-Encoding", + "Ventura-US", + "Ventura-International", + "DEC-MCS", + "IBM850", + "IBM852", + "IBM437", + "PC8-Danish-Norwegian", + "IBM862", + "PC8-Turkish", + "IBM-Symbols", + "IBM-Thai", + "HP-Legal", + "HP-Pi-font", + "HP-Math8", + "Adobe-Symbol-Encoding", + "HP-DeskTop", + "Ventura-Math", + "Microsoft-Publishing", + "Windows-31J", + "GB2312", + "Big5", + "macintosh", + "IBM037", + "IBM038", + "IBM273", + "IBM274", + "IBM275", + "IBM277", + "IBM278", + "IBM280", + "IBM281", + "IBM284", + "IBM285", + "IBM290", + "IBM297", + "IBM420", + "IBM423", + "IBM424", + "IBM500", + "IBM851", + "IBM855", + "IBM857", + "IBM860", + "IBM861", + "IBM863", + "IBM864", + "IBM865", + "IBM868", + "IBM869", + "IBM870", + "IBM871", + "IBM880", + "IBM891", + "IBM903", + "IBM904", + "IBM905", + "IBM918", + "IBM1026", + "EBCDIC-AT-DE", + "EBCDIC-AT-DE-A", + "EBCDIC-CA-FR", + "EBCDIC-DK-NO", + "EBCDIC-DK-NO-A", + "EBCDIC-FI-SE", + "EBCDIC-FI-SE-A", + "EBCDIC-FR", + "EBCDIC-IT", + "EBCDIC-PT", + "EBCDIC-ES", + "EBCDIC-ES-A", + "EBCDIC-ES-S", + "EBCDIC-UK", + "EBCDIC-US", + "UNKNOWN-8BIT", + "MNEMONIC", + "MNEM", + "VISCII", + "VIQR", + "KOI8-R", + "HZ-GB-2312", + "IBM866", + "IBM775", + "KOI8-U", + "IBM00858", + "IBM00924", + "IBM01140", + "IBM01141", + "IBM01142", + "IBM01143", + "IBM01144", + "IBM01145", + "IBM01146", + "IBM01147", + "IBM01148", + "IBM01149", + "Big5-HKSCS", + "IBM1047", + "PTCP154", + "Amiga-1251", + "KOI7-switched", + "BRF", + "TSCII", + "CP51932", + "windows-874", + "windows-1250", + "windows-1251", + "windows-1252", + "windows-1253", + "windows-1254", + "windows-1255", + "windows-1256", + "windows-1257", + "windows-1258", + "TIS-620", + "CP50220", +} // Size: 7114 bytes + +var mibNames = []string{ // 258 elements + "ASCII", + "ISOLatin1", + "ISOLatin2", + "ISOLatin3", + "ISOLatin4", + "ISOLatinCyrillic", + "ISOLatinArabic", + "ISOLatinGreek", + "ISOLatinHebrew", + "ISOLatin5", + "ISOLatin6", + "ISOTextComm", + "HalfWidthKatakana", + "JISEncoding", + "ShiftJIS", + "EUCPkdFmtJapanese", + "EUCFixWidJapanese", + "ISO4UnitedKingdom", + "ISO11SwedishForNames", + "ISO15Italian", + "ISO17Spanish", + "ISO21German", + "ISO60Norwegian1", + "ISO69French", + "ISO10646UTF1", + "ISO646basic1983", + "INVARIANT", + "ISO2IntlRefVersion", + "NATSSEFI", + "NATSSEFIADD", + "NATSDANO", + "NATSDANOADD", + "ISO10Swedish", + "KSC56011987", + "ISO2022KR", + "EUCKR", + "ISO2022JP", + "ISO2022JP2", + "ISO13JISC6220jp", + "ISO14JISC6220ro", + "ISO16Portuguese", + "ISO18Greek7Old", + "ISO19LatinGreek", + "ISO25French", + "ISO27LatinGreek1", + "ISO5427Cyrillic", + "ISO42JISC62261978", + "ISO47BSViewdata", + "ISO49INIS", + "ISO50INIS8", + "ISO51INISCyrillic", + "ISO54271981", + "ISO5428Greek", + "ISO57GB1988", + "ISO58GB231280", + "ISO61Norwegian2", + "ISO70VideotexSupp1", + "ISO84Portuguese2", + "ISO85Spanish2", + "ISO86Hungarian", + "ISO87JISX0208", + "ISO88Greek7", + "ISO89ASMO449", + "ISO90", + "ISO91JISC62291984a", + "ISO92JISC62991984b", + "ISO93JIS62291984badd", + "ISO94JIS62291984hand", + "ISO95JIS62291984handadd", + "ISO96JISC62291984kana", + "ISO2033", + "ISO99NAPLPS", + "ISO102T617bit", + "ISO103T618bit", + "ISO111ECMACyrillic", + "ISO121Canadian1", + "ISO122Canadian2", + "ISO123CSAZ24341985gr", + "ISO88596E", + "ISO88596I", + "ISO128T101G2", + "ISO88598E", + "ISO88598I", + "ISO139CSN369103", + "ISO141JUSIB1002", + "ISO143IECP271", + "ISO146Serbian", + "ISO147Macedonian", + "ISO150GreekCCITT", + "ISO151Cuba", + "ISO6937Add", + "ISO153GOST1976874", + "ISO8859Supp", + "ISO10367Box", + "ISO158Lap", + "ISO159JISX02121990", + "ISO646Danish", + "USDK", + "DKUS", + "KSC5636", + "Unicode11UTF7", + "ISO2022CN", + "ISO2022CNEXT", + "UTF8", + "ISO885913", + "ISO885914", + "ISO885915", + "ISO885916", + "GBK", + "GB18030", + "OSDEBCDICDF0415", + "OSDEBCDICDF03IRV", + "OSDEBCDICDF041", + "ISO115481", + "KZ1048", + "Unicode", + "UCS4", + "UnicodeASCII", + "UnicodeLatin1", + "UnicodeJapanese", + "UnicodeIBM1261", + "UnicodeIBM1268", + "UnicodeIBM1276", + "UnicodeIBM1264", + "UnicodeIBM1265", + "Unicode11", + "SCSU", + "UTF7", + "UTF16BE", + "UTF16LE", + "UTF16", + "CESU-8", + "UTF32", + "UTF32BE", + "UTF32LE", + "BOCU-1", + "UTF7IMAP", + "Windows30Latin1", + "Windows31Latin1", + "Windows31Latin2", + "Windows31Latin5", + "HPRoman8", + "AdobeStandardEncoding", + "VenturaUS", + "VenturaInternational", + "DECMCS", + "PC850Multilingual", + "PCp852", + "PC8CodePage437", + "PC8DanishNorwegian", + "PC862LatinHebrew", + "PC8Turkish", + "IBMSymbols", + "IBMThai", + "HPLegal", + "HPPiFont", + "HPMath8", + "HPPSMath", + "HPDesktop", + "VenturaMath", + "MicrosoftPublishing", + "Windows31J", + "GB2312", + "Big5", + "Macintosh", + "IBM037", + "IBM038", + "IBM273", + "IBM274", + "IBM275", + "IBM277", + "IBM278", + "IBM280", + "IBM281", + "IBM284", + "IBM285", + "IBM290", + "IBM297", + "IBM420", + "IBM423", + "IBM424", + "IBM500", + "IBM851", + "IBM855", + "IBM857", + "IBM860", + "IBM861", + "IBM863", + "IBM864", + "IBM865", + "IBM868", + "IBM869", + "IBM870", + "IBM871", + "IBM880", + "IBM891", + "IBM903", + "IBBM904", + "IBM905", + "IBM918", + "IBM1026", + "IBMEBCDICATDE", + "EBCDICATDEA", + "EBCDICCAFR", + "EBCDICDKNO", + "EBCDICDKNOA", + "EBCDICFISE", + "EBCDICFISEA", + "EBCDICFR", + "EBCDICIT", + "EBCDICPT", + "EBCDICES", + "EBCDICESA", + "EBCDICESS", + "EBCDICUK", + "EBCDICUS", + "Unknown8BiT", + "Mnemonic", + "Mnem", + "VISCII", + "VIQR", + "KOI8R", + "HZ-GB-2312", + "IBM866", + "PC775Baltic", + "KOI8U", + "IBM00858", + "IBM00924", + "IBM01140", + "IBM01141", + "IBM01142", + "IBM01143", + "IBM01144", + "IBM01145", + "IBM01146", + "IBM01147", + "IBM01148", + "IBM01149", + "Big5HKSCS", + "IBM1047", + "PTCP154", + "Amiga1251\n(Aliases", + "KOI7switched", + "BRF", + "TSCII", + "CP51932", + "windows874", + "windows1250", + "windows1251", + "windows1252", + "windows1253", + "windows1254", + "windows1255", + "windows1256", + "windows1257", + "windows1258", + "TIS620", + "CP50220", +} // Size: 6800 bytes + +// TODO: Instead of using a map, we could use binary search strings doing +// on-the fly lower-casing per character. This allows to always avoid +// allocation and will be considerably more compact. +var ianaAliases = map[string]int{ + "US-ASCII": enc3, + "us-ascii": enc3, + "iso-ir-6": enc3, + "ANSI_X3.4-1968": enc3, + "ansi_x3.4-1968": enc3, + "ANSI_X3.4-1986": enc3, + "ansi_x3.4-1986": enc3, + "ISO_646.irv:1991": enc3, + "iso_646.irv:1991": enc3, + "ISO646-US": enc3, + "iso646-us": enc3, + "us": enc3, + "IBM367": enc3, + "ibm367": enc3, + "cp367": enc3, + "csASCII": enc3, + "csascii": enc3, + "ISO_8859-1:1987": enc4, + "iso_8859-1:1987": enc4, + "iso-ir-100": enc4, + "ISO_8859-1": enc4, + "iso_8859-1": enc4, + "ISO-8859-1": enc4, + "iso-8859-1": enc4, + "latin1": enc4, + "l1": enc4, + "IBM819": enc4, + "ibm819": enc4, + "CP819": enc4, + "cp819": enc4, + "csISOLatin1": enc4, + "csisolatin1": enc4, + "ISO_8859-2:1987": enc5, + "iso_8859-2:1987": enc5, + "iso-ir-101": enc5, + "ISO_8859-2": enc5, + "iso_8859-2": enc5, + "ISO-8859-2": enc5, + "iso-8859-2": enc5, + "latin2": enc5, + "l2": enc5, + "csISOLatin2": enc5, + "csisolatin2": enc5, + "ISO_8859-3:1988": enc6, + "iso_8859-3:1988": enc6, + "iso-ir-109": enc6, + "ISO_8859-3": enc6, + "iso_8859-3": enc6, + "ISO-8859-3": enc6, + "iso-8859-3": enc6, + "latin3": enc6, + "l3": enc6, + "csISOLatin3": enc6, + "csisolatin3": enc6, + "ISO_8859-4:1988": enc7, + "iso_8859-4:1988": enc7, + "iso-ir-110": enc7, + "ISO_8859-4": enc7, + "iso_8859-4": enc7, + "ISO-8859-4": enc7, + "iso-8859-4": enc7, + "latin4": enc7, + "l4": enc7, + "csISOLatin4": enc7, + "csisolatin4": enc7, + "ISO_8859-5:1988": enc8, + "iso_8859-5:1988": enc8, + "iso-ir-144": enc8, + "ISO_8859-5": enc8, + "iso_8859-5": enc8, + "ISO-8859-5": enc8, + "iso-8859-5": enc8, + "cyrillic": enc8, + "csISOLatinCyrillic": enc8, + "csisolatincyrillic": enc8, + "ISO_8859-6:1987": enc9, + "iso_8859-6:1987": enc9, + "iso-ir-127": enc9, + "ISO_8859-6": enc9, + "iso_8859-6": enc9, + "ISO-8859-6": enc9, + "iso-8859-6": enc9, + "ECMA-114": enc9, + "ecma-114": enc9, + "ASMO-708": enc9, + "asmo-708": enc9, + "arabic": enc9, + "csISOLatinArabic": enc9, + "csisolatinarabic": enc9, + "ISO_8859-7:1987": enc10, + "iso_8859-7:1987": enc10, + "iso-ir-126": enc10, + "ISO_8859-7": enc10, + "iso_8859-7": enc10, + "ISO-8859-7": enc10, + "iso-8859-7": enc10, + "ELOT_928": enc10, + "elot_928": enc10, + "ECMA-118": enc10, + "ecma-118": enc10, + "greek": enc10, + "greek8": enc10, + "csISOLatinGreek": enc10, + "csisolatingreek": enc10, + "ISO_8859-8:1988": enc11, + "iso_8859-8:1988": enc11, + "iso-ir-138": enc11, + "ISO_8859-8": enc11, + "iso_8859-8": enc11, + "ISO-8859-8": enc11, + "iso-8859-8": enc11, + "hebrew": enc11, + "csISOLatinHebrew": enc11, + "csisolatinhebrew": enc11, + "ISO_8859-9:1989": enc12, + "iso_8859-9:1989": enc12, + "iso-ir-148": enc12, + "ISO_8859-9": enc12, + "iso_8859-9": enc12, + "ISO-8859-9": enc12, + "iso-8859-9": enc12, + "latin5": enc12, + "l5": enc12, + "csISOLatin5": enc12, + "csisolatin5": enc12, + "ISO-8859-10": enc13, + "iso-8859-10": enc13, + "iso-ir-157": enc13, + "l6": enc13, + "ISO_8859-10:1992": enc13, + "iso_8859-10:1992": enc13, + "csISOLatin6": enc13, + "csisolatin6": enc13, + "latin6": enc13, + "ISO_6937-2-add": enc14, + "iso_6937-2-add": enc14, + "iso-ir-142": enc14, + "csISOTextComm": enc14, + "csisotextcomm": enc14, + "JIS_X0201": enc15, + "jis_x0201": enc15, + "X0201": enc15, + "x0201": enc15, + "csHalfWidthKatakana": enc15, + "cshalfwidthkatakana": enc15, + "JIS_Encoding": enc16, + "jis_encoding": enc16, + "csJISEncoding": enc16, + "csjisencoding": enc16, + "Shift_JIS": enc17, + "shift_jis": enc17, + "MS_Kanji": enc17, + "ms_kanji": enc17, + "csShiftJIS": enc17, + "csshiftjis": enc17, + "Extended_UNIX_Code_Packed_Format_for_Japanese": enc18, + "extended_unix_code_packed_format_for_japanese": enc18, + "csEUCPkdFmtJapanese": enc18, + "cseucpkdfmtjapanese": enc18, + "EUC-JP": enc18, + "euc-jp": enc18, + "Extended_UNIX_Code_Fixed_Width_for_Japanese": enc19, + "extended_unix_code_fixed_width_for_japanese": enc19, + "csEUCFixWidJapanese": enc19, + "cseucfixwidjapanese": enc19, + "BS_4730": enc20, + "bs_4730": enc20, + "iso-ir-4": enc20, + "ISO646-GB": enc20, + "iso646-gb": enc20, + "gb": enc20, + "uk": enc20, + "csISO4UnitedKingdom": enc20, + "csiso4unitedkingdom": enc20, + "SEN_850200_C": enc21, + "sen_850200_c": enc21, + "iso-ir-11": enc21, + "ISO646-SE2": enc21, + "iso646-se2": enc21, + "se2": enc21, + "csISO11SwedishForNames": enc21, + "csiso11swedishfornames": enc21, + "IT": enc22, + "it": enc22, + "iso-ir-15": enc22, + "ISO646-IT": enc22, + "iso646-it": enc22, + "csISO15Italian": enc22, + "csiso15italian": enc22, + "ES": enc23, + "es": enc23, + "iso-ir-17": enc23, + "ISO646-ES": enc23, + "iso646-es": enc23, + "csISO17Spanish": enc23, + "csiso17spanish": enc23, + "DIN_66003": enc24, + "din_66003": enc24, + "iso-ir-21": enc24, + "de": enc24, + "ISO646-DE": enc24, + "iso646-de": enc24, + "csISO21German": enc24, + "csiso21german": enc24, + "NS_4551-1": enc25, + "ns_4551-1": enc25, + "iso-ir-60": enc25, + "ISO646-NO": enc25, + "iso646-no": enc25, + "no": enc25, + "csISO60DanishNorwegian": enc25, + "csiso60danishnorwegian": enc25, + "csISO60Norwegian1": enc25, + "csiso60norwegian1": enc25, + "NF_Z_62-010": enc26, + "nf_z_62-010": enc26, + "iso-ir-69": enc26, + "ISO646-FR": enc26, + "iso646-fr": enc26, + "fr": enc26, + "csISO69French": enc26, + "csiso69french": enc26, + "ISO-10646-UTF-1": enc27, + "iso-10646-utf-1": enc27, + "csISO10646UTF1": enc27, + "csiso10646utf1": enc27, + "ISO_646.basic:1983": enc28, + "iso_646.basic:1983": enc28, + "ref": enc28, + "csISO646basic1983": enc28, + "csiso646basic1983": enc28, + "INVARIANT": enc29, + "invariant": enc29, + "csINVARIANT": enc29, + "csinvariant": enc29, + "ISO_646.irv:1983": enc30, + "iso_646.irv:1983": enc30, + "iso-ir-2": enc30, + "irv": enc30, + "csISO2IntlRefVersion": enc30, + "csiso2intlrefversion": enc30, + "NATS-SEFI": enc31, + "nats-sefi": enc31, + "iso-ir-8-1": enc31, + "csNATSSEFI": enc31, + "csnatssefi": enc31, + "NATS-SEFI-ADD": enc32, + "nats-sefi-add": enc32, + "iso-ir-8-2": enc32, + "csNATSSEFIADD": enc32, + "csnatssefiadd": enc32, + "NATS-DANO": enc33, + "nats-dano": enc33, + "iso-ir-9-1": enc33, + "csNATSDANO": enc33, + "csnatsdano": enc33, + "NATS-DANO-ADD": enc34, + "nats-dano-add": enc34, + "iso-ir-9-2": enc34, + "csNATSDANOADD": enc34, + "csnatsdanoadd": enc34, + "SEN_850200_B": enc35, + "sen_850200_b": enc35, + "iso-ir-10": enc35, + "FI": enc35, + "fi": enc35, + "ISO646-FI": enc35, + "iso646-fi": enc35, + "ISO646-SE": enc35, + "iso646-se": enc35, + "se": enc35, + "csISO10Swedish": enc35, + "csiso10swedish": enc35, + "KS_C_5601-1987": enc36, + "ks_c_5601-1987": enc36, + "iso-ir-149": enc36, + "KS_C_5601-1989": enc36, + "ks_c_5601-1989": enc36, + "KSC_5601": enc36, + "ksc_5601": enc36, + "korean": enc36, + "csKSC56011987": enc36, + "csksc56011987": enc36, + "ISO-2022-KR": enc37, + "iso-2022-kr": enc37, + "csISO2022KR": enc37, + "csiso2022kr": enc37, + "EUC-KR": enc38, + "euc-kr": enc38, + "csEUCKR": enc38, + "cseuckr": enc38, + "ISO-2022-JP": enc39, + "iso-2022-jp": enc39, + "csISO2022JP": enc39, + "csiso2022jp": enc39, + "ISO-2022-JP-2": enc40, + "iso-2022-jp-2": enc40, + "csISO2022JP2": enc40, + "csiso2022jp2": enc40, + "JIS_C6220-1969-jp": enc41, + "jis_c6220-1969-jp": enc41, + "JIS_C6220-1969": enc41, + "jis_c6220-1969": enc41, + "iso-ir-13": enc41, + "katakana": enc41, + "x0201-7": enc41, + "csISO13JISC6220jp": enc41, + "csiso13jisc6220jp": enc41, + "JIS_C6220-1969-ro": enc42, + "jis_c6220-1969-ro": enc42, + "iso-ir-14": enc42, + "jp": enc42, + "ISO646-JP": enc42, + "iso646-jp": enc42, + "csISO14JISC6220ro": enc42, + "csiso14jisc6220ro": enc42, + "PT": enc43, + "pt": enc43, + "iso-ir-16": enc43, + "ISO646-PT": enc43, + "iso646-pt": enc43, + "csISO16Portuguese": enc43, + "csiso16portuguese": enc43, + "greek7-old": enc44, + "iso-ir-18": enc44, + "csISO18Greek7Old": enc44, + "csiso18greek7old": enc44, + "latin-greek": enc45, + "iso-ir-19": enc45, + "csISO19LatinGreek": enc45, + "csiso19latingreek": enc45, + "NF_Z_62-010_(1973)": enc46, + "nf_z_62-010_(1973)": enc46, + "iso-ir-25": enc46, + "ISO646-FR1": enc46, + "iso646-fr1": enc46, + "csISO25French": enc46, + "csiso25french": enc46, + "Latin-greek-1": enc47, + "latin-greek-1": enc47, + "iso-ir-27": enc47, + "csISO27LatinGreek1": enc47, + "csiso27latingreek1": enc47, + "ISO_5427": enc48, + "iso_5427": enc48, + "iso-ir-37": enc48, + "csISO5427Cyrillic": enc48, + "csiso5427cyrillic": enc48, + "JIS_C6226-1978": enc49, + "jis_c6226-1978": enc49, + "iso-ir-42": enc49, + "csISO42JISC62261978": enc49, + "csiso42jisc62261978": enc49, + "BS_viewdata": enc50, + "bs_viewdata": enc50, + "iso-ir-47": enc50, + "csISO47BSViewdata": enc50, + "csiso47bsviewdata": enc50, + "INIS": enc51, + "inis": enc51, + "iso-ir-49": enc51, + "csISO49INIS": enc51, + "csiso49inis": enc51, + "INIS-8": enc52, + "inis-8": enc52, + "iso-ir-50": enc52, + "csISO50INIS8": enc52, + "csiso50inis8": enc52, + "INIS-cyrillic": enc53, + "inis-cyrillic": enc53, + "iso-ir-51": enc53, + "csISO51INISCyrillic": enc53, + "csiso51iniscyrillic": enc53, + "ISO_5427:1981": enc54, + "iso_5427:1981": enc54, + "iso-ir-54": enc54, + "ISO5427Cyrillic1981": enc54, + "iso5427cyrillic1981": enc54, + "csISO54271981": enc54, + "csiso54271981": enc54, + "ISO_5428:1980": enc55, + "iso_5428:1980": enc55, + "iso-ir-55": enc55, + "csISO5428Greek": enc55, + "csiso5428greek": enc55, + "GB_1988-80": enc56, + "gb_1988-80": enc56, + "iso-ir-57": enc56, + "cn": enc56, + "ISO646-CN": enc56, + "iso646-cn": enc56, + "csISO57GB1988": enc56, + "csiso57gb1988": enc56, + "GB_2312-80": enc57, + "gb_2312-80": enc57, + "iso-ir-58": enc57, + "chinese": enc57, + "csISO58GB231280": enc57, + "csiso58gb231280": enc57, + "NS_4551-2": enc58, + "ns_4551-2": enc58, + "ISO646-NO2": enc58, + "iso646-no2": enc58, + "iso-ir-61": enc58, + "no2": enc58, + "csISO61Norwegian2": enc58, + "csiso61norwegian2": enc58, + "videotex-suppl": enc59, + "iso-ir-70": enc59, + "csISO70VideotexSupp1": enc59, + "csiso70videotexsupp1": enc59, + "PT2": enc60, + "pt2": enc60, + "iso-ir-84": enc60, + "ISO646-PT2": enc60, + "iso646-pt2": enc60, + "csISO84Portuguese2": enc60, + "csiso84portuguese2": enc60, + "ES2": enc61, + "es2": enc61, + "iso-ir-85": enc61, + "ISO646-ES2": enc61, + "iso646-es2": enc61, + "csISO85Spanish2": enc61, + "csiso85spanish2": enc61, + "MSZ_7795.3": enc62, + "msz_7795.3": enc62, + "iso-ir-86": enc62, + "ISO646-HU": enc62, + "iso646-hu": enc62, + "hu": enc62, + "csISO86Hungarian": enc62, + "csiso86hungarian": enc62, + "JIS_C6226-1983": enc63, + "jis_c6226-1983": enc63, + "iso-ir-87": enc63, + "x0208": enc63, + "JIS_X0208-1983": enc63, + "jis_x0208-1983": enc63, + "csISO87JISX0208": enc63, + "csiso87jisx0208": enc63, + "greek7": enc64, + "iso-ir-88": enc64, + "csISO88Greek7": enc64, + "csiso88greek7": enc64, + "ASMO_449": enc65, + "asmo_449": enc65, + "ISO_9036": enc65, + "iso_9036": enc65, + "arabic7": enc65, + "iso-ir-89": enc65, + "csISO89ASMO449": enc65, + "csiso89asmo449": enc65, + "iso-ir-90": enc66, + "csISO90": enc66, + "csiso90": enc66, + "JIS_C6229-1984-a": enc67, + "jis_c6229-1984-a": enc67, + "iso-ir-91": enc67, + "jp-ocr-a": enc67, + "csISO91JISC62291984a": enc67, + "csiso91jisc62291984a": enc67, + "JIS_C6229-1984-b": enc68, + "jis_c6229-1984-b": enc68, + "iso-ir-92": enc68, + "ISO646-JP-OCR-B": enc68, + "iso646-jp-ocr-b": enc68, + "jp-ocr-b": enc68, + "csISO92JISC62991984b": enc68, + "csiso92jisc62991984b": enc68, + "JIS_C6229-1984-b-add": enc69, + "jis_c6229-1984-b-add": enc69, + "iso-ir-93": enc69, + "jp-ocr-b-add": enc69, + "csISO93JIS62291984badd": enc69, + "csiso93jis62291984badd": enc69, + "JIS_C6229-1984-hand": enc70, + "jis_c6229-1984-hand": enc70, + "iso-ir-94": enc70, + "jp-ocr-hand": enc70, + "csISO94JIS62291984hand": enc70, + "csiso94jis62291984hand": enc70, + "JIS_C6229-1984-hand-add": enc71, + "jis_c6229-1984-hand-add": enc71, + "iso-ir-95": enc71, + "jp-ocr-hand-add": enc71, + "csISO95JIS62291984handadd": enc71, + "csiso95jis62291984handadd": enc71, + "JIS_C6229-1984-kana": enc72, + "jis_c6229-1984-kana": enc72, + "iso-ir-96": enc72, + "csISO96JISC62291984kana": enc72, + "csiso96jisc62291984kana": enc72, + "ISO_2033-1983": enc73, + "iso_2033-1983": enc73, + "iso-ir-98": enc73, + "e13b": enc73, + "csISO2033": enc73, + "csiso2033": enc73, + "ANSI_X3.110-1983": enc74, + "ansi_x3.110-1983": enc74, + "iso-ir-99": enc74, + "CSA_T500-1983": enc74, + "csa_t500-1983": enc74, + "NAPLPS": enc74, + "naplps": enc74, + "csISO99NAPLPS": enc74, + "csiso99naplps": enc74, + "T.61-7bit": enc75, + "t.61-7bit": enc75, + "iso-ir-102": enc75, + "csISO102T617bit": enc75, + "csiso102t617bit": enc75, + "T.61-8bit": enc76, + "t.61-8bit": enc76, + "T.61": enc76, + "t.61": enc76, + "iso-ir-103": enc76, + "csISO103T618bit": enc76, + "csiso103t618bit": enc76, + "ECMA-cyrillic": enc77, + "ecma-cyrillic": enc77, + "iso-ir-111": enc77, + "KOI8-E": enc77, + "koi8-e": enc77, + "csISO111ECMACyrillic": enc77, + "csiso111ecmacyrillic": enc77, + "CSA_Z243.4-1985-1": enc78, + "csa_z243.4-1985-1": enc78, + "iso-ir-121": enc78, + "ISO646-CA": enc78, + "iso646-ca": enc78, + "csa7-1": enc78, + "csa71": enc78, + "ca": enc78, + "csISO121Canadian1": enc78, + "csiso121canadian1": enc78, + "CSA_Z243.4-1985-2": enc79, + "csa_z243.4-1985-2": enc79, + "iso-ir-122": enc79, + "ISO646-CA2": enc79, + "iso646-ca2": enc79, + "csa7-2": enc79, + "csa72": enc79, + "csISO122Canadian2": enc79, + "csiso122canadian2": enc79, + "CSA_Z243.4-1985-gr": enc80, + "csa_z243.4-1985-gr": enc80, + "iso-ir-123": enc80, + "csISO123CSAZ24341985gr": enc80, + "csiso123csaz24341985gr": enc80, + "ISO_8859-6-E": enc81, + "iso_8859-6-e": enc81, + "csISO88596E": enc81, + "csiso88596e": enc81, + "ISO-8859-6-E": enc81, + "iso-8859-6-e": enc81, + "ISO_8859-6-I": enc82, + "iso_8859-6-i": enc82, + "csISO88596I": enc82, + "csiso88596i": enc82, + "ISO-8859-6-I": enc82, + "iso-8859-6-i": enc82, + "T.101-G2": enc83, + "t.101-g2": enc83, + "iso-ir-128": enc83, + "csISO128T101G2": enc83, + "csiso128t101g2": enc83, + "ISO_8859-8-E": enc84, + "iso_8859-8-e": enc84, + "csISO88598E": enc84, + "csiso88598e": enc84, + "ISO-8859-8-E": enc84, + "iso-8859-8-e": enc84, + "ISO_8859-8-I": enc85, + "iso_8859-8-i": enc85, + "csISO88598I": enc85, + "csiso88598i": enc85, + "ISO-8859-8-I": enc85, + "iso-8859-8-i": enc85, + "CSN_369103": enc86, + "csn_369103": enc86, + "iso-ir-139": enc86, + "csISO139CSN369103": enc86, + "csiso139csn369103": enc86, + "JUS_I.B1.002": enc87, + "jus_i.b1.002": enc87, + "iso-ir-141": enc87, + "ISO646-YU": enc87, + "iso646-yu": enc87, + "js": enc87, + "yu": enc87, + "csISO141JUSIB1002": enc87, + "csiso141jusib1002": enc87, + "IEC_P27-1": enc88, + "iec_p27-1": enc88, + "iso-ir-143": enc88, + "csISO143IECP271": enc88, + "csiso143iecp271": enc88, + "JUS_I.B1.003-serb": enc89, + "jus_i.b1.003-serb": enc89, + "iso-ir-146": enc89, + "serbian": enc89, + "csISO146Serbian": enc89, + "csiso146serbian": enc89, + "JUS_I.B1.003-mac": enc90, + "jus_i.b1.003-mac": enc90, + "macedonian": enc90, + "iso-ir-147": enc90, + "csISO147Macedonian": enc90, + "csiso147macedonian": enc90, + "greek-ccitt": enc91, + "iso-ir-150": enc91, + "csISO150": enc91, + "csiso150": enc91, + "csISO150GreekCCITT": enc91, + "csiso150greekccitt": enc91, + "NC_NC00-10:81": enc92, + "nc_nc00-10:81": enc92, + "cuba": enc92, + "iso-ir-151": enc92, + "ISO646-CU": enc92, + "iso646-cu": enc92, + "csISO151Cuba": enc92, + "csiso151cuba": enc92, + "ISO_6937-2-25": enc93, + "iso_6937-2-25": enc93, + "iso-ir-152": enc93, + "csISO6937Add": enc93, + "csiso6937add": enc93, + "GOST_19768-74": enc94, + "gost_19768-74": enc94, + "ST_SEV_358-88": enc94, + "st_sev_358-88": enc94, + "iso-ir-153": enc94, + "csISO153GOST1976874": enc94, + "csiso153gost1976874": enc94, + "ISO_8859-supp": enc95, + "iso_8859-supp": enc95, + "iso-ir-154": enc95, + "latin1-2-5": enc95, + "csISO8859Supp": enc95, + "csiso8859supp": enc95, + "ISO_10367-box": enc96, + "iso_10367-box": enc96, + "iso-ir-155": enc96, + "csISO10367Box": enc96, + "csiso10367box": enc96, + "latin-lap": enc97, + "lap": enc97, + "iso-ir-158": enc97, + "csISO158Lap": enc97, + "csiso158lap": enc97, + "JIS_X0212-1990": enc98, + "jis_x0212-1990": enc98, + "x0212": enc98, + "iso-ir-159": enc98, + "csISO159JISX02121990": enc98, + "csiso159jisx02121990": enc98, + "DS_2089": enc99, + "ds_2089": enc99, + "DS2089": enc99, + "ds2089": enc99, + "ISO646-DK": enc99, + "iso646-dk": enc99, + "dk": enc99, + "csISO646Danish": enc99, + "csiso646danish": enc99, + "us-dk": enc100, + "csUSDK": enc100, + "csusdk": enc100, + "dk-us": enc101, + "csDKUS": enc101, + "csdkus": enc101, + "KSC5636": enc102, + "ksc5636": enc102, + "ISO646-KR": enc102, + "iso646-kr": enc102, + "csKSC5636": enc102, + "csksc5636": enc102, + "UNICODE-1-1-UTF-7": enc103, + "unicode-1-1-utf-7": enc103, + "csUnicode11UTF7": enc103, + "csunicode11utf7": enc103, + "ISO-2022-CN": enc104, + "iso-2022-cn": enc104, + "csISO2022CN": enc104, + "csiso2022cn": enc104, + "ISO-2022-CN-EXT": enc105, + "iso-2022-cn-ext": enc105, + "csISO2022CNEXT": enc105, + "csiso2022cnext": enc105, + "UTF-8": enc106, + "utf-8": enc106, + "csUTF8": enc106, + "csutf8": enc106, + "ISO-8859-13": enc109, + "iso-8859-13": enc109, + "csISO885913": enc109, + "csiso885913": enc109, + "ISO-8859-14": enc110, + "iso-8859-14": enc110, + "iso-ir-199": enc110, + "ISO_8859-14:1998": enc110, + "iso_8859-14:1998": enc110, + "ISO_8859-14": enc110, + "iso_8859-14": enc110, + "latin8": enc110, + "iso-celtic": enc110, + "l8": enc110, + "csISO885914": enc110, + "csiso885914": enc110, + "ISO-8859-15": enc111, + "iso-8859-15": enc111, + "ISO_8859-15": enc111, + "iso_8859-15": enc111, + "Latin-9": enc111, + "latin-9": enc111, + "csISO885915": enc111, + "csiso885915": enc111, + "ISO-8859-16": enc112, + "iso-8859-16": enc112, + "iso-ir-226": enc112, + "ISO_8859-16:2001": enc112, + "iso_8859-16:2001": enc112, + "ISO_8859-16": enc112, + "iso_8859-16": enc112, + "latin10": enc112, + "l10": enc112, + "csISO885916": enc112, + "csiso885916": enc112, + "GBK": enc113, + "gbk": enc113, + "CP936": enc113, + "cp936": enc113, + "MS936": enc113, + "ms936": enc113, + "windows-936": enc113, + "csGBK": enc113, + "csgbk": enc113, + "GB18030": enc114, + "gb18030": enc114, + "csGB18030": enc114, + "csgb18030": enc114, + "OSD_EBCDIC_DF04_15": enc115, + "osd_ebcdic_df04_15": enc115, + "csOSDEBCDICDF0415": enc115, + "csosdebcdicdf0415": enc115, + "OSD_EBCDIC_DF03_IRV": enc116, + "osd_ebcdic_df03_irv": enc116, + "csOSDEBCDICDF03IRV": enc116, + "csosdebcdicdf03irv": enc116, + "OSD_EBCDIC_DF04_1": enc117, + "osd_ebcdic_df04_1": enc117, + "csOSDEBCDICDF041": enc117, + "csosdebcdicdf041": enc117, + "ISO-11548-1": enc118, + "iso-11548-1": enc118, + "ISO_11548-1": enc118, + "iso_11548-1": enc118, + "ISO_TR_11548-1": enc118, + "iso_tr_11548-1": enc118, + "csISO115481": enc118, + "csiso115481": enc118, + "KZ-1048": enc119, + "kz-1048": enc119, + "STRK1048-2002": enc119, + "strk1048-2002": enc119, + "RK1048": enc119, + "rk1048": enc119, + "csKZ1048": enc119, + "cskz1048": enc119, + "ISO-10646-UCS-2": enc1000, + "iso-10646-ucs-2": enc1000, + "csUnicode": enc1000, + "csunicode": enc1000, + "ISO-10646-UCS-4": enc1001, + "iso-10646-ucs-4": enc1001, + "csUCS4": enc1001, + "csucs4": enc1001, + "ISO-10646-UCS-Basic": enc1002, + "iso-10646-ucs-basic": enc1002, + "csUnicodeASCII": enc1002, + "csunicodeascii": enc1002, + "ISO-10646-Unicode-Latin1": enc1003, + "iso-10646-unicode-latin1": enc1003, + "csUnicodeLatin1": enc1003, + "csunicodelatin1": enc1003, + "ISO-10646": enc1003, + "iso-10646": enc1003, + "ISO-10646-J-1": enc1004, + "iso-10646-j-1": enc1004, + "csUnicodeJapanese": enc1004, + "csunicodejapanese": enc1004, + "ISO-Unicode-IBM-1261": enc1005, + "iso-unicode-ibm-1261": enc1005, + "csUnicodeIBM1261": enc1005, + "csunicodeibm1261": enc1005, + "ISO-Unicode-IBM-1268": enc1006, + "iso-unicode-ibm-1268": enc1006, + "csUnicodeIBM1268": enc1006, + "csunicodeibm1268": enc1006, + "ISO-Unicode-IBM-1276": enc1007, + "iso-unicode-ibm-1276": enc1007, + "csUnicodeIBM1276": enc1007, + "csunicodeibm1276": enc1007, + "ISO-Unicode-IBM-1264": enc1008, + "iso-unicode-ibm-1264": enc1008, + "csUnicodeIBM1264": enc1008, + "csunicodeibm1264": enc1008, + "ISO-Unicode-IBM-1265": enc1009, + "iso-unicode-ibm-1265": enc1009, + "csUnicodeIBM1265": enc1009, + "csunicodeibm1265": enc1009, + "UNICODE-1-1": enc1010, + "unicode-1-1": enc1010, + "csUnicode11": enc1010, + "csunicode11": enc1010, + "SCSU": enc1011, + "scsu": enc1011, + "csSCSU": enc1011, + "csscsu": enc1011, + "UTF-7": enc1012, + "utf-7": enc1012, + "csUTF7": enc1012, + "csutf7": enc1012, + "UTF-16BE": enc1013, + "utf-16be": enc1013, + "csUTF16BE": enc1013, + "csutf16be": enc1013, + "UTF-16LE": enc1014, + "utf-16le": enc1014, + "csUTF16LE": enc1014, + "csutf16le": enc1014, + "UTF-16": enc1015, + "utf-16": enc1015, + "csUTF16": enc1015, + "csutf16": enc1015, + "CESU-8": enc1016, + "cesu-8": enc1016, + "csCESU8": enc1016, + "cscesu8": enc1016, + "csCESU-8": enc1016, + "cscesu-8": enc1016, + "UTF-32": enc1017, + "utf-32": enc1017, + "csUTF32": enc1017, + "csutf32": enc1017, + "UTF-32BE": enc1018, + "utf-32be": enc1018, + "csUTF32BE": enc1018, + "csutf32be": enc1018, + "UTF-32LE": enc1019, + "utf-32le": enc1019, + "csUTF32LE": enc1019, + "csutf32le": enc1019, + "BOCU-1": enc1020, + "bocu-1": enc1020, + "csBOCU1": enc1020, + "csbocu1": enc1020, + "csBOCU-1": enc1020, + "csbocu-1": enc1020, + "UTF-7-IMAP": enc1021, + "utf-7-imap": enc1021, + "csUTF7IMAP": enc1021, + "csutf7imap": enc1021, + "ISO-8859-1-Windows-3.0-Latin-1": enc2000, + "iso-8859-1-windows-3.0-latin-1": enc2000, + "csWindows30Latin1": enc2000, + "cswindows30latin1": enc2000, + "ISO-8859-1-Windows-3.1-Latin-1": enc2001, + "iso-8859-1-windows-3.1-latin-1": enc2001, + "csWindows31Latin1": enc2001, + "cswindows31latin1": enc2001, + "ISO-8859-2-Windows-Latin-2": enc2002, + "iso-8859-2-windows-latin-2": enc2002, + "csWindows31Latin2": enc2002, + "cswindows31latin2": enc2002, + "ISO-8859-9-Windows-Latin-5": enc2003, + "iso-8859-9-windows-latin-5": enc2003, + "csWindows31Latin5": enc2003, + "cswindows31latin5": enc2003, + "hp-roman8": enc2004, + "roman8": enc2004, + "r8": enc2004, + "csHPRoman8": enc2004, + "cshproman8": enc2004, + "Adobe-Standard-Encoding": enc2005, + "adobe-standard-encoding": enc2005, + "csAdobeStandardEncoding": enc2005, + "csadobestandardencoding": enc2005, + "Ventura-US": enc2006, + "ventura-us": enc2006, + "csVenturaUS": enc2006, + "csventuraus": enc2006, + "Ventura-International": enc2007, + "ventura-international": enc2007, + "csVenturaInternational": enc2007, + "csventurainternational": enc2007, + "DEC-MCS": enc2008, + "dec-mcs": enc2008, + "dec": enc2008, + "csDECMCS": enc2008, + "csdecmcs": enc2008, + "IBM850": enc2009, + "ibm850": enc2009, + "cp850": enc2009, + "850": enc2009, + "csPC850Multilingual": enc2009, + "cspc850multilingual": enc2009, + "PC8-Danish-Norwegian": enc2012, + "pc8-danish-norwegian": enc2012, + "csPC8DanishNorwegian": enc2012, + "cspc8danishnorwegian": enc2012, + "IBM862": enc2013, + "ibm862": enc2013, + "cp862": enc2013, + "862": enc2013, + "csPC862LatinHebrew": enc2013, + "cspc862latinhebrew": enc2013, + "PC8-Turkish": enc2014, + "pc8-turkish": enc2014, + "csPC8Turkish": enc2014, + "cspc8turkish": enc2014, + "IBM-Symbols": enc2015, + "ibm-symbols": enc2015, + "csIBMSymbols": enc2015, + "csibmsymbols": enc2015, + "IBM-Thai": enc2016, + "ibm-thai": enc2016, + "csIBMThai": enc2016, + "csibmthai": enc2016, + "HP-Legal": enc2017, + "hp-legal": enc2017, + "csHPLegal": enc2017, + "cshplegal": enc2017, + "HP-Pi-font": enc2018, + "hp-pi-font": enc2018, + "csHPPiFont": enc2018, + "cshppifont": enc2018, + "HP-Math8": enc2019, + "hp-math8": enc2019, + "csHPMath8": enc2019, + "cshpmath8": enc2019, + "Adobe-Symbol-Encoding": enc2020, + "adobe-symbol-encoding": enc2020, + "csHPPSMath": enc2020, + "cshppsmath": enc2020, + "HP-DeskTop": enc2021, + "hp-desktop": enc2021, + "csHPDesktop": enc2021, + "cshpdesktop": enc2021, + "Ventura-Math": enc2022, + "ventura-math": enc2022, + "csVenturaMath": enc2022, + "csventuramath": enc2022, + "Microsoft-Publishing": enc2023, + "microsoft-publishing": enc2023, + "csMicrosoftPublishing": enc2023, + "csmicrosoftpublishing": enc2023, + "Windows-31J": enc2024, + "windows-31j": enc2024, + "csWindows31J": enc2024, + "cswindows31j": enc2024, + "GB2312": enc2025, + "gb2312": enc2025, + "csGB2312": enc2025, + "csgb2312": enc2025, + "Big5": enc2026, + "big5": enc2026, + "csBig5": enc2026, + "csbig5": enc2026, + "macintosh": enc2027, + "mac": enc2027, + "csMacintosh": enc2027, + "csmacintosh": enc2027, + "IBM037": enc2028, + "ibm037": enc2028, + "cp037": enc2028, + "ebcdic-cp-us": enc2028, + "ebcdic-cp-ca": enc2028, + "ebcdic-cp-wt": enc2028, + "ebcdic-cp-nl": enc2028, + "csIBM037": enc2028, + "csibm037": enc2028, + "IBM038": enc2029, + "ibm038": enc2029, + "EBCDIC-INT": enc2029, + "ebcdic-int": enc2029, + "cp038": enc2029, + "csIBM038": enc2029, + "csibm038": enc2029, + "IBM273": enc2030, + "ibm273": enc2030, + "CP273": enc2030, + "cp273": enc2030, + "csIBM273": enc2030, + "csibm273": enc2030, + "IBM274": enc2031, + "ibm274": enc2031, + "EBCDIC-BE": enc2031, + "ebcdic-be": enc2031, + "CP274": enc2031, + "cp274": enc2031, + "csIBM274": enc2031, + "csibm274": enc2031, + "IBM275": enc2032, + "ibm275": enc2032, + "EBCDIC-BR": enc2032, + "ebcdic-br": enc2032, + "cp275": enc2032, + "csIBM275": enc2032, + "csibm275": enc2032, + "IBM277": enc2033, + "ibm277": enc2033, + "EBCDIC-CP-DK": enc2033, + "ebcdic-cp-dk": enc2033, + "EBCDIC-CP-NO": enc2033, + "ebcdic-cp-no": enc2033, + "csIBM277": enc2033, + "csibm277": enc2033, + "IBM278": enc2034, + "ibm278": enc2034, + "CP278": enc2034, + "cp278": enc2034, + "ebcdic-cp-fi": enc2034, + "ebcdic-cp-se": enc2034, + "csIBM278": enc2034, + "csibm278": enc2034, + "IBM280": enc2035, + "ibm280": enc2035, + "CP280": enc2035, + "cp280": enc2035, + "ebcdic-cp-it": enc2035, + "csIBM280": enc2035, + "csibm280": enc2035, + "IBM281": enc2036, + "ibm281": enc2036, + "EBCDIC-JP-E": enc2036, + "ebcdic-jp-e": enc2036, + "cp281": enc2036, + "csIBM281": enc2036, + "csibm281": enc2036, + "IBM284": enc2037, + "ibm284": enc2037, + "CP284": enc2037, + "cp284": enc2037, + "ebcdic-cp-es": enc2037, + "csIBM284": enc2037, + "csibm284": enc2037, + "IBM285": enc2038, + "ibm285": enc2038, + "CP285": enc2038, + "cp285": enc2038, + "ebcdic-cp-gb": enc2038, + "csIBM285": enc2038, + "csibm285": enc2038, + "IBM290": enc2039, + "ibm290": enc2039, + "cp290": enc2039, + "EBCDIC-JP-kana": enc2039, + "ebcdic-jp-kana": enc2039, + "csIBM290": enc2039, + "csibm290": enc2039, + "IBM297": enc2040, + "ibm297": enc2040, + "cp297": enc2040, + "ebcdic-cp-fr": enc2040, + "csIBM297": enc2040, + "csibm297": enc2040, + "IBM420": enc2041, + "ibm420": enc2041, + "cp420": enc2041, + "ebcdic-cp-ar1": enc2041, + "csIBM420": enc2041, + "csibm420": enc2041, + "IBM423": enc2042, + "ibm423": enc2042, + "cp423": enc2042, + "ebcdic-cp-gr": enc2042, + "csIBM423": enc2042, + "csibm423": enc2042, + "IBM424": enc2043, + "ibm424": enc2043, + "cp424": enc2043, + "ebcdic-cp-he": enc2043, + "csIBM424": enc2043, + "csibm424": enc2043, + "IBM437": enc2011, + "ibm437": enc2011, + "cp437": enc2011, + "437": enc2011, + "csPC8CodePage437": enc2011, + "cspc8codepage437": enc2011, + "IBM500": enc2044, + "ibm500": enc2044, + "CP500": enc2044, + "cp500": enc2044, + "ebcdic-cp-be": enc2044, + "ebcdic-cp-ch": enc2044, + "csIBM500": enc2044, + "csibm500": enc2044, + "IBM851": enc2045, + "ibm851": enc2045, + "cp851": enc2045, + "851": enc2045, + "csIBM851": enc2045, + "csibm851": enc2045, + "IBM852": enc2010, + "ibm852": enc2010, + "cp852": enc2010, + "852": enc2010, + "csPCp852": enc2010, + "cspcp852": enc2010, + "IBM855": enc2046, + "ibm855": enc2046, + "cp855": enc2046, + "855": enc2046, + "csIBM855": enc2046, + "csibm855": enc2046, + "IBM857": enc2047, + "ibm857": enc2047, + "cp857": enc2047, + "857": enc2047, + "csIBM857": enc2047, + "csibm857": enc2047, + "IBM860": enc2048, + "ibm860": enc2048, + "cp860": enc2048, + "860": enc2048, + "csIBM860": enc2048, + "csibm860": enc2048, + "IBM861": enc2049, + "ibm861": enc2049, + "cp861": enc2049, + "861": enc2049, + "cp-is": enc2049, + "csIBM861": enc2049, + "csibm861": enc2049, + "IBM863": enc2050, + "ibm863": enc2050, + "cp863": enc2050, + "863": enc2050, + "csIBM863": enc2050, + "csibm863": enc2050, + "IBM864": enc2051, + "ibm864": enc2051, + "cp864": enc2051, + "csIBM864": enc2051, + "csibm864": enc2051, + "IBM865": enc2052, + "ibm865": enc2052, + "cp865": enc2052, + "865": enc2052, + "csIBM865": enc2052, + "csibm865": enc2052, + "IBM868": enc2053, + "ibm868": enc2053, + "CP868": enc2053, + "cp868": enc2053, + "cp-ar": enc2053, + "csIBM868": enc2053, + "csibm868": enc2053, + "IBM869": enc2054, + "ibm869": enc2054, + "cp869": enc2054, + "869": enc2054, + "cp-gr": enc2054, + "csIBM869": enc2054, + "csibm869": enc2054, + "IBM870": enc2055, + "ibm870": enc2055, + "CP870": enc2055, + "cp870": enc2055, + "ebcdic-cp-roece": enc2055, + "ebcdic-cp-yu": enc2055, + "csIBM870": enc2055, + "csibm870": enc2055, + "IBM871": enc2056, + "ibm871": enc2056, + "CP871": enc2056, + "cp871": enc2056, + "ebcdic-cp-is": enc2056, + "csIBM871": enc2056, + "csibm871": enc2056, + "IBM880": enc2057, + "ibm880": enc2057, + "cp880": enc2057, + "EBCDIC-Cyrillic": enc2057, + "ebcdic-cyrillic": enc2057, + "csIBM880": enc2057, + "csibm880": enc2057, + "IBM891": enc2058, + "ibm891": enc2058, + "cp891": enc2058, + "csIBM891": enc2058, + "csibm891": enc2058, + "IBM903": enc2059, + "ibm903": enc2059, + "cp903": enc2059, + "csIBM903": enc2059, + "csibm903": enc2059, + "IBM904": enc2060, + "ibm904": enc2060, + "cp904": enc2060, + "904": enc2060, + "csIBBM904": enc2060, + "csibbm904": enc2060, + "IBM905": enc2061, + "ibm905": enc2061, + "CP905": enc2061, + "cp905": enc2061, + "ebcdic-cp-tr": enc2061, + "csIBM905": enc2061, + "csibm905": enc2061, + "IBM918": enc2062, + "ibm918": enc2062, + "CP918": enc2062, + "cp918": enc2062, + "ebcdic-cp-ar2": enc2062, + "csIBM918": enc2062, + "csibm918": enc2062, + "IBM1026": enc2063, + "ibm1026": enc2063, + "CP1026": enc2063, + "cp1026": enc2063, + "csIBM1026": enc2063, + "csibm1026": enc2063, + "EBCDIC-AT-DE": enc2064, + "ebcdic-at-de": enc2064, + "csIBMEBCDICATDE": enc2064, + "csibmebcdicatde": enc2064, + "EBCDIC-AT-DE-A": enc2065, + "ebcdic-at-de-a": enc2065, + "csEBCDICATDEA": enc2065, + "csebcdicatdea": enc2065, + "EBCDIC-CA-FR": enc2066, + "ebcdic-ca-fr": enc2066, + "csEBCDICCAFR": enc2066, + "csebcdiccafr": enc2066, + "EBCDIC-DK-NO": enc2067, + "ebcdic-dk-no": enc2067, + "csEBCDICDKNO": enc2067, + "csebcdicdkno": enc2067, + "EBCDIC-DK-NO-A": enc2068, + "ebcdic-dk-no-a": enc2068, + "csEBCDICDKNOA": enc2068, + "csebcdicdknoa": enc2068, + "EBCDIC-FI-SE": enc2069, + "ebcdic-fi-se": enc2069, + "csEBCDICFISE": enc2069, + "csebcdicfise": enc2069, + "EBCDIC-FI-SE-A": enc2070, + "ebcdic-fi-se-a": enc2070, + "csEBCDICFISEA": enc2070, + "csebcdicfisea": enc2070, + "EBCDIC-FR": enc2071, + "ebcdic-fr": enc2071, + "csEBCDICFR": enc2071, + "csebcdicfr": enc2071, + "EBCDIC-IT": enc2072, + "ebcdic-it": enc2072, + "csEBCDICIT": enc2072, + "csebcdicit": enc2072, + "EBCDIC-PT": enc2073, + "ebcdic-pt": enc2073, + "csEBCDICPT": enc2073, + "csebcdicpt": enc2073, + "EBCDIC-ES": enc2074, + "ebcdic-es": enc2074, + "csEBCDICES": enc2074, + "csebcdices": enc2074, + "EBCDIC-ES-A": enc2075, + "ebcdic-es-a": enc2075, + "csEBCDICESA": enc2075, + "csebcdicesa": enc2075, + "EBCDIC-ES-S": enc2076, + "ebcdic-es-s": enc2076, + "csEBCDICESS": enc2076, + "csebcdicess": enc2076, + "EBCDIC-UK": enc2077, + "ebcdic-uk": enc2077, + "csEBCDICUK": enc2077, + "csebcdicuk": enc2077, + "EBCDIC-US": enc2078, + "ebcdic-us": enc2078, + "csEBCDICUS": enc2078, + "csebcdicus": enc2078, + "UNKNOWN-8BIT": enc2079, + "unknown-8bit": enc2079, + "csUnknown8BiT": enc2079, + "csunknown8bit": enc2079, + "MNEMONIC": enc2080, + "mnemonic": enc2080, + "csMnemonic": enc2080, + "csmnemonic": enc2080, + "MNEM": enc2081, + "mnem": enc2081, + "csMnem": enc2081, + "csmnem": enc2081, + "VISCII": enc2082, + "viscii": enc2082, + "csVISCII": enc2082, + "csviscii": enc2082, + "VIQR": enc2083, + "viqr": enc2083, + "csVIQR": enc2083, + "csviqr": enc2083, + "KOI8-R": enc2084, + "koi8-r": enc2084, + "csKOI8R": enc2084, + "cskoi8r": enc2084, + "HZ-GB-2312": enc2085, + "hz-gb-2312": enc2085, + "IBM866": enc2086, + "ibm866": enc2086, + "cp866": enc2086, + "866": enc2086, + "csIBM866": enc2086, + "csibm866": enc2086, + "IBM775": enc2087, + "ibm775": enc2087, + "cp775": enc2087, + "csPC775Baltic": enc2087, + "cspc775baltic": enc2087, + "KOI8-U": enc2088, + "koi8-u": enc2088, + "csKOI8U": enc2088, + "cskoi8u": enc2088, + "IBM00858": enc2089, + "ibm00858": enc2089, + "CCSID00858": enc2089, + "ccsid00858": enc2089, + "CP00858": enc2089, + "cp00858": enc2089, + "PC-Multilingual-850+euro": enc2089, + "pc-multilingual-850+euro": enc2089, + "csIBM00858": enc2089, + "csibm00858": enc2089, + "IBM00924": enc2090, + "ibm00924": enc2090, + "CCSID00924": enc2090, + "ccsid00924": enc2090, + "CP00924": enc2090, + "cp00924": enc2090, + "ebcdic-Latin9--euro": enc2090, + "ebcdic-latin9--euro": enc2090, + "csIBM00924": enc2090, + "csibm00924": enc2090, + "IBM01140": enc2091, + "ibm01140": enc2091, + "CCSID01140": enc2091, + "ccsid01140": enc2091, + "CP01140": enc2091, + "cp01140": enc2091, + "ebcdic-us-37+euro": enc2091, + "csIBM01140": enc2091, + "csibm01140": enc2091, + "IBM01141": enc2092, + "ibm01141": enc2092, + "CCSID01141": enc2092, + "ccsid01141": enc2092, + "CP01141": enc2092, + "cp01141": enc2092, + "ebcdic-de-273+euro": enc2092, + "csIBM01141": enc2092, + "csibm01141": enc2092, + "IBM01142": enc2093, + "ibm01142": enc2093, + "CCSID01142": enc2093, + "ccsid01142": enc2093, + "CP01142": enc2093, + "cp01142": enc2093, + "ebcdic-dk-277+euro": enc2093, + "ebcdic-no-277+euro": enc2093, + "csIBM01142": enc2093, + "csibm01142": enc2093, + "IBM01143": enc2094, + "ibm01143": enc2094, + "CCSID01143": enc2094, + "ccsid01143": enc2094, + "CP01143": enc2094, + "cp01143": enc2094, + "ebcdic-fi-278+euro": enc2094, + "ebcdic-se-278+euro": enc2094, + "csIBM01143": enc2094, + "csibm01143": enc2094, + "IBM01144": enc2095, + "ibm01144": enc2095, + "CCSID01144": enc2095, + "ccsid01144": enc2095, + "CP01144": enc2095, + "cp01144": enc2095, + "ebcdic-it-280+euro": enc2095, + "csIBM01144": enc2095, + "csibm01144": enc2095, + "IBM01145": enc2096, + "ibm01145": enc2096, + "CCSID01145": enc2096, + "ccsid01145": enc2096, + "CP01145": enc2096, + "cp01145": enc2096, + "ebcdic-es-284+euro": enc2096, + "csIBM01145": enc2096, + "csibm01145": enc2096, + "IBM01146": enc2097, + "ibm01146": enc2097, + "CCSID01146": enc2097, + "ccsid01146": enc2097, + "CP01146": enc2097, + "cp01146": enc2097, + "ebcdic-gb-285+euro": enc2097, + "csIBM01146": enc2097, + "csibm01146": enc2097, + "IBM01147": enc2098, + "ibm01147": enc2098, + "CCSID01147": enc2098, + "ccsid01147": enc2098, + "CP01147": enc2098, + "cp01147": enc2098, + "ebcdic-fr-297+euro": enc2098, + "csIBM01147": enc2098, + "csibm01147": enc2098, + "IBM01148": enc2099, + "ibm01148": enc2099, + "CCSID01148": enc2099, + "ccsid01148": enc2099, + "CP01148": enc2099, + "cp01148": enc2099, + "ebcdic-international-500+euro": enc2099, + "csIBM01148": enc2099, + "csibm01148": enc2099, + "IBM01149": enc2100, + "ibm01149": enc2100, + "CCSID01149": enc2100, + "ccsid01149": enc2100, + "CP01149": enc2100, + "cp01149": enc2100, + "ebcdic-is-871+euro": enc2100, + "csIBM01149": enc2100, + "csibm01149": enc2100, + "Big5-HKSCS": enc2101, + "big5-hkscs": enc2101, + "csBig5HKSCS": enc2101, + "csbig5hkscs": enc2101, + "IBM1047": enc2102, + "ibm1047": enc2102, + "IBM-1047": enc2102, + "ibm-1047": enc2102, + "csIBM1047": enc2102, + "csibm1047": enc2102, + "PTCP154": enc2103, + "ptcp154": enc2103, + "csPTCP154": enc2103, + "csptcp154": enc2103, + "PT154": enc2103, + "pt154": enc2103, + "CP154": enc2103, + "cp154": enc2103, + "Cyrillic-Asian": enc2103, + "cyrillic-asian": enc2103, + "Amiga-1251": enc2104, + "amiga-1251": enc2104, + "Ami1251": enc2104, + "ami1251": enc2104, + "Amiga1251": enc2104, + "amiga1251": enc2104, + "Ami-1251": enc2104, + "ami-1251": enc2104, + "csAmiga1251\n(Aliases": enc2104, + "csamiga1251\n(aliases": enc2104, + "KOI7-switched": enc2105, + "koi7-switched": enc2105, + "csKOI7switched": enc2105, + "cskoi7switched": enc2105, + "BRF": enc2106, + "brf": enc2106, + "csBRF": enc2106, + "csbrf": enc2106, + "TSCII": enc2107, + "tscii": enc2107, + "csTSCII": enc2107, + "cstscii": enc2107, + "CP51932": enc2108, + "cp51932": enc2108, + "csCP51932": enc2108, + "cscp51932": enc2108, + "windows-874": enc2109, + "cswindows874": enc2109, + "windows-1250": enc2250, + "cswindows1250": enc2250, + "windows-1251": enc2251, + "cswindows1251": enc2251, + "windows-1252": enc2252, + "cswindows1252": enc2252, + "windows-1253": enc2253, + "cswindows1253": enc2253, + "windows-1254": enc2254, + "cswindows1254": enc2254, + "windows-1255": enc2255, + "cswindows1255": enc2255, + "windows-1256": enc2256, + "cswindows1256": enc2256, + "windows-1257": enc2257, + "cswindows1257": enc2257, + "windows-1258": enc2258, + "cswindows1258": enc2258, + "TIS-620": enc2259, + "tis-620": enc2259, + "csTIS620": enc2259, + "cstis620": enc2259, + "ISO-8859-11": enc2259, + "iso-8859-11": enc2259, + "CP50220": enc2260, + "cp50220": enc2260, + "csCP50220": enc2260, + "cscp50220": enc2260, +} + +// Total table size 14454 bytes (14KiB); checksum: 9095144D diff --git a/vendor/modules.txt b/vendor/modules.txt index df4f227816..3ade1d9f02 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -15,6 +15,13 @@ cloud.google.com/go/internal/version # cloud.google.com/go/storage v1.10.0 ## explicit; go 1.11 cloud.google.com/go/storage +# gitee.com/chunanyong/dm v1.8.14 +## explicit; go 1.13 +gitee.com/chunanyong/dm +gitee.com/chunanyong/dm/i18n +gitee.com/chunanyong/dm/parser +gitee.com/chunanyong/dm/security +gitee.com/chunanyong/dm/util # github.com/360EntSecGroup-Skylar/excelize v1.4.0 ## explicit github.com/360EntSecGroup-Skylar/excelize @@ -461,7 +468,7 @@ github.com/golang/protobuf/ptypes github.com/golang/protobuf/ptypes/any github.com/golang/protobuf/ptypes/duration github.com/golang/protobuf/ptypes/timestamp -# github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db +# github.com/golang/snappy v0.0.1 ## explicit github.com/golang/snappy # github.com/google/btree v1.0.1 @@ -1102,6 +1109,7 @@ golang.org/x/term golang.org/x/text/encoding golang.org/x/text/encoding/charmap golang.org/x/text/encoding/htmlindex +golang.org/x/text/encoding/ianaindex golang.org/x/text/encoding/internal golang.org/x/text/encoding/internal/identifier golang.org/x/text/encoding/japanese @@ -1465,7 +1473,7 @@ sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.2.0 ## explicit; go 1.12 sigs.k8s.io/yaml -# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240223082938-77dea2c9d55b +# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240228112145-f7432518ad4b ## explicit; go 1.18 yunion.io/x/cloudmux/pkg/apis yunion.io/x/cloudmux/pkg/apis/billing @@ -1487,6 +1495,8 @@ yunion.io/x/cloudmux/pkg/multicloud/baidu yunion.io/x/cloudmux/pkg/multicloud/baidu/provider yunion.io/x/cloudmux/pkg/multicloud/bingocloud yunion.io/x/cloudmux/pkg/multicloud/bingocloud/provider +yunion.io/x/cloudmux/pkg/multicloud/cephfs +yunion.io/x/cloudmux/pkg/multicloud/cephfs/provider yunion.io/x/cloudmux/pkg/multicloud/ctyun yunion.io/x/cloudmux/pkg/multicloud/ctyun/provider yunion.io/x/cloudmux/pkg/multicloud/cucloud @@ -1616,11 +1626,12 @@ yunion.io/x/pkg/utils # yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e ## explicit; go 1.12 yunion.io/x/s3cli -# yunion.io/x/sqlchemy v1.1.3-0.20240210161427-e48bb9a658b7 +# yunion.io/x/sqlchemy v1.1.3-0.20240228104732-b8924f0c2e81 ## explicit; go 1.17 yunion.io/x/sqlchemy yunion.io/x/sqlchemy/backends yunion.io/x/sqlchemy/backends/clickhouse +yunion.io/x/sqlchemy/backends/dameng yunion.io/x/sqlchemy/backends/mysql yunion.io/x/sqlchemy/backends/sqlite # yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c diff --git a/vendor/yunion.io/x/cloudmux/pkg/apis/compute/cloudaccount_const.go b/vendor/yunion.io/x/cloudmux/pkg/apis/compute/cloudaccount_const.go index 7b8e35a8a4..f0c0940f50 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/apis/compute/cloudaccount_const.go +++ b/vendor/yunion.io/x/cloudmux/pkg/apis/compute/cloudaccount_const.go @@ -49,6 +49,7 @@ const ( CLOUD_PROVIDER_GENERICS3 = "S3" CLOUD_PROVIDER_CEPH = "Ceph" + CLOUD_PROVIDER_CEPHFS = "CephFS" CLOUD_PROVIDER_XSKY = "Xsky" CLOUD_PROVIDER_HEALTH_NORMAL = "normal" // 远端处于健康状态 diff --git a/vendor/yunion.io/x/cloudmux/pkg/apis/compute/natgateway.go b/vendor/yunion.io/x/cloudmux/pkg/apis/compute/natgateway.go index 4a49b8d7a9..dee361da6c 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/apis/compute/natgateway.go +++ b/vendor/yunion.io/x/cloudmux/pkg/apis/compute/natgateway.go @@ -30,4 +30,9 @@ const ( QCLOUD_NAT_SPEC_SMALL = "small" QCLOUD_NAT_SPEC_MIDDLE = "middle" QCLOUD_NAT_SPEC_LARGE = "large" + + // 公网 + NAT_NETWORK_TYPE_INTERNET = "internet" + // VPC + NAT_NETWORK_TYPE_INTRANET = "intranet" ) diff --git a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go index 9dfbacf030..08fe6a613d 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go +++ b/vendor/yunion.io/x/cloudmux/pkg/cloudprovider/resources.go @@ -915,14 +915,16 @@ type ICloudNatGateway interface { GetINatSTable() ([]ICloudNatSEntry, error) // ID is the ID of snat entry/rule or dnat entry/rule. - GetINatDEntryByID(id string) (ICloudNatDEntry, error) - GetINatSEntryByID(id string) (ICloudNatSEntry, error) + GetINatDEntryById(id string) (ICloudNatDEntry, error) + GetINatSEntryById(id string) (ICloudNatSEntry, error) // Read the description of these two structures before using. CreateINatDEntry(rule SNatDRule) (ICloudNatDEntry, error) CreateINatSEntry(rule SNatSRule) (ICloudNatSEntry, error) GetINetworkId() string + // internet(公网) or intranet(VPC) + GetNetworkType() string GetBandwidthMb() int GetIpAddr() string @@ -1394,7 +1396,7 @@ type ICloudInterVpcNetworkRoute interface { } type ICloudFileSystem interface { - ICloudResource + IVirtualResource IBillingResource GetFileSystemType() string diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/filesystem.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/filesystem.go index 0967a1bced..2718b13fd1 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/filesystem.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/filesystem.go @@ -71,6 +71,7 @@ type SFileSystem struct { FileSystemType string FileSystemId string RegionId string + ResourceGroupId string } func (self *SFileSystem) GetId() string { @@ -360,3 +361,7 @@ func (self *SRegion) CreateFileSystem(opts *cloudprovider.FileSystemCraeteOption func (self *SFileSystem) SetTags(tags map[string]string, replace bool) error { return self.region.SetResourceTags(ALIYUN_SERVICE_NAS, "filesystem", self.FileSystemId, tags, replace) } + +func (self *SFileSystem) GetProjectId() string { + return self.ResourceGroupId +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/natgateway.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/natgateway.go index 3abadbc718..4901940d9a 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/natgateway.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aliyun/natgateway.go @@ -61,6 +61,7 @@ type SNatGateway struct { ExpiredTime time.Time Description string ForwardTableIds SForwardTableIds + NetworkType string SnatTableIds SSnatTableIds InstanceChargeType TChargeType Name string @@ -104,6 +105,10 @@ func (self *SNatGateway) GetINetworkId() string { return self.NatGatewayPrivateInfo.VswitchId } +func (self *SNatGateway) GetNetworkType() string { + return self.NetworkType +} + func (self *SNatGateway) GetIpAddr() string { return self.NatGatewayPrivateInfo.PrivateIpAddress } @@ -197,7 +202,7 @@ func (nat *SNatGateway) GetINatSTable() ([]cloudprovider.ICloudNatSEntry, error) return itables, nil } -func (nat *SNatGateway) GetINatDEntryByID(id string) (cloudprovider.ICloudNatDEntry, error) { +func (nat *SNatGateway) GetINatDEntryById(id string) (cloudprovider.ICloudNatDEntry, error) { dNATEntry, err := nat.vpc.region.GetForwardTableEntry(nat.ForwardTableIds.ForwardTableId[0], id) if err != nil { return nil, cloudprovider.ErrNotFound @@ -206,7 +211,7 @@ func (nat *SNatGateway) GetINatDEntryByID(id string) (cloudprovider.ICloudNatDEn return &dNATEntry, nil } -func (nat *SNatGateway) GetINatSEntryByID(id string) (cloudprovider.ICloudNatSEntry, error) { +func (nat *SNatGateway) GetINatSEntryById(id string) (cloudprovider.ICloudNatSEntry, error) { sNATEntry, err := nat.vpc.region.GetSNATEntry(nat.SnatTableIds.SnatTableId[0], id) if err != nil { return nil, cloudprovider.ErrNotFound @@ -220,7 +225,7 @@ func (nat *SNatGateway) CreateINatDEntry(rule cloudprovider.SNatDRule) (cloudpro if err != nil { return nil, errors.Wrapf(err, `create dnat rule for nat gateway %q`, nat.GetId()) } - return nat.GetINatDEntryByID(entryID) + return nat.GetINatDEntryById(entryID) } func (nat *SNatGateway) CreateINatSEntry(rule cloudprovider.SNatSRule) (cloudprovider.ICloudNatSEntry, error) { @@ -228,7 +233,7 @@ func (nat *SNatGateway) CreateINatSEntry(rule cloudprovider.SNatSRule) (cloudpro if err != nil { return nil, errors.Wrapf(err, `create snat rule for nat gateway %q`, nat.GetId()) } - return nat.GetINatSEntryByID(entryID) + return nat.GetINatSEntryById(entryID) } func (self *SRegion) GetNatGateways(vpcId string, natGwId string, offset, limit int) ([]SNatGateway, int, error) { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/apsara/natgateway.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/apsara/natgateway.go index 03eaf4dacf..d99eb11773 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/apsara/natgateway.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/apsara/natgateway.go @@ -48,6 +48,7 @@ type SNatGetway struct { BusinessStatus string CreationTime time.Time ExpiredTime time.Time + NetworkType string Description string ForwardTableIds SForwardTableIds SnatTableIds SSnatTableIds @@ -101,6 +102,10 @@ func (nat *SNatGetway) GetNatSpec() string { return nat.Spec } +func (nat *SNatGetway) GetNetworkType() string { + return nat.NetworkType +} + func (nat *SNatGetway) GetCreatedAt() time.Time { return nat.CreationTime } @@ -157,7 +162,7 @@ func (nat *SNatGetway) GetINatSTable() ([]cloudprovider.ICloudNatSEntry, error) return itables, nil } -func (nat *SNatGetway) GetINatDEntryByID(id string) (cloudprovider.ICloudNatDEntry, error) { +func (nat *SNatGetway) GetINatDEntryById(id string) (cloudprovider.ICloudNatDEntry, error) { dNATEntry, err := nat.vpc.region.GetForwardTableEntry(nat.ForwardTableIds.ForwardTableId[0], id) if err != nil { return nil, cloudprovider.ErrNotFound @@ -166,7 +171,7 @@ func (nat *SNatGetway) GetINatDEntryByID(id string) (cloudprovider.ICloudNatDEnt return &dNATEntry, nil } -func (nat *SNatGetway) GetINatSEntryByID(id string) (cloudprovider.ICloudNatSEntry, error) { +func (nat *SNatGetway) GetINatSEntryById(id string) (cloudprovider.ICloudNatSEntry, error) { sNATEntry, err := nat.vpc.region.GetSNATEntry(nat.SnatTableIds.SnatTableId[0], id) if err != nil { return nil, cloudprovider.ErrNotFound @@ -180,7 +185,7 @@ func (nat *SNatGetway) CreateINatDEntry(rule cloudprovider.SNatDRule) (cloudprov if err != nil { return nil, errors.Wrapf(err, `create dnat rule for nat gateway %q`, nat.GetId()) } - return nat.GetINatDEntryByID(entryID) + return nat.GetINatDEntryById(entryID) } func (nat *SNatGetway) CreateINatSEntry(rule cloudprovider.SNatSRule) (cloudprovider.ICloudNatSEntry, error) { @@ -188,7 +193,7 @@ func (nat *SNatGetway) CreateINatSEntry(rule cloudprovider.SNatSRule) (cloudprov if err != nil { return nil, errors.Wrapf(err, `create snat rule for nat gateway %q`, nat.GetId()) } - return nat.GetINatSEntryByID(entryID) + return nat.GetINatSEntryById(entryID) } func (self *SRegion) GetNatGateways(vpcId string, natGwId string, offset, limit int) ([]SNatGetway, int, error) { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/lambda.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/lambda.go index 4a2632035f..322c860f11 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/lambda.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/lambda.go @@ -14,7 +14,10 @@ package aws -import "fmt" +import ( + "fmt" + "net/url" +) type LambdaFunction struct { Description string `json:"Description"` @@ -68,20 +71,20 @@ type LambdaFunction struct { } func (self *SRegion) ListFunctions() ([]LambdaFunction, error) { - params := map[string]interface{}{ - "MaxItems": "10000", - } + params := url.Values{} + params.Set("MaxItems", "10000") + params.Set("FunctionVersion", "ALL") ret, marker := []LambdaFunction{}, "" for { part := struct { Functions []LambdaFunction NextMarker string }{} - path := "/2015-03-31/functions/?FunctionVersion=ALL&MaxItems={MaxItems}" if len(marker) > 0 { - path += "&Marker=" + marker + params.Set("Marker", marker) } - err := self.lambdaRequest("ListFunctions", path, params, &part) + path := fmt.Sprintf("/2015-03-31/functions/?%s", params.Encode()) + err := self.lambdaRequest("ListFunctions", path, map[string]interface{}{}, &part) if err != nil { return nil, err } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/natgateway.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/natgateway.go index 2d67212e03..845ca386f8 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/natgateway.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/aws/natgateway.go @@ -93,6 +93,13 @@ func (self *SNatGateway) GetStatus() string { } } +func (self *SNatGateway) GetNetworkType() string { + if self.ConnectivityType == "public" { + return api.NAT_NETWORK_TYPE_INTERNET + } + return api.NAT_NETWORK_TYPE_INTRANET +} + func (self *SNatGateway) GetNatSpec() string { return "" } @@ -126,11 +133,11 @@ func (self *SNatGateway) GetINatSTable() ([]cloudprovider.ICloudNatSEntry, error return []cloudprovider.ICloudNatSEntry{}, nil } -func (self *SNatGateway) GetINatDEntryByID(id string) (cloudprovider.ICloudNatDEntry, error) { +func (self *SNatGateway) GetINatDEntryById(id string) (cloudprovider.ICloudNatDEntry, error) { return nil, errors.Wrapf(cloudprovider.ErrNotFound, id) } -func (self *SNatGateway) GetINatSEntryByID(id string) (cloudprovider.ICloudNatSEntry, error) { +func (self *SNatGateway) GetINatSEntryById(id string) (cloudprovider.ICloudNatSEntry, error) { return nil, errors.Wrapf(cloudprovider.ErrNotFound, id) } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/cephfs/cephfs.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/cephfs/cephfs.go new file mode 100644 index 0000000000..da66d97a7b --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/cephfs/cephfs.go @@ -0,0 +1,44 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cephfs + +type SCephFS struct { + Id string + Mdsmap struct { + Epoch int + Flags int + EverAllowedFeatures int + ExplicitlyAllowedFeatures int + SessionTimeout int + SessionAutoclose int + MaxFileSize int64 + Created string + Enabled bool + FsName string + } +} + +func (cli *SCephFSClient) GetCephFSs() ([]SCephFS, error) { + resp, err := cli.list("cephfs", nil) + if err != nil { + return nil, err + } + ret := []SCephFS{} + err = resp.Unmarshal(&ret) + if err != nil { + return nil, err + } + return ret, nil +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/cephfs/client.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/cephfs/client.go new file mode 100644 index 0000000000..46b5cfb45d --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/cephfs/client.go @@ -0,0 +1,221 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cephfs + +import ( + "context" + "crypto/tls" + "fmt" + "net/http" + "net/url" + "strings" + "sync" + + api "yunion.io/x/cloudmux/pkg/apis/compute" + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud" + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" + "yunion.io/x/pkg/gotypes" + "yunion.io/x/pkg/util/httputils" +) + +const ( + CLOUD_PROVIDER_CEPHFS = api.CLOUD_PROVIDER_CEPHFS +) + +type CephFSClientConfig struct { + cpcfg cloudprovider.ProviderConfig + + host string + port int + username string + password string + fsId string + + debug bool +} + +func (cfg *CephFSClientConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *CephFSClientConfig { + cfg.cpcfg = cpcfg + return cfg +} + +func (cfg *CephFSClientConfig) Debug(debug bool) *CephFSClientConfig { + cfg.debug = debug + return cfg +} + +func NewCephFSClientConfig(host string, port int, username, password, fsId string) *CephFSClientConfig { + cfg := &CephFSClientConfig{ + host: host, + port: port, + + username: username, + password: password, + + fsId: fsId, + } + return cfg +} + +type SCephFSClient struct { + *CephFSClientConfig + + cloudprovider.SFakeOnPremiseRegion + multicloud.SNoObjectStorageRegion + multicloud.SRegion + + lock sync.Mutex + client *http.Client + + token string +} + +func NewCephFSClient(cfg *CephFSClientConfig) (*SCephFSClient, error) { + client := &SCephFSClient{ + CephFSClientConfig: cfg, + } + return client, client.auth() +} + +func (cli *SCephFSClient) GetI18n() cloudprovider.SModelI18nTable { + table := cloudprovider.SModelI18nTable{} + table["name"] = cloudprovider.NewSModelI18nEntry(cli.GetName()).CN(cli.GetName()) + return table +} + +func (cli *SCephFSClient) getDefaultClient() *http.Client { + cli.lock.Lock() + defer cli.lock.Unlock() + if !gotypes.IsNil(cli.client) { + return cli.client + } + cli.client = httputils.GetAdaptiveTimeoutClient() + httputils.SetClientProxyFunc(cli.client, cli.cpcfg.ProxyFunc) + ts, _ := cli.client.Transport.(*http.Transport) + ts.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + cli.client.Transport = cloudprovider.GetCheckTransport(ts, func(req *http.Request) (func(resp *http.Response) error, error) { + if cli.cpcfg.ReadOnly { + if req.Method == "GET" || strings.HasSuffix(req.URL.Path, "/auth") { + return nil, nil + } + return nil, errors.Wrapf(cloudprovider.ErrAccountReadOnly, "%s %s", req.Method, req.URL.Path) + } + return nil, nil + }) + return cli.client +} + +func (cli *SCephFSClient) baseUrl() string { + return fmt.Sprintf("https://%s:%d/api", cli.host, cli.port) +} + +func (cli *SCephFSClient) auth() error { + client := cli.getDefaultClient() + url := fmt.Sprintf("%s/auth", cli.baseUrl()) + header := http.Header{} + header.Set("Accept", "application/vnd.ceph.api.v1.0+json") + header.Set("Accept-Encoding", "gzip") + body := jsonutils.Marshal(map[string]interface{}{ + "username": cli.username, + "password": cli.password, + }) + _, resp, err := httputils.JSONRequest(client, context.Background(), httputils.POST, url, header, body, cli.debug) + if err != nil { + return errors.Wrapf(err, "auth") + } + cli.token, err = resp.GetString("token") + return err +} + +func (cli *SCephFSClient) GetCapabilities() []string { + return []string{ + cloudprovider.CLOUD_CAPABILITY_NAS, + } +} + +func (cli *SCephFSClient) list(res string, params url.Values) (jsonutils.JSONObject, error) { + client := cli.getDefaultClient() + url := fmt.Sprintf("%s/%s", cli.baseUrl(), res) + if len(params) > 0 { + url = fmt.Sprintf("%s/%s?%s", cli.baseUrl(), res, params.Encode()) + } + header := http.Header{} + header.Set("Accept", "application/vnd.ceph.api.v1.0+json") + header.Set("Accept-Encoding", "gzip") + header.Set("Authorization", fmt.Sprintf("Bearer %s", cli.token)) + _, resp, err := httputils.JSONRequest(client, context.Background(), httputils.GET, url, header, nil, cli.debug) + return resp, err +} + +func (cli *SCephFSClient) post(res string, params map[string]interface{}) (jsonutils.JSONObject, error) { + client := cli.getDefaultClient() + url := fmt.Sprintf("%s/%s", cli.baseUrl(), res) + header := http.Header{} + header.Set("Accept", "application/vnd.ceph.api.v1.0+json") + header.Set("Accept-Encoding", "gzip") + header.Set("Authorization", fmt.Sprintf("Bearer %s", cli.token)) + _, resp, err := httputils.JSONRequest(client, context.Background(), httputils.POST, url, header, jsonutils.Marshal(params), cli.debug) + return resp, err +} + +func (cli *SCephFSClient) delete(res string, params map[string]interface{}) (jsonutils.JSONObject, error) { + client := cli.getDefaultClient() + url := fmt.Sprintf("%s/%s", cli.baseUrl(), res) + header := http.Header{} + header.Set("Accept", "application/vnd.ceph.api.v1.0+json") + header.Set("Accept-Encoding", "gzip") + header.Set("Authorization", fmt.Sprintf("Bearer %s", cli.token)) + _, resp, err := httputils.JSONRequest(client, context.Background(), httputils.DELETE, url, header, jsonutils.Marshal(params), cli.debug) + return resp, err +} + +func (cli *SCephFSClient) put(res string, params map[string]interface{}) (jsonutils.JSONObject, error) { + client := cli.getDefaultClient() + url := fmt.Sprintf("%s/%s", cli.baseUrl(), res) + header := http.Header{} + header.Set("Accept", "application/vnd.ceph.api.v1.0+json") + header.Set("Accept-Encoding", "gzip") + header.Set("Authorization", fmt.Sprintf("Bearer %s", cli.token)) + _, resp, err := httputils.JSONRequest(client, context.Background(), httputils.PUT, url, header, jsonutils.Marshal(params), cli.debug) + return resp, err +} + +func (cli *SCephFSClient) GetProvider() string { + return api.CLOUD_PROVIDER_CEPHFS +} + +func (cli *SCephFSClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error) { + fss, err := cli.GetCephFSs() + if err != nil { + return nil, err + } + ret := []cloudprovider.SSubAccount{} + for _, fs := range fss { + subAccount := cloudprovider.SSubAccount{ + Id: cli.cpcfg.Id, + Account: fmt.Sprintf("%s/%s", cli.username, fs.Id), + Name: fs.Mdsmap.FsName, + HealthStatus: api.CLOUD_PROVIDER_HEALTH_NORMAL, + } + ret = append(ret, subAccount) + } + return ret, nil +} + +func (cli *SCephFSClient) GetAccountId() string { + return fmt.Sprintf("%s@%s:%d", cli.username, cli.host, cli.port) +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/cephfs/dirs.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/cephfs/dirs.go new file mode 100644 index 0000000000..d83446404c --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/cephfs/dirs.go @@ -0,0 +1,173 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cephfs + +import ( + "fmt" + "net/url" + "strings" + + api "yunion.io/x/cloudmux/pkg/apis/compute" + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud" + "yunion.io/x/pkg/errors" +) + +type SCephFsDir struct { + multicloud.SVirtualResourceBase + multicloud.SBillingBase + multicloud.STagBase + client *SCephFSClient + + Name string + Path string + Parent string + Quotas struct { + MaxFiles int64 + MaxBytes int64 + } +} + +func (dir *SCephFsDir) GetId() string { + return dir.Path +} + +func (dir *SCephFsDir) GetGlobalId() string { + return dir.Path +} + +func (dir *SCephFsDir) GetName() string { + return dir.Name +} + +func (dir *SCephFsDir) GetStatus() string { + return api.NAS_STATUS_AVAILABLE +} + +func (dir *SCephFsDir) GetFileSystemType() string { + return "standard" +} + +func (dir *SCephFsDir) GetStorageType() string { + return "capacity" +} + +func (dir *SCephFsDir) GetProtocol() string { + return "CephFS" +} + +func (dir *SCephFsDir) GetCapacityGb() int64 { + return dir.Quotas.MaxBytes / 1024 / 1024 / 1024 +} + +func (dir *SCephFsDir) GetUsedCapacityGb() int64 { + return 0 +} + +func (dir *SCephFsDir) GetMountTargetCountLimit() int { + return 0 +} + +func (dir *SCephFsDir) GetZoneId() string { + return "" +} + +func (dir *SCephFsDir) GetMountTargets() ([]cloudprovider.ICloudMountTarget, error) { + return []cloudprovider.ICloudMountTarget{}, nil +} + +func (dir *SCephFsDir) CreateMountTarget(opts *cloudprovider.SMountTargetCreateOptions) (cloudprovider.ICloudMountTarget, error) { + return nil, cloudprovider.ErrNotSupported +} + +func (dir *SCephFsDir) Delete() error { + return dir.client.DeleteDir(dir.client.fsId, dir.Path) +} + +func (cli *SCephFSClient) GetCephDirs(fsId string) ([]SCephFsDir, error) { + res := fmt.Sprintf("cephfs/%s/ls_dir", fsId) + params := url.Values{} + resp, err := cli.list(res, params) + if err != nil { + return nil, err + } + ret := []SCephFsDir{} + err = resp.Unmarshal(&ret) + if err != nil { + return nil, err + } + return ret, nil +} + +func (cli *SCephFSClient) GetICloudFileSystems() ([]cloudprovider.ICloudFileSystem, error) { + dirs, err := cli.GetCephDirs(cli.fsId) + if err != nil { + return nil, err + } + ret := []cloudprovider.ICloudFileSystem{} + for i := range dirs { + dirs[i].client = cli + ret = append(ret, &dirs[i]) + } + return ret, nil +} + +func (cli *SCephFSClient) GetICloudFileSystemById(id string) (cloudprovider.ICloudFileSystem, error) { + dirs, err := cli.GetCephDirs(cli.fsId) + if err != nil { + return nil, err + } + for i := range dirs { + dirs[i].client = cli + if dirs[i].GetGlobalId() == id { + return &dirs[i], nil + } + } + return nil, errors.Wrapf(cloudprovider.ErrNotFound, id) +} + +func (cli *SCephFSClient) CreateDir(fsId, path string) error { + res := fmt.Sprintf("cephfs/%s/tree", fsId) + _, err := cli.post(res, map[string]interface{}{ + "path": fmt.Sprintf("/%s", strings.TrimPrefix(path, "/")), + }) + return err +} + +func (cli *SCephFSClient) DeleteDir(fsId, path string) error { + res := fmt.Sprintf("cephfs/%s/tree", fsId) + _, err := cli.delete(res, map[string]interface{}{ + "path": fmt.Sprintf("/%s", strings.TrimPrefix(path, "/")), + }) + return err +} + +func (cli *SCephFSClient) SetDirQuota(fsId, path string, maxBytes int64) error { + res := fmt.Sprintf("cephfs/%s/quota", fsId) + _, err := cli.put(res, map[string]interface{}{ + "path": fmt.Sprintf("/%s", strings.TrimPrefix(path, "/")), + "max_bytes": maxBytes, + }) + return err +} + +func (cli *SCephFSClient) CreateICloudFileSystem(opts *cloudprovider.FileSystemCraeteOptions) (cloudprovider.ICloudFileSystem, error) { + err := cli.CreateDir(cli.fsId, opts.Name) + if err != nil { + return nil, err + } + cli.SetDirQuota(cli.fsId, opts.Name, opts.Capacity*1024*1024*1024) + return cli.GetICloudFileSystemById("/" + opts.Name) +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/cephfs/provider/provider.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/cephfs/provider/provider.go new file mode 100644 index 0000000000..3520ee81f6 --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/cephfs/provider/provider.go @@ -0,0 +1,248 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package provider + +import ( + "context" + "fmt" + "net/url" + "strconv" + "strings" + + "yunion.io/x/jsonutils" + "yunion.io/x/log" + "yunion.io/x/pkg/errors" + "yunion.io/x/pkg/util/regutils" + + api "yunion.io/x/cloudmux/pkg/apis/compute" + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud/cephfs" +) + +type SCephFSProviderFactory struct { + cloudprovider.SPremiseBaseProviderFactory +} + +func (self *SCephFSProviderFactory) GetId() string { + return cephfs.CLOUD_PROVIDER_CEPHFS +} + +func (self *SCephFSProviderFactory) GetName() string { + return cephfs.CLOUD_PROVIDER_CEPHFS +} + +func (self *SCephFSProviderFactory) ValidateChangeBandwidth(instanceId string, bandwidth int64) error { + return fmt.Errorf("Changing %s bandwidth is not supported", cephfs.CLOUD_PROVIDER_CEPHFS) +} + +func (self *SCephFSProviderFactory) ValidateCreateCloudaccountData(ctx context.Context, input cloudprovider.SCloudaccountCredential) (cloudprovider.SCloudaccount, error) { + output := cloudprovider.SCloudaccount{} + if len(input.Username) == 0 { + return output, errors.Wrap(cloudprovider.ErrMissingParameter, "username") + } + if len(input.Password) == 0 { + return output, errors.Wrap(cloudprovider.ErrMissingParameter, "password") + } + if len(input.Host) == 0 { + return output, errors.Wrap(cloudprovider.ErrMissingParameter, "host") + } + if !regutils.MatchIPAddr(input.Host) && !regutils.MatchDomainName(input.Host) { + return output, errors.Wrap(cloudprovider.ErrInputParameter, "host should be ip or domain name") + } + output.AccessUrl = fmt.Sprintf("https://%s:%d/api", input.Host, input.Port) + if input.Port == 443 { + output.AccessUrl = fmt.Sprintf("https://%s/api", input.Host) + } + output.Account = input.Username + output.Secret = input.Password + return output, nil +} + +func (self *SCephFSProviderFactory) ValidateUpdateCloudaccountCredential(ctx context.Context, input cloudprovider.SCloudaccountCredential, cloudaccount string) (cloudprovider.SCloudaccount, error) { + output := cloudprovider.SCloudaccount{} + if len(input.Username) == 0 { + return output, errors.Wrap(cloudprovider.ErrMissingParameter, "username") + } + if len(input.Password) == 0 { + return output, errors.Wrap(cloudprovider.ErrMissingParameter, "password") + } + output = cloudprovider.SCloudaccount{ + Account: input.Username, + Secret: input.Password, + } + if len(input.Host) > 0 { + if !regutils.MatchIPAddr(input.Host) && !regutils.MatchDomainName(input.Host) { + return output, errors.Wrap(cloudprovider.ErrInputParameter, "host should be ip or domain name") + } + output.AccessUrl = fmt.Sprintf("https://%s:%d/api", input.Host, input.Port) + if input.Port == 443 { + output.AccessUrl = fmt.Sprintf("https://%s/api", input.Host) + } + } + return output, nil +} + +func parseHostPort(host string, defPort int) (string, int, error) { + colonPos := strings.IndexByte(host, ':') + if colonPos > 0 { + h := host[:colonPos] + p, err := strconv.Atoi(host[colonPos+1:]) + if err != nil { + log.Errorf("Invalid host %s", host) + return "", 0, err + } + if p == 0 { + p = defPort + } + return h, p, nil + } else { + return host, defPort, nil + } +} + +func (self *SCephFSProviderFactory) GetProvider(cfg cloudprovider.ProviderConfig) (cloudprovider.ICloudProvider, error) { + parts, err := url.Parse(cfg.URL) + if err != nil { + return nil, err + } + host, port, err := parseHostPort(parts.Host, 8443) + if err != nil { + return nil, err + } + + account, fsId := cfg.Account, "" + if idx := strings.Index(account, "/"); idx > 0 { + account, fsId = cfg.Account[:idx], cfg.Account[idx+1:] + } + + client, err := cephfs.NewCephFSClient( + cephfs.NewCephFSClientConfig( + host, port, account, cfg.Secret, fsId, + ).CloudproviderConfig(cfg), + ) + if err != nil { + return nil, err + } + return &SCephFSProvider{ + SBaseProvider: cloudprovider.NewBaseProvider(self), + client: client, + }, nil +} + +func (self *SCephFSProviderFactory) GetClientRC(info cloudprovider.SProviderInfo) (map[string]string, error) { + parts, err := url.Parse(info.Url) + if err != nil { + return nil, err + } + host, port, err := parseHostPort(parts.Host, 443) + if err != nil { + return nil, err + } + + return map[string]string{ + "CEPHFS_HOST": host, + "CEPHFS_PORT": fmt.Sprintf("%d", port), + "CEPHFS_USERNAME": info.Account, + "CEPHFS_PASSWORD": info.Secret, + }, nil +} + +func (self *SCephFSProviderFactory) GetAccountIdEqualizer() func(origin, now string) bool { + return func(origin, now string) bool { + if len(now) == 0 { + return true + } + originUserName, nowUserName := origin, now + index1 := strings.Index(origin, "@") + index2 := strings.Index(now, "@") + if index1 != -1 { + originUserName = originUserName[:index1] + } + if index2 != -1 { + nowUserName = nowUserName[:index2] + } + return originUserName == nowUserName + } +} + +func init() { + factory := SCephFSProviderFactory{} + cloudprovider.RegisterFactory(&factory) +} + +type SCephFSProvider struct { + cloudprovider.SBaseProvider + client *cephfs.SCephFSClient +} + +func (self *SCephFSProvider) GetSysInfo() (jsonutils.JSONObject, error) { + return jsonutils.NewDict(), nil +} + +func (self *SCephFSProvider) GetVersion() string { + return "v1.0" +} + +func (self *SCephFSProvider) GetSubAccounts() ([]cloudprovider.SSubAccount, error) { + return self.client.GetSubAccounts() +} + +func (self *SCephFSProvider) GetAccountId() string { + return self.client.GetAccountId() +} + +func (self *SCephFSProvider) GetIRegions() []cloudprovider.ICloudRegion { + return nil +} + +func (self *SCephFSProvider) GetIRegionById(id string) (cloudprovider.ICloudRegion, error) { + return nil, cloudprovider.ErrNotSupported +} + +func (self *SCephFSProvider) GetBalance() (*cloudprovider.SBalanceInfo, error) { + return &cloudprovider.SBalanceInfo{ + Amount: 0.0, + Currency: "CNY", + Status: api.CLOUD_PROVIDER_HEALTH_NORMAL, + }, cloudprovider.ErrNotSupported +} + +func (self *SCephFSProvider) GetOnPremiseIRegion() (cloudprovider.ICloudRegion, error) { + return self.client, nil +} + +func (self *SCephFSProvider) GetIProjects() ([]cloudprovider.ICloudProject, error) { + return []cloudprovider.ICloudProject{}, nil +} + +func (self *SCephFSProvider) GetStorageClasses(regionId string) []string { + return nil +} + +func (self *SCephFSProvider) GetBucketCannedAcls(regionId string) []string { + return nil +} + +func (self *SCephFSProvider) GetObjectCannedAcls(regionId string) []string { + return nil +} + +func (self *SCephFSProvider) GetCapabilities() []string { + return self.client.GetCapabilities() +} + +func (self *SCephFSProvider) GetMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) { + return nil, cloudprovider.ErrNotSupported +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/hcso/natgateway.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/hcso/natgateway.go index d46b04e35f..d8b67e8913 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/hcso/natgateway.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/hcso/natgateway.go @@ -74,6 +74,10 @@ func (self *SNatGateway) GetINetworkId() string { return self.InternalNetworkId } +func (self *SNatGateway) GetNetworkType() string { + return api.NAT_NETWORK_TYPE_INTERNET +} + func (gateway *SNatGateway) GetNatSpec() string { switch gateway.Spec { case "1": @@ -182,7 +186,7 @@ func (gateway *SNatGateway) CreateINatSEntry(rule cloudprovider.SNatSRule) (clou return &snat, nil } -func (gateway *SNatGateway) GetINatDEntryByID(id string) (cloudprovider.ICloudNatDEntry, error) { +func (gateway *SNatGateway) GetINatDEntryById(id string) (cloudprovider.ICloudNatDEntry, error) { dnat, err := gateway.region.GetNatDEntryByID(id) if err != nil { return nil, err @@ -191,7 +195,7 @@ func (gateway *SNatGateway) GetINatDEntryByID(id string) (cloudprovider.ICloudNa return &dnat, nil } -func (gateway *SNatGateway) GetINatSEntryByID(id string) (cloudprovider.ICloudNatSEntry, error) { +func (gateway *SNatGateway) GetINatSEntryById(id string) (cloudprovider.ICloudNatSEntry, error) { snat, err := gateway.region.GetNatSEntryByID(id) if err != nil { return nil, err diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/eip.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/eip.go index 1a1cb03924..a98cd10aad 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/eip.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/eip.go @@ -328,7 +328,7 @@ func (self *SRegion) GetEips(portId string, addrs []string) ([]SEipAddress, erro query.Add("public_ip_address", addr) } if len(portId) > 0 { - query.Set("port_id", portId) + query.Set("vnic.port_id", portId) } query.Set("ip_version", "4") eips := []SEipAddress{} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/huawei.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/huawei.go index f7614720e1..ba531406c6 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/huawei.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/huawei.go @@ -64,6 +64,7 @@ const ( SERVICE_SFS = "sfs-turbo" SERVICE_CTS = "cts" SERVICE_NAT = "nat" + SERVICE_NAT_V2 = "nat_v2" SERVICE_BMS = "bms" SERVICE_CCI = "cci" SERVICE_CSBS = "csbs" @@ -650,6 +651,8 @@ func (self *SHuaweiClient) getUrl(service, regionId, resource string, method htt url = fmt.Sprintf("https://cts.%s.myhuaweicloud.com/v3/%s/%s", regionId, projectId, resource) case SERVICE_NAT: url = fmt.Sprintf("https://nat.%s.myhuaweicloud.com/v3/%s/%s", regionId, projectId, resource) + case SERVICE_NAT_V2: + url = fmt.Sprintf("https://nat.%s.myhuaweicloud.com/v2/%s/%s", regionId, projectId, resource) case SERVICE_SCM: url = fmt.Sprintf("https://scm.cn-north-4.myhuaweicloud.com/v3/%s", resource) case SERVICE_CDN: diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/nat.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/nat.go new file mode 100644 index 0000000000..c9055d5ef7 --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/nat.go @@ -0,0 +1,246 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package huawei + +import ( + "net/url" + "time" + + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" + + billing_api "yunion.io/x/cloudmux/pkg/apis/billing" + api "yunion.io/x/cloudmux/pkg/apis/compute" + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud" +) + +// 公网NAT +type SNatgateway struct { + multicloud.SNatGatewayBase + HuaweiTags + region *SRegion + + Id string + Name string + Description string + Spec string + Status string + AdminStateUp bool + + InternalNetworkId string + RouterId string + CreatedAt string `json:"created_at"` + EnterpriseProject_id string + NgportIpAddress string + BillingInfo string + DnatRulesLimit int + SnatRulePublicIpLimit int +} + +func (gateway *SNatgateway) GetId() string { + return gateway.Id +} + +func (gateway *SNatgateway) GetName() string { + return gateway.Name +} + +func (gateway *SNatgateway) GetGlobalId() string { + return gateway.GetId() +} + +func (gateway *SNatgateway) GetStatus() string { + return NatResouceStatusTransfer(gateway.Status) +} + +func (self *SNatgateway) Delete() error { + return self.region.DeleteNatgateway(self.Id) +} + +func (self *SNatgateway) Refresh() error { + nat, err := self.region.GetNatgateway(self.Id) + if err != nil { + return errors.Wrapf(err, "GetNatgateway(%s)", self.Id) + } + return jsonutils.Update(self, nat) +} + +func (self *SNatgateway) GetINetworkId() string { + return self.InternalNetworkId +} + +func (self *SNatgateway) GetNetworkType() string { + return api.NAT_NETWORK_TYPE_INTERNET +} + +func (gateway *SNatgateway) GetNatSpec() string { + switch gateway.Spec { + case "1": + return api.NAT_SPEC_SMALL + case "2": + return api.NAT_SPEC_MIDDLE + case "3": + return api.NAT_SPEC_LARGE + case "4": + return api.NAT_SPEC_XLARGE + } + return gateway.Spec +} + +func (gateway *SNatgateway) GetDescription() string { + return gateway.Description +} + +func (gateway *SNatgateway) GetBillingType() string { + if len(gateway.BillingInfo) > 0 { + return billing_api.BILLING_TYPE_PREPAID + } + return billing_api.BILLING_TYPE_POSTPAID +} + +func (gateway *SNatgateway) GetCreatedAt() time.Time { + t, _ := time.Parse("2006-01-02 15:04:05.000000", gateway.CreatedAt) + return t +} + +func (gateway *SNatgateway) GetExpiredAt() time.Time { + // no support for expired time + return time.Time{} +} + +func (gateway *SNatgateway) GetIEips() ([]cloudprovider.ICloudEIP, error) { + ports, err := gateway.region.GetPorts(gateway.Id) + if err != nil { + return nil, errors.Wrapf(err, "GetPorts(%s)", gateway.Id) + } + ret := []cloudprovider.ICloudEIP{} + for i := range ports { + eips, err := gateway.region.GetEips(ports[i].ID, nil) + if err != nil { + return nil, err + } + for i := range eips { + eips[i].region = gateway.region + ret = append(ret, &eips[i]) + } + } + return ret, nil +} + +func (gateway *SNatgateway) GetINatDTable() ([]cloudprovider.ICloudNatDEntry, error) { + dNatTable, err := gateway.region.GetPublicNatDTable(gateway.Id) + if err != nil { + return nil, errors.Wrapf(err, "GetPublicNatDTable") + } + ret := []cloudprovider.ICloudNatDEntry{} + for i := range dNatTable { + dNatTable[i].nat = gateway + ret = append(ret, &dNatTable[i]) + } + return ret, nil +} + +func (gateway *SNatgateway) GetINatSTable() ([]cloudprovider.ICloudNatSEntry, error) { + sNatTable, err := gateway.region.GetPublicNatSTable(gateway.Id) + if err != nil { + return nil, errors.Wrapf(err, "GetNatSTable") + } + ret := []cloudprovider.ICloudNatSEntry{} + for i := range sNatTable { + sNatTable[i].nat = gateway + ret = append(ret, &sNatTable[i]) + } + return ret, nil +} + +func (gateway *SNatgateway) GetINatDEntryById(id string) (cloudprovider.ICloudNatDEntry, error) { + dnat, err := gateway.region.GetNatDTable(id) + if err != nil { + return nil, err + } + dnat.nat = gateway + return dnat, nil +} + +func (gateway *SNatgateway) GetINatSEntryById(id string) (cloudprovider.ICloudNatSEntry, error) { + snat, err := gateway.region.GetNatSEntry(id) + if err != nil { + return nil, err + } + snat.nat = gateway + return snat, nil +} + +func (region *SRegion) GetNatgateways(vpcId, id string) ([]SNatgateway, error) { + query := url.Values{} + if len(id) != 0 { + query.Set("id", id) + } + if len(vpcId) != 0 { + query.Set("router_id", vpcId) + } + ret := []SNatgateway{} + for { + resp, err := region.list(SERVICE_NAT_V2, "nat_gateways", query) + if err != nil { + return nil, err + } + part := struct { + NatGateways []SNatgateway + }{} + err = resp.Unmarshal(&part) + if err != nil { + return nil, err + } + ret = append(ret, part.NatGateways...) + if len(part.NatGateways) == 0 { + break + } + query.Set("marker", part.NatGateways[len(part.NatGateways)-1].Id) + } + return ret, nil +} + +func (region *SRegion) GetNatDTable(id string) (*SNatDTable, error) { + resp, err := region.list(SERVICE_NAT_V2, "dnat_rules/"+id, nil) + if err != nil { + return nil, err + } + ret := &SNatDTable{} + err = resp.Unmarshal(ret, "dnat_rule") + if err != nil { + return nil, err + } + return ret, nil +} + +func (self *SRegion) GetNatgateway(id string) (*SNatgateway, error) { + resp, err := self.list(SERVICE_NAT_V2, "nat_gateways/"+id, nil) + if err != nil { + return nil, err + } + nat := &SNatgateway{region: self} + err = resp.Unmarshal(nat, "nat_gateway") + if err != nil { + return nil, err + } + return nat, nil +} + +func (self *SRegion) DeleteNatgateway(id string) error { + _, err := self.delete(SERVICE_NAT_V2, "nat_gateways/"+id) + return err +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/nat_dtable.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/nat_dtable.go new file mode 100644 index 0000000000..f33f4a478b --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/nat_dtable.go @@ -0,0 +1,160 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package huawei + +import ( + "fmt" + "net/url" + + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud" + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" +) + +type SNatDTable struct { + multicloud.SResourceBase + multicloud.STagBase + nat *SNatgateway + + Id string + Description string + PortId string + PrivateIp string + InternalServicePort int + NatGatewayId string + FloatingIpId string + FloatingIpAddress string + ExternalServicePort int + Status string + AdminStateUp bool + InternalServicePortRange string + ExternalServicePortRange string + Protocol string + CreatedAt string + GlobalEipId string + GlobalEipAddress string +} + +func (nat *SNatDTable) GetId() string { + return nat.Id +} + +func (nat *SNatDTable) GetName() string { + return nat.GetId() +} + +func (nat *SNatDTable) GetGlobalId() string { + return nat.GetId() +} + +func (nat *SNatDTable) GetStatus() string { + return NatResouceStatusTransfer(nat.Status) +} + +func (nat *SNatDTable) Refresh() error { + table, err := nat.nat.region.GetNatDTable(nat.Id) + if err != nil { + return err + } + return jsonutils.Update(nat, table) +} + +func (nat *SNatDTable) GetIpProtocol() string { + return nat.Protocol +} + +func (nat *SNatDTable) GetExternalIp() string { + return nat.FloatingIpAddress +} + +func (nat *SNatDTable) GetExternalPort() int { + return nat.ExternalServicePort +} + +func (nat *SNatDTable) GetInternalIp() string { + return nat.PrivateIp +} + +func (nat *SNatDTable) GetInternalPort() int { + return nat.InternalServicePort +} + +func (nat *SNatDTable) Delete() error { + return nat.nat.region.DeletePublicNatDEntry(nat.nat.Id, nat.GetId()) +} + +func (region *SRegion) DeletePublicNatDEntry(natId, id string) error { + res := fmt.Sprintf("nat_gateways/%s/dnat_rules/%s", natId, id) + _, err := region.delete(SERVICE_NAT_V2, res) + return err +} + +func (region *SRegion) GetPublicNatDTable(natId string) ([]SNatDTable, error) { + query := url.Values{} + if len(natId) > 0 { + query.Set("nat_gateway_id", natId) + } + ret := []SNatDTable{} + for { + resp, err := region.list(SERVICE_NAT_V2, "dnat_rules", query) + if err != nil { + return nil, err + } + part := struct { + DnatRules []SNatDTable + }{} + err = resp.Unmarshal(&part) + if err != nil { + return nil, err + } + ret = append(ret, part.DnatRules...) + if len(part.DnatRules) == 0 { + break + } + query.Set("marker", part.DnatRules[len(part.DnatRules)-1].Id) + } + return ret, nil +} + +func (gateway *SNatgateway) CreateINatDEntry(rule cloudprovider.SNatDRule) (cloudprovider.ICloudNatDEntry, error) { + dnat, err := gateway.region.CreateNatDTable(rule, gateway.GetId()) + if err != nil { + return nil, err + } + dnat.nat = gateway + return dnat, nil +} + +func (region *SRegion) CreateNatDTable(rule cloudprovider.SNatDRule, gatewayID string) (*SNatDTable, error) { + params := make(map[string]interface{}) + params["nat_gateway_id"] = gatewayID + params["private_ip"] = rule.InternalIP + params["internal_service_port"] = rule.InternalPort + params["floating_ip_id"] = rule.ExternalIPID + params["external_service_port"] = rule.ExternalPort + params["protocol"] = rule.Protocol + + resp, err := region.post(SERVICE_NAT_V2, "dnat_rules", map[string]interface{}{"dnat_rule": params}) + if err != nil { + return nil, errors.Wrapf(err, "create dnat") + } + ret := &SNatDTable{} + err = resp.Unmarshal(ret, "dnat_rule") + if err != nil { + return nil, err + } + return ret, nil +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/nat_stable.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/nat_stable.go new file mode 100644 index 0000000000..60f3d36afd --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/nat_stable.go @@ -0,0 +1,162 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package huawei + +import ( + "fmt" + "net/url" + + "yunion.io/x/cloudmux/pkg/cloudprovider" + "yunion.io/x/cloudmux/pkg/multicloud" + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" +) + +type SNatSTable struct { + multicloud.SResourceBase + multicloud.STagBase + + nat *SNatgateway + Id string + Cidr string + SourceType int + FloatingIpId string + Description string + Status string + CreatedAt string + NetworkId string + AdminStateUp bool + FloatingIpAddress string + FreezedIpAddress string + GlobalEipId string + GlobalEipAddress string +} + +func (nat *SNatSTable) GetId() string { + return nat.Id +} + +func (nat *SNatSTable) GetName() string { + return nat.GetId() +} + +func (nat *SNatSTable) GetGlobalId() string { + return nat.GetId() +} + +func (nat *SNatSTable) GetStatus() string { + return NatResouceStatusTransfer(nat.Status) +} + +func (nat *SNatSTable) GetIP() string { + return nat.FloatingIpAddress +} + +func (nat *SNatSTable) Refresh() error { + table, err := nat.nat.region.GetNatSEntry(nat.Id) + if err != nil { + return err + } + return jsonutils.Update(nat, table) +} + +func (nat *SNatSTable) GetSourceCIDR() string { + return nat.Cidr +} + +func (nat *SNatSTable) GetNetworkId() string { + return nat.NetworkId +} + +func (nat *SNatSTable) Delete() error { + return nat.nat.region.DeleteNatSTable(nat.nat.Id, nat.GetId()) +} + +func (region *SRegion) DeleteNatSTable(natId, id string) error { + res := fmt.Sprintf("nat_gateways/%s/snat_rules/%s", natId, id) + _, err := region.delete(SERVICE_NAT_V2, res) + return err +} + +func (region *SRegion) GetNatSEntry(id string) (*SNatSTable, error) { + resp, err := region.list(SERVICE_NAT_V2, "snat_rules/"+id, nil) + if err != nil { + return nil, err + } + ret := &SNatSTable{} + err = resp.Unmarshal(ret, "snat_rule") + if err != nil { + return nil, err + } + return ret, nil +} + +func (region *SRegion) GetPublicNatSTable(natId string) ([]SNatSTable, error) { + query := url.Values{} + if len(natId) > 0 { + query.Set("nat_gateway_id", natId) + } + ret := []SNatSTable{} + for { + resp, err := region.list(SERVICE_NAT_V2, "snat_rules", query) + if err != nil { + return nil, err + } + part := struct { + SnatRules []SNatSTable + }{} + err = resp.Unmarshal(&part) + if err != nil { + return nil, err + } + ret = append(ret, part.SnatRules...) + if len(part.SnatRules) == 0 { + break + } + query.Set("marker", part.SnatRules[len(part.SnatRules)-1].Id) + } + return ret, nil +} + +func (gateway *SNatgateway) CreateINatSEntry(rule cloudprovider.SNatSRule) (cloudprovider.ICloudNatSEntry, error) { + snat, err := gateway.region.CreateNatSTable(rule, gateway.GetId()) + if err != nil { + return nil, err + } + snat.nat = gateway + return snat, nil +} + +func (region *SRegion) CreateNatSTable(rule cloudprovider.SNatSRule, gatewayId string) (*SNatSTable, error) { + params := make(map[string]interface{}) + params["nat_gateway_id"] = gatewayId + if len(rule.NetworkID) != 0 { + params["network_id"] = rule.NetworkID + } + if len(rule.SourceCIDR) != 0 { + params["cidr"] = rule.SourceCIDR + } + params["floating_ip_id"] = rule.ExternalIPID + resp, err := region.post(SERVICE_NAT_V2, "snat_rules", map[string]interface{}{"snat_rule": params}) + if err != nil { + return nil, errors.Wrapf(err, "create snat") + } + ret := &SNatSTable{} + err = resp.Unmarshal(ret, "snat_rule") + if err != nil { + return nil, err + } + return ret, nil +} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/natdtable.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/natdtable.go index f52bbd745b..5d650e3b73 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/natdtable.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/natdtable.go @@ -80,19 +80,7 @@ func (nat *SNatDEntry) Delete() error { return nat.gateway.region.DeleteNatDEntry(nat.GetId()) } -// getNatSTable return all snat rules of gateway -func (gateway *SNatGateway) getNatDTable() ([]SNatDEntry, error) { - ret, err := gateway.region.GetNatDTable(gateway.GetId()) - if err != nil { - return nil, err - } - for i := range ret { - ret[i].gateway = gateway - } - return ret, nil -} - -func (region *SRegion) GetNatDTable(natId string) ([]SNatDEntry, error) { +func (region *SRegion) GetNatDEntries(natId string) ([]SNatDEntry, error) { query := url.Values{} if len(natId) > 0 { query.Set("gateway_id", natId) diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/natgateway.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/natgateway.go index ad35559437..456cc331e8 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/natgateway.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/natgateway.go @@ -74,6 +74,10 @@ func (self *SNatGateway) GetINetworkId() string { return self.InternalNetworkId } +func (self *SNatGateway) GetNetworkType() string { + return api.NAT_NETWORK_TYPE_INTRANET +} + func (gateway *SNatGateway) GetNatSpec() string { switch gateway.Spec { case "1": @@ -127,24 +131,26 @@ func (gateway *SNatGateway) GetIEips() ([]cloudprovider.ICloudEIP, error) { } func (gateway *SNatGateway) GetINatDTable() ([]cloudprovider.ICloudNatDEntry, error) { - dNatTable, err := gateway.getNatDTable() + dNatTable, err := gateway.region.GetNatDEntries(gateway.ID) if err != nil { return nil, errors.Wrapf(err, `get dnat table of nat gateway %q`, gateway.GetId()) } ret := make([]cloudprovider.ICloudNatDEntry, len(dNatTable)) for i := range dNatTable { + dNatTable[i].gateway = gateway ret[i] = &dNatTable[i] } return ret, nil } func (gateway *SNatGateway) GetINatSTable() ([]cloudprovider.ICloudNatSEntry, error) { - sNatTable, err := gateway.getNatSTable() + sNatTable, err := gateway.region.GetNatSEntries(gateway.ID) if err != nil { return nil, errors.Wrapf(err, `get dnat table of nat gateway %q`, gateway.GetId()) } ret := make([]cloudprovider.ICloudNatSEntry, len(sNatTable)) for i := range sNatTable { + sNatTable[i].gateway = gateway ret[i] = &sNatTable[i] } return ret, nil @@ -168,7 +174,7 @@ func (gateway *SNatGateway) CreateINatSEntry(rule cloudprovider.SNatSRule) (clou return snat, nil } -func (gateway *SNatGateway) GetINatDEntryByID(id string) (cloudprovider.ICloudNatDEntry, error) { +func (gateway *SNatGateway) GetINatDEntryById(id string) (cloudprovider.ICloudNatDEntry, error) { dnat, err := gateway.region.GetNatDEntryByID(id) if err != nil { return nil, err @@ -177,7 +183,7 @@ func (gateway *SNatGateway) GetINatDEntryByID(id string) (cloudprovider.ICloudNa return dnat, nil } -func (gateway *SNatGateway) GetINatSEntryByID(id string) (cloudprovider.ICloudNatSEntry, error) { +func (gateway *SNatGateway) GetINatSEntryById(id string) (cloudprovider.ICloudNatSEntry, error) { snat, err := gateway.region.GetNatSEntryByID(id) if err != nil { return nil, err @@ -219,7 +225,7 @@ func (region *SRegion) GetNatGateways(vpcId, id string) ([]SNatGateway, error) { func (region *SRegion) CreateNatDEntry(rule cloudprovider.SNatDRule, gatewayID string) (*SNatDEntry, error) { params := make(map[string]interface{}) - params["nat_gateway_id"] = gatewayID + params["gateway_id"] = gatewayID params["private_ip"] = rule.InternalIP params["internal_service_port"] = rule.InternalPort params["floating_ip_id"] = rule.ExternalIPID @@ -240,7 +246,7 @@ func (region *SRegion) CreateNatDEntry(rule cloudprovider.SNatDRule, gatewayID s func (region *SRegion) CreateNatSEntry(rule cloudprovider.SNatSRule, gatewayId string) (*SNatSEntry, error) { params := make(map[string]interface{}) - params["nat_gateway_id"] = gatewayId + params["gateway_id"] = gatewayId if len(rule.NetworkID) != 0 { params["network_id"] = rule.NetworkID } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/natstable.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/natstable.go index dd0ee09331..e08e65791f 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/natstable.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/natstable.go @@ -41,7 +41,6 @@ func (nat *SNatSEntry) GetId() string { } func (nat *SNatSEntry) GetName() string { - // Snat rule has no name in Huawei Cloud, so return ID return nat.GetId() } @@ -69,18 +68,7 @@ func (nat *SNatSEntry) Delete() error { return nat.gateway.region.DeleteNatSEntry(nat.GetId()) } -func (gateway *SNatGateway) getNatSTable() ([]SNatSEntry, error) { - ret, err := gateway.region.GetNatSTable(gateway.GetId()) - if err != nil { - return nil, err - } - for i := range ret { - ret[i].gateway = gateway - } - return ret, nil -} - -func (region *SRegion) GetNatSTable(natId string) ([]SNatSEntry, error) { +func (region *SRegion) GetNatSEntries(natId string) ([]SNatSEntry, error) { query := url.Values{} if len(natId) > 0 { query.Set("gateway_id", natId) diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/sfs-turbo.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/sfs-turbo.go index e820a61a73..59c42b15da 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/sfs-turbo.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/sfs-turbo.go @@ -152,6 +152,10 @@ func (self *SfsTurbo) Delete() error { return self.region.DeleteSfsTurbo(self.Id) } +func (self *SfsTurbo) GetProjectId() string { + return self.EnterpriseProjectId +} + func (self *SRegion) GetICloudFileSystems() ([]cloudprovider.ICloudFileSystem, error) { sfs, err := self.GetSfsTurbos() if err != nil { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/vpc.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/vpc.go index 9b8c41c238..45f13c10c3 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/vpc.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/huawei/vpc.go @@ -130,10 +130,18 @@ func (self *SVpc) GetINatGateways() ([]cloudprovider.ICloudNatGateway, error) { if err != nil { return nil, err } - ret := make([]cloudprovider.ICloudNatGateway, len(nats)) + nats2, err := self.region.GetNatgateways(self.GetId(), "") + if err != nil { + return nil, err + } + ret := []cloudprovider.ICloudNatGateway{} for i := 0; i < len(nats); i++ { nats[i].region = self.region - ret[i] = &nats[i] + ret = append(ret, &nats[i]) + } + for i := range nats2 { + nats2[i].region = self.region + ret = append(ret, &nats2[i]) } return ret, nil } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/loader/loader.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/loader/loader.go index afce5dbbb7..9d6c498e46 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/loader/loader.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/loader/loader.go @@ -23,6 +23,7 @@ import ( _ "yunion.io/x/cloudmux/pkg/multicloud/azure/provider" _ "yunion.io/x/cloudmux/pkg/multicloud/baidu/provider" _ "yunion.io/x/cloudmux/pkg/multicloud/bingocloud/provider" // private clouds + _ "yunion.io/x/cloudmux/pkg/multicloud/cephfs/provider" _ "yunion.io/x/cloudmux/pkg/multicloud/ctyun/provider" _ "yunion.io/x/cloudmux/pkg/multicloud/cucloud/provider" _ "yunion.io/x/cloudmux/pkg/multicloud/ecloud/provider" // public clouds diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/nas_base.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/nas_base.go index 1fe6a505d8..8d8b2b9495 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/nas_base.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/nas_base.go @@ -15,6 +15,6 @@ package multicloud type SNasBase struct { - SResourceBase + SVirtualResourceBase SBillingBase } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/natgateway.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/natgateway.go index c5b5ea6a12..70ea9fea08 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/natgateway.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/qcloud/natgateway.go @@ -62,6 +62,10 @@ func (self *SNatGateway) GetINetworkId() string { return "" } +func (self *SNatGateway) GetNetworkType() string { + return api.NAT_NETWORK_TYPE_INTERNET +} + func (nat *SNatGateway) GetStatus() string { switch nat.State { case "PENDING": @@ -133,11 +137,11 @@ func (nat *SNatGateway) GetINatDTable() ([]cloudprovider.ICloudNatDEntry, error) return itables, nil } -func (nat *SNatGateway) GetINatDEntryByID(id string) (cloudprovider.ICloudNatDEntry, error) { +func (nat *SNatGateway) GetINatDEntryById(id string) (cloudprovider.ICloudNatDEntry, error) { return nil, cloudprovider.ErrNotImplemented } -func (nat *SNatGateway) GetINatSEntryByID(id string) (cloudprovider.ICloudNatSEntry, error) { +func (nat *SNatGateway) GetINatSEntryById(id string) (cloudprovider.ICloudNatSEntry, error) { return nil, cloudprovider.ErrNotImplemented } diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/volcengine/natgateway.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/volcengine/natgateway.go index 5692c45482..bc4fac8953 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/volcengine/natgateway.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/volcengine/natgateway.go @@ -88,6 +88,10 @@ func (nat *SNatGateway) GetINetworkId() string { return nat.SubnetId } +func (nat *SNatGateway) GetNetworkType() string { + return api.NAT_NETWORK_TYPE_INTERNET +} + func (nat *SNatGateway) GetIpAddr() string { if len(nat.PrivateIP) > 0 { return nat.PrivateIP @@ -168,7 +172,7 @@ func (nat *SNatGateway) GetINatSTable() ([]cloudprovider.ICloudNatSEntry, error) return itables, nil } -func (nat *SNatGateway) GetINatDEntryByID(id string) (cloudprovider.ICloudNatDEntry, error) { +func (nat *SNatGateway) GetINatDEntryById(id string) (cloudprovider.ICloudNatDEntry, error) { dNATEntry, err := nat.vpc.region.GetDnatEntry(nat.NatGatewayId, id) if err != nil { return nil, cloudprovider.ErrNotFound @@ -177,7 +181,7 @@ func (nat *SNatGateway) GetINatDEntryByID(id string) (cloudprovider.ICloudNatDEn return &dNATEntry, nil } -func (nat *SNatGateway) GetINatSEntryByID(id string) (cloudprovider.ICloudNatSEntry, error) { +func (nat *SNatGateway) GetINatSEntryById(id string) (cloudprovider.ICloudNatSEntry, error) { sNATEntry, err := nat.vpc.region.GetSnatEntry(nat.NatGatewayId, id) if err != nil { return nil, cloudprovider.ErrNotFound @@ -191,7 +195,7 @@ func (nat *SNatGateway) CreateINatDEntry(rule cloudprovider.SNatDRule) (cloudpro if err != nil { return nil, errors.Wrapf(err, `create dnat rule for nat gateway %q`, nat.GetId()) } - return nat.GetINatDEntryByID(entryID) + return nat.GetINatDEntryById(entryID) } func (nat *SNatGateway) CreateINatSEntry(rule cloudprovider.SNatSRule) (cloudprovider.ICloudNatSEntry, error) { @@ -199,7 +203,7 @@ func (nat *SNatGateway) CreateINatSEntry(rule cloudprovider.SNatSRule) (cloudpro if err != nil { return nil, errors.Wrapf(err, `create snat rule for nat gateway %q`, nat.GetId()) } - return nat.GetINatSEntryByID(entryID) + return nat.GetINatSEntryById(entryID) } func (region *SRegion) GetNatGateways(vpcId string, natGatewayId string, pageNumber int, pageSize int) ([]SNatGateway, int, error) { diff --git a/vendor/yunion.io/x/sqlchemy/README.md b/vendor/yunion.io/x/sqlchemy/README.md index 843c81ae1e..1ff62d641f 100644 --- a/vendor/yunion.io/x/sqlchemy/README.md +++ b/vendor/yunion.io/x/sqlchemy/README.md @@ -11,7 +11,7 @@ Features * Automatic creation and synchronization of table schema based on golang struct * Query syntax inpired by sqlalchemy -* Support: MySQL/MariaDB with InnoDB engine / Sqlite (Exprimental) / ClickHouse (Exprimental) +* Support: MySQL/MariaDB with InnoDB engine / Sqlite (Exprimental) / ClickHouse / Dameng (Exprimental) * Support select, insert, update and insertOrupdate (no delete) Quick Examples @@ -52,6 +52,14 @@ dbconn := sql.Open("clickhouse", "tcp://host1:9000?username=user&password=qwerty sqlchemy.SetDBWithNameBackend(dbconn, sqlchemy.DBName("clickhousedb"), sqlchemy.ClickhouseBackend) ``` +### Setup database of Dameng + +```go +dbconn := sql.Open("dm", "dm://username:password@host1:5246/schema") + +sqlchemy.SetDBWithNameBackend(dbconn, sqlchemy.DBName("damengdb"), sqlchemy.DamengBackend) +``` + ## Table Schema Table schema is defined by struct field tags diff --git a/vendor/yunion.io/x/sqlchemy/backends.go b/vendor/yunion.io/x/sqlchemy/backends.go index 4a7811da33..7f17adda61 100644 --- a/vendor/yunion.io/x/sqlchemy/backends.go +++ b/vendor/yunion.io/x/sqlchemy/backends.go @@ -25,9 +25,12 @@ const ( MySQLBackend = DBBackendName("MySQL") // Clickhouse is the backend name of Clickhouse ClickhouseBackend = DBBackendName("Clickhouse") - // SQLiteBackend is the backend name of Sqlite3 + // SQLite is the backend name of Sqlite3 SQLiteBackend = DBBackendName("SQLite") // PostgreSQLBackend = DBBackendName("PostgreSQL") + + // DAMENG is the backend name of DAMENG + DamengBackend = DBBackendName("DAMENG") ) // IBackend is the interface for all kinds of sql backends, e.g. MySQL, ClickHouse, Sqlite, PostgreSQL, etc. @@ -81,6 +84,15 @@ type IBackend interface { UpdateSQLTemplate() string // InsertOrUpdateSQLTemplate returns the template of insert or update SQL InsertOrUpdateSQLTemplate() string + // prepare insert or update sql + // t: ITableSpec + // names: insert target column names + // insertFields: insert target column values format + // primaryKeys: on conditions primary keys + // updates: update set values + // values: insert values + // updateupdateValues: update values + PrepareInsertOrUpdateSQL(ts ITableSpec, insertColNames []string, insertFields []string, onPrimaryCols []string, updateSetCols []string, insertValues []interface{}, updateValues []interface{}) (string, []interface{}) // CanSupportRowAffected returns wether the backend support RowAffected method after update // MySQL: true @@ -91,6 +103,8 @@ type IBackend interface { // CommitTableChangeSQL outputs the SQLs to alter a table CommitTableChangeSQL(ts ITableSpec, changes STableChanges) []string + QuoteChar() string + /////////////////////////////////////////////////////////////////////// ////////////////// FUNCTIONS ////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// diff --git a/vendor/yunion.io/x/sqlchemy/backends/clickhouse/functions.go b/vendor/yunion.io/x/sqlchemy/backends/clickhouse/functions.go index c5c39989e3..31f76ce578 100644 --- a/vendor/yunion.io/x/sqlchemy/backends/clickhouse/functions.go +++ b/vendor/yunion.io/x/sqlchemy/backends/clickhouse/functions.go @@ -22,5 +22,5 @@ import ( // GROUP_CONCAT1 represents the SQL function GROUP_CONCAT func (click *SClickhouseBackend) GROUP_CONCAT2(name string, sep string, field sqlchemy.IQueryField) sqlchemy.IQueryField { - return sqlchemy.NewFunctionField(name, fmt.Sprintf("arrayStringConcat(groupUniqArray(%%s), '%s')", sep), field) + return sqlchemy.NewFunctionField(name, true, fmt.Sprintf("arrayStringConcat(groupUniqArray(%%s), '%s')", sep), field) } diff --git a/vendor/yunion.io/x/sqlchemy/backends/dameng/README.md b/vendor/yunion.io/x/sqlchemy/backends/dameng/README.md new file mode 100644 index 0000000000..7a0df70bd7 --- /dev/null +++ b/vendor/yunion.io/x/sqlchemy/backends/dameng/README.md @@ -0,0 +1,55 @@ +达梦数据库驱动 +================== + + +https://gitee.com/chunanyong/dm + + +初始化要求:UTF-8字符编码,不区分大小写,建表语句的字段名不要带""双引号 + +./dminit path=/opt/dmdbms/data page_size=32 extent_size=16 log_size=2048 port_num=5236 charset=1 case_sensitive=0 LENGTH_IN_CHAR=1 db_name=DAMENG instance_name=DMSERVER + +注册服务 +cd /opt/dmdbms/script/root +./dm_service_installer.sh -t dmserver -dm_ini /opt/dmdbms/data/DAMENG/dm.ini -p DMSERVER + +修改 /opt/dmdbms/data/DAMENG/dm.ini 的 + +COMPATIBLE_MODE 为4 (0:none, 1:SQL92, 2:Oracle, 3:MS SQL Server, 4:MySQL, 5:DM6, 6:Teradata) +ENABLE_BLOB_CMP_FLAG = 1 (允许对TEXT, BLOB等长字段进行比较和排序) + +启停服务 + +systemctl enable DmServiceDMSERVER +systemctl start DmServiceDMSERVER +systemctl stop DmServiceDMSERVER + +卸载: + +/opt/dmdbms/script/root/dm_service_uninstaller.sh -n DmServiceDMSERVER + +访问数据库: + +./disql +用户名:sysdba 密码:SYSDBA + + +创建用户 + +create user "yunioncloud" identified by "passw0rd"; +grant resource,public to yunioncloud; + +创建用户的同时会自动创建一个同名的 schema (模式),达梦的模式类似其他数据库的database + + +数据迁移: + +找一台Windows主机,下载达梦windows版本,仅安装客户端,则会包含达梦的数据库迁移工具DTS,使用DTS将mysql的数据迁移到达梦。 + +## 达梦与MySQL的兼容问题: + +1. LENGTH('')返回的是NULL +2. 查询的一行数据长度超过page的一半会报错,因此把page设置为最大32k,如果还是出现,则可以设置表属性为允许超过page的一半大小: +```sql +alter table table_name enable using long row; +``` diff --git a/vendor/yunion.io/x/sqlchemy/backends/dameng/column.go b/vendor/yunion.io/x/sqlchemy/backends/dameng/column.go new file mode 100644 index 0000000000..8e6f9cef65 --- /dev/null +++ b/vendor/yunion.io/x/sqlchemy/backends/dameng/column.go @@ -0,0 +1,612 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dameng + +import ( + "bytes" + "database/sql" + "fmt" + "reflect" + "strconv" + "strings" + "time" + + "yunion.io/x/log" + "yunion.io/x/pkg/gotypes" + "yunion.io/x/pkg/tristate" + "yunion.io/x/pkg/util/timeutils" + "yunion.io/x/pkg/utils" + + "yunion.io/x/sqlchemy" +) + +func columnDefinitionBuffer(c sqlchemy.IColumnSpec) bytes.Buffer { + var buf bytes.Buffer + buf.WriteByte('"') + buf.WriteString(c.Name()) + buf.WriteByte('"') + buf.WriteByte(' ') + buf.WriteString(c.ColType()) + + extra := c.ExtraDefs() + if len(extra) > 0 { + buf.WriteString(" ") + buf.WriteString(extra) + } + + def := c.Default() + if hasDefault(c) { + // if c is NOT NULL, default value must be set + if !c.IsSupportDefault() { + panic(fmt.Errorf("column %q type %q does not support having default value: %q", + c.Name(), c.ColType(), def, + )) + } + def = sqlchemy.GetStringValue(c.ConvertFromString(def)) + buf.WriteString(" DEFAULT ") + if c.IsText() { + buf.WriteByte('\'') + } + buf.WriteString(def) + if c.IsText() { + buf.WriteByte('\'') + } + } + + if !c.IsNullable() { + buf.WriteString(" NOT NULL") + } + + return buf +} + +func hasDefault(c sqlchemy.IColumnSpec) bool { + return (c.Default() != "" || !c.IsNullable()) && !c.IsAutoIncrement() +} + +// SBooleanColumn represents a boolean type column, which is a int(1) for mysql, with value of true or false +type SBooleanColumn struct { + sqlchemy.SBaseWidthColumn +} + +// DefinitionString implementation of SBooleanColumn for IColumnSpec +func (c *SBooleanColumn) DefinitionString() string { + buf := columnDefinitionBuffer(c) + return buf.String() +} + +// ConvertFromString implementation of SBooleanColumn for IColumnSpec +func (c *SBooleanColumn) ConvertFromString(str string) interface{} { + switch strings.ToLower(str) { + case "true", "yes", "on", "ok", "1": + return 1 + default: + return 0 + } +} + +// ConvertFromValue implementation of STristateColumn for IColumnSpec +func (c *SBooleanColumn) ConvertFromValue(val interface{}) interface{} { + var bVal bool + if c.IsPointer() { + bVal = *val.(*bool) + } else { + bVal = val.(bool) + } + if bVal { + return 1 + } + return 0 +} + +// IsZero implementation of SBooleanColumn for IColumnSpec +func (c *SBooleanColumn) IsZero(val interface{}) bool { + if c.IsPointer() { + bVal := val.(*bool) + return bVal == nil + } + bVal := val.(bool) + return bVal == false +} + +// NewBooleanColumn return an instance of SBooleanColumn +func NewBooleanColumn(name string, tagmap map[string]string, isPointer bool) SBooleanColumn { + bc := SBooleanColumn{SBaseWidthColumn: sqlchemy.NewBaseWidthColumn(name, "TINYINT", tagmap, isPointer)} + if !bc.IsPointer() && len(bc.Default()) > 0 && bc.ConvertFromString(bc.Default()) == 1 { + msg := fmt.Sprintf("Non-pointer boolean column should not default true: %s(%s)", name, tagmap) + panic(msg) + } + return bc +} + +// STristateColumn represents a tristate type column, with value of true, false or none +type STristateColumn struct { + sqlchemy.SBaseWidthColumn +} + +// DefinitionString implementation of STristateColumn for IColumnSpec +func (c *STristateColumn) DefinitionString() string { + buf := columnDefinitionBuffer(c) + return buf.String() +} + +// ConvertFromString implementation of STristateColumn for IColumnSpec +func (c *STristateColumn) ConvertFromString(str string) interface{} { + switch strings.ToLower(str) { + case "true", "yes", "on", "ok", "1": + return 1 + case "none", "null", "unknown": + return sql.NullInt32{} + default: + return 0 + } +} + +// ConvertFromValue implementation of STristateColumn for IColumnSpec +func (c *STristateColumn) ConvertFromValue(val interface{}) interface{} { + bVal := val.(tristate.TriState) + if bVal == tristate.True { + return 1 + } else if bVal == tristate.False { + return 0 + } else { + return sql.NullInt32{} + } +} + +// IsZero implementation of STristateColumn for IColumnSpec +func (c *STristateColumn) IsZero(val interface{}) bool { + if c.IsPointer() { + bVal := val.(*tristate.TriState) + return bVal == nil + } + bVal := val.(tristate.TriState) + return bVal == tristate.None +} + +// NewTristateColumn return an instance of STristateColumn +func NewTristateColumn(table, name string, tagmap map[string]string, isPointer bool) STristateColumn { + if _, ok := tagmap[sqlchemy.TAG_NULLABLE]; ok { + // simply warning, for backward compatiblity reason + // tristate always nullable + // delete(tagmap, sqlchemy.TAG_NULLABLE) + log.Warningf("%s TristateColumn %s should have no nullable tag", table, name) + } + bc := STristateColumn{SBaseWidthColumn: sqlchemy.NewBaseWidthColumn(name, "TINYINT", tagmap, isPointer)} + return bc +} + +// SIntegerColumn represents an integer type of column, with value of integer +type SIntegerColumn struct { + sqlchemy.SBaseColumn + + // Is this column an autoincrement colmn + isAutoIncrement bool + + // Is this column is a version column for this records + isAutoVersion bool + + // Is this column a unsigned integer? + // isUnsigned bool + + // If this column is an autoincrement column, AutoIncrementOffset records the initial offset + autoIncrementOffset int64 +} + +// IsNumeric implementation of SIntegerColumn for IColumnSpec +func (c *SIntegerColumn) IsNumeric() bool { + return true +} + +// ExtraDefs implementation of SIntegerColumn for IColumnSpec +func (c *SIntegerColumn) ExtraDefs() string { + if c.isAutoIncrement { + return fmt.Sprintf("IDENTITY(%d, %d)", c.autoIncrementOffset, 1) + } + return "" +} + +// DefinitionString implementation of SIntegerColumn for IColumnSpec +func (c *SIntegerColumn) DefinitionString() string { + buf := columnDefinitionBuffer(c) + return buf.String() +} + +// IsZero implementation of SIntegerColumn for IColumnSpec +func (c *SIntegerColumn) IsZero(val interface{}) bool { + if val == nil || (c.IsPointer() && reflect.ValueOf(val).IsNil()) { + return true + } + switch intVal := val.(type) { + case int8, int16, int32, int64, int, uint, uint8, uint16, uint32, uint64: + return intVal == 0 + } + return true +} + +// ConvertFromString implementation of SBooleanColumn for IColumnSpec +func (c *SIntegerColumn) ConvertFromString(str string) interface{} { + val, _ := strconv.ParseInt(str, 10, 64) + return val +} + +func (c *SIntegerColumn) IsAutoVersion() bool { + return c.isAutoVersion +} + +func (c *SIntegerColumn) IsAutoIncrement() bool { + return c.isAutoIncrement +} + +func (c *SIntegerColumn) AutoIncrementOffset() int64 { + return c.autoIncrementOffset +} + +func (c *SIntegerColumn) SetAutoIncrement(on bool) { + c.isAutoIncrement = on +} + +func (c *SIntegerColumn) SetAutoIncrementOffset(offset int64) { + c.autoIncrementOffset = offset +} + +// NewIntegerColumn return an instance of SIntegerColumn +func NewIntegerColumn(name string, sqltype string, tagmap map[string]string, isPointer bool) SIntegerColumn { + autoinc := false + autoincBase := int64(1) + tagmap, v, ok := utils.TagPop(tagmap, sqlchemy.TAG_AUTOINCREMENT) + if ok { + base, err := strconv.ParseInt(v, 10, 64) + if err == nil && base > 0 { + autoinc = true + autoincBase = base + } else { + autoinc = utils.ToBool(v) + } + } + autover := false + tagmap, v, ok = utils.TagPop(tagmap, sqlchemy.TAG_AUTOVERSION) + if ok { + autover = utils.ToBool(v) + } + c := SIntegerColumn{ + SBaseColumn: sqlchemy.NewBaseColumn(name, sqltype, tagmap, isPointer), + isAutoIncrement: autoinc, + autoIncrementOffset: autoincBase, + isAutoVersion: autover, + } + if autoinc { + c.SetPrimary(true) // autoincrement column must be primary key + c.SetNullable(false) + c.isAutoVersion = false + } else if autover { + c.SetPrimary(false) + c.SetNullable(false) + if len(c.Default()) == 0 { + c.SetDefault("0") + } + } + return c +} + +// SFloatColumn represents a float type column, e.g. float32 or float64 +type SFloatColumn struct { + sqlchemy.SBaseColumn +} + +// IsNumeric implementation of SFloatColumn for IColumnSpec +func (c *SFloatColumn) IsNumeric() bool { + return true +} + +// DefinitionString implementation of SFloatColumn for IColumnSpec +func (c *SFloatColumn) DefinitionString() string { + buf := columnDefinitionBuffer(c) + return buf.String() +} + +// IsZero implementation of SFloatColumn for IColumnSpec +func (c *SFloatColumn) IsZero(val interface{}) bool { + if c.IsPointer() { + switch val.(type) { + case *float32: + return val.(*float32) == nil + case *float64: + return val.(*float64) == nil + } + } else { + switch val.(type) { + case float32: + return val.(float32) == 0.0 + case float64: + return val.(float64) == 0.0 + } + } + return true +} + +// ConvertFromString implementation of SBooleanColumn for IColumnSpec +func (c *SFloatColumn) ConvertFromString(str string) interface{} { + val, _ := strconv.ParseFloat(str, 64) + return val +} + +// NewFloatColumn returns an instance of SFloatColumn +func NewFloatColumn(name string, sqlType string, tagmap map[string]string, isPointer bool) SFloatColumn { + return SFloatColumn{SBaseColumn: sqlchemy.NewBaseColumn(name, sqlType, tagmap, isPointer)} +} + +// SDecimalColumn represents a DECIMAL type of column, i.e. a float with fixed width of digits +type SDecimalColumn struct { + sqlchemy.SBaseWidthColumn + Precision int +} + +// ColType implementation of SDecimalColumn for IColumnSpec +func (c *SDecimalColumn) ColType() string { + str := c.SBaseWidthColumn.ColType() + if str[len(str)-1] == ')' { + str = str[:len(str)-1] + } + return fmt.Sprintf("%s, %d)", str, c.Precision) +} + +// IsNumeric implementation of SDecimalColumn for IColumnSpec +func (c *SDecimalColumn) IsNumeric() bool { + return true +} + +// DefinitionString implementation of SDecimalColumn for IColumnSpec +func (c *SDecimalColumn) DefinitionString() string { + buf := columnDefinitionBuffer(c) + return buf.String() +} + +// IsZero implementation of SDecimalColumn for IColumnSpec +func (c *SDecimalColumn) IsZero(val interface{}) bool { + if c.IsPointer() { + switch val.(type) { + case *float32: + return val.(*float32) == nil + case *float64: + return val.(*float64) == nil + } + } else { + switch val.(type) { + case float32: + return val.(float32) == 0.0 + case float64: + return val.(float64) == 0.0 + } + } + return true +} + +// ConvertFromString implementation of SBooleanColumn for IColumnSpec +func (c *SDecimalColumn) ConvertFromString(str string) interface{} { + val, _ := strconv.ParseFloat(str, 64) + return val +} + +// NewDecimalColumn returns an instance of SDecimalColumn +func NewDecimalColumn(name string, tagmap map[string]string, isPointer bool) SDecimalColumn { + tagmap, v, ok := utils.TagPop(tagmap, sqlchemy.TAG_PRECISION) + if !ok { + panic(fmt.Sprintf("Field %q of float misses precision tag", name)) + } + prec, err := strconv.Atoi(v) + if err != nil { + panic(fmt.Sprintf("Field precision of %q shoud be integer (%q)", name, v)) + } + return SDecimalColumn{ + SBaseWidthColumn: sqlchemy.NewBaseWidthColumn(name, "DECIMAL", tagmap, isPointer), + Precision: prec, + } +} + +// STextColumn represents a text type of column +type STextColumn struct { + sqlchemy.SBaseWidthColumn +} + +// IsSupportDefault implementation of STextColumn for IColumnSpec +func (c *STextColumn) IsSupportDefault() bool { + return true // c.SBaseColumn.ColType() == "VARCHAR" +} + +// IsText implementation of STextColumn for IColumnSpec +func (c *STextColumn) IsText() bool { + return true +} + +// IsSearchable implementation of STextColumn for IColumnSpec +func (c *STextColumn) IsSearchable() bool { + return true +} + +// IsAscii implementation of STextColumn for IColumnSpec +func (c *STextColumn) IsAscii() bool { + return false +} + +// DefinitionString implementation of STextColumn for IColumnSpec +func (c *STextColumn) DefinitionString() string { + buf := columnDefinitionBuffer(c) + return buf.String() +} + +// IsZero implementation of STextColumn for IColumnSpec +func (c *STextColumn) IsZero(val interface{}) bool { + if c.IsPointer() { + return gotypes.IsNil(val) + } + return reflect.ValueOf(val).Len() == 0 +} + +// ConvertFromString implementation of SBooleanColumn for IColumnSpec +func (c *STextColumn) ConvertFromString(str string) interface{} { + return str +} + +func (c *STextColumn) IsString() bool { + return true +} + +// NewTextColumn return an instance of STextColumn +func NewTextColumn(name string, sqlType string, tagmap map[string]string, isPointer bool) STextColumn { + return STextColumn{ + SBaseWidthColumn: sqlchemy.NewBaseWidthColumn(name, sqlType, tagmap, isPointer), + } +} + +// STimeTypeColumn represents a Detetime type of column, e.g. DateTime +type STimeTypeColumn struct { + sqlchemy.SBaseColumn + + // timestamp precision of nanoseconds, 0-6 + precision int +} + +// IsText implementation of STimeTypeColumn for IColumnSpec +func (c *STimeTypeColumn) IsText() bool { + return true +} + +// DefinitionString implementation of STimeTypeColumn for IColumnSpec +func (c *STimeTypeColumn) DefinitionString() string { + buf := columnDefinitionBuffer(c) + return buf.String() +} + +// IsZero implementation of STimeTypeColumn for IColumnSpec +func (c *STimeTypeColumn) IsZero(val interface{}) bool { + if c.IsPointer() { + bVal := val.(*time.Time) + return bVal == nil + } + bVal := val.(time.Time) + return bVal.IsZero() +} + +// ColType implementation of SIntegerColumn for IColumnSpec +func (c *STimeTypeColumn) ColType() string { + return fmt.Sprintf("%s(%d)", (&c.SBaseColumn).ColType(), c.precision) +} + +// ConvertFromString implementation of SBooleanColumn for IColumnSpec +func (c *STimeTypeColumn) ConvertFromString(str string) interface{} { + tm, _ := timeutils.ParseTimeStr(str) + return tm +} + +// NewTimeTypeColumn return an instance of STimeTypeColumn +func NewTimeTypeColumn(name string, typeStr string, tagmap map[string]string, isPointer bool) STimeTypeColumn { + tagmap, v, ok := utils.TagPop(tagmap, sqlchemy.TAG_PRECISION) + prec := 6 + if ok { + prec, _ = strconv.Atoi(v) + if prec > 6 || prec <= 0 { + log.Warningf("datetime field %s precision %d change to 6", name, prec) + prec = 6 + } + } + dc := STimeTypeColumn{ + SBaseColumn: sqlchemy.NewBaseColumn(name, typeStr, tagmap, isPointer), + precision: prec, + } + return dc +} + +// SDateTimeColumn represents a DateTime type of column +type SDateTimeColumn struct { + STimeTypeColumn + + // Is this column a 'created_at' field, whichi records the time of create this record + isCreatedAt bool + + // Is this column a 'updated_at' field, whichi records the time when this record was updated + isUpdatedAt bool +} + +func (c *SDateTimeColumn) IsCreatedAt() bool { + return c.isCreatedAt +} + +func (c *SDateTimeColumn) IsUpdatedAt() bool { + return c.isUpdatedAt +} + +func (c *SDateTimeColumn) IsDateTime() bool { + return true +} + +// NewDateTimeColumn returns an instance of DateTime column +func NewDateTimeColumn(name string, tagmap map[string]string, isPointer bool) SDateTimeColumn { + createdAt := false + updatedAt := false + tagmap, v, ok := utils.TagPop(tagmap, sqlchemy.TAG_CREATE_TIMESTAMP) + if ok { + createdAt = utils.ToBool(v) + } + tagmap, v, ok = utils.TagPop(tagmap, sqlchemy.TAG_UPDATE_TIMESTAMP) + if ok { + updatedAt = utils.ToBool(v) + } + dtc := SDateTimeColumn{ + STimeTypeColumn: NewTimeTypeColumn(name, "TIMESTAMP", tagmap, isPointer), + isCreatedAt: createdAt, + isUpdatedAt: updatedAt, + } + return dtc +} + +// CompoundColumn represents a column of compound tye, e.g. a JSON, an Array, or a struct +type CompoundColumn struct { + STextColumn + sqlchemy.SBaseCompoundColumn +} + +// DefinitionString implementation of CompoundColumn for IColumnSpec +func (c *CompoundColumn) DefinitionString() string { + buf := columnDefinitionBuffer(c) + return buf.String() +} + +// IsZero implementation of CompoundColumn for IColumnSpec +func (c *CompoundColumn) IsZero(val interface{}) bool { + if val == nil { + return true + } + if c.IsPointer() && reflect.ValueOf(val).IsNil() { + return true + } + return false +} + +// ConvertFromString implementation of CompoundColumn for IColumnSpec +func (c *CompoundColumn) ConvertFromString(str string) interface{} { + return c.SBaseCompoundColumn.ConvertFromString(str) +} + +// ConvertFromValue implementation of CompoundColumn for IColumnSpec +func (c *CompoundColumn) ConvertFromValue(val interface{}) interface{} { + return c.SBaseCompoundColumn.ConvertFromValue(val) +} + +// NewCompoundColumn returns an instance of CompoundColumn +func NewCompoundColumn(name string, sqlType string, tagmap map[string]string, isPointer bool) CompoundColumn { + dtc := CompoundColumn{STextColumn: NewTextColumn(name, sqlType, tagmap, isPointer)} + return dtc +} diff --git a/vendor/yunion.io/x/sqlchemy/backends/dameng/columninfo.go b/vendor/yunion.io/x/sqlchemy/backends/dameng/columninfo.go new file mode 100644 index 0000000000..82ee1b0ee6 --- /dev/null +++ b/vendor/yunion.io/x/sqlchemy/backends/dameng/columninfo.go @@ -0,0 +1,255 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dameng + +import ( + "bytes" + "database/sql" + "encoding/binary" + "fmt" + "strings" + + "yunion.io/x/log" + "yunion.io/x/pkg/errors" + + "yunion.io/x/sqlchemy" +) + +// COLUMN_NAME, DATA_TYPE, NULLABLE, DATA_LENGTH, CHARACTER_SET_NAME, DATA_DEFAULT +type sSqlColumnInfo struct { + TableName string `json:"TABLE_NAME"` + ColumnName string `json:"COLUMN_NAME"` + DataType string `json:"DATA_TYPE"` + Nullable string `json:"NULLABLE"` + DataLength int `json:"DATA_LENGTH"` + DataPrecision int `json:"DATA_PRECISION"` + DataScale int `json:"DATA_SCALE"` + CharacterSetName string `json:"CHARACTER_SET_NAME"` + DataDefault string `json:"DATA_DEFAULT"` + IsPrimary bool `json:"is_primary"` + + IsAutoIncrement bool `json:"is_auto_increment"` + AutoIncrementOffset uint64 `json:"auto_increment_offset"` + AutoIncrementStep uint64 `json:"auto_increment_step"` +} + +func fetchTableColInfo(ts sqlchemy.ITableSpec) (map[string]*sSqlColumnInfo, error) { + sqlStr := fmt.Sprintf("SELECT COLUMN_NAME, DATA_TYPE, NULLABLE, DATA_LENGTH, DATA_PRECISION, DATA_SCALE, CHARACTER_SET_NAME, DATA_DEFAULT FROM USER_TAB_COLUMNS WHERE Table_Name='%s'", ts.Name()) + query := ts.Database().NewRawQuery(sqlStr, "column_name", "data_type", "nullable", "data_length", "data_precision", "data_scale", "character_set_name", "data_default") + infos := make([]sSqlColumnInfo, 0) + err := query.All(&infos) + if err != nil { + return nil, errors.Wrap(err, "query") + } + ret := make(map[string]*sSqlColumnInfo) + for i := range infos { + infos[i].TableName = ts.Name() + infos[i].ColumnName = strings.ToLower(infos[i].ColumnName) + ret[infos[i].ColumnName] = &infos[i] + } + + indexes, err := fetchTableIndexes(ts) + if err != nil { + return nil, errors.Wrap(err, "fetchTableIndexes") + } + + for _, idx := range indexes { + if idx.isPrimary { + for _, col := range idx.colnames { + ret[col].IsPrimary = true + } + break + } + } + + autoIncInfo, err := fetchTableAutoIncrementCol(ts) + if err != nil { + return nil, errors.Wrap(err, "fetchTableAutoIncrementCol") + } else if autoIncInfo != nil { + ret[autoIncInfo.Name].IsAutoIncrement = true + ret[autoIncInfo.Name].AutoIncrementOffset = autoIncInfo.Offset + ret[autoIncInfo.Name].AutoIncrementStep = autoIncInfo.Step + } + + return ret, nil +} + +type sDamengTableIndex struct { + isPrimary bool + indexName string + colnames []string +} + +func fetchTableIndexes(ts sqlchemy.ITableSpec) (map[string]sDamengTableIndex, error) { + type sIndexInfo struct { + ColumnName string `json:"COLUMN_NAME"` + IndexName string `json:"INDEX_NAME"` + ConstraintType string `json:"CONSTRAINT_TYPE"` + } + sqlStr := fmt.Sprintf("SELECT a.COLUMN_NAME, a.INDEX_NAME, b.CONSTRAINT_TYPE FROM USER_IND_COLUMNS a LEFT JOIN USER_CONSTRAINTS b ON a.INDEX_NAME=b.INDEX_NAME WHERE a.TABLE_NAME='%s'", ts.Name()) + query := ts.Database().NewRawQuery(sqlStr, "column_name", "index_name", "constraint_type") + infos := make([]sIndexInfo, 0) + err := query.All(&infos) + if err != nil { + return nil, err + } + ret := make(map[string]sDamengTableIndex) + for _, info := range infos { + info.IndexName = strings.ToLower(info.IndexName) + info.ColumnName = strings.ToLower(info.ColumnName) + if idx, ok := ret[info.IndexName]; ok { + idx.colnames = append(idx.colnames, info.ColumnName) + ret[info.IndexName] = idx + } else { + ret[info.IndexName] = sDamengTableIndex{ + isPrimary: info.ConstraintType == "P", + indexName: info.IndexName, + colnames: []string{info.ColumnName}, + } + } + } + return ret, nil +} + +func fetchTableAutoIncrementCol(ts sqlchemy.ITableSpec) (*sDamengAutoIncrementInfo, error) { + sqlStr := fmt.Sprintf("SELECT a.NAME, c.INFO6 from SYSCOLUMNS a, SYSOBJECTS c WHERE a.INFO2 & 0x01 = 0x01 AND a.ID=c.ID and c.NAME='%s' AND c.SCHID=CURRENT_SCHID", ts.Name()) + query := ts.Database().NewRawQuery(sqlStr, "name", "info6") + row := query.Row() + name := "" + info6 := make([]byte, 0) + err := row.Scan(&name, &info6) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, nil + } else { + return nil, errors.Wrap(err, "Query") + } + } + return decodeInfo6(name, info6) +} + +type sDamengAutoIncrementInfo struct { + Name string + Offset uint64 + Step uint64 + Dummy uint64 +} + +func decodeInfo6(name string, binHex []byte) (*sDamengAutoIncrementInfo, error) { + buf := bytes.NewReader(binHex) + var pi [3]uint64 + for i := range pi { + err := binary.Read(buf, binary.LittleEndian, &pi[i]) + if err != nil { + return nil, errors.Wrap(err, "binary.LittleEndian.Read") + } + } + return &sDamengAutoIncrementInfo{ + Name: strings.ToLower(name), + Offset: pi[0], + Step: pi[1], + Dummy: pi[2], + }, nil +} + +func (info *sSqlColumnInfo) toColumnSpec() sqlchemy.IColumnSpec { + tagmap := make(map[string]string) + + typeStr := strings.ToUpper(info.DataType) + if info.Nullable == "Y" { + tagmap[sqlchemy.TAG_NULLABLE] = "true" + } else { + tagmap[sqlchemy.TAG_NULLABLE] = "false" + } + if info.IsPrimary { + tagmap[sqlchemy.TAG_PRIMARY] = "true" + } else { + tagmap[sqlchemy.TAG_PRIMARY] = "false" + } + if info.DataDefault != "NULL" && len(info.DataDefault) > 0 { + tagmap[sqlchemy.TAG_DEFAULT] = info.DataDefault + } + if typeStr == "VARCHAR" || typeStr == "CHAR" || typeStr == "CHARACTER" { + tagmap[sqlchemy.TAG_WIDTH] = fmt.Sprintf("%d", info.DataLength) + if val, ok := tagmap[sqlchemy.TAG_DEFAULT]; ok { + tagmap[sqlchemy.TAG_DEFAULT] = strings.Trim(val, "'\"") + } + c := NewTextColumn(info.ColumnName, typeStr, tagmap, false) + return &c + } else if typeStr == "TEXT" || typeStr == "LONGVARCHAR" || typeStr == "CLOB" || typeStr == "BLOB" { + if val, ok := tagmap[sqlchemy.TAG_DEFAULT]; ok { + tagmap[sqlchemy.TAG_DEFAULT] = strings.Trim(val, "'\"") + } + c := NewTextColumn(info.ColumnName, typeStr, tagmap, false) + return &c + } else if strings.HasSuffix(typeStr, "INT") { + if val, ok := tagmap[sqlchemy.TAG_DEFAULT]; ok { + tagmap[sqlchemy.TAG_DEFAULT] = strings.Trim(val, "()") + } + if typeStr == "TINYINT" { + if info.Nullable == "Y" { + c := NewTristateColumn(info.TableName, info.ColumnName, tagmap, false) + return &c + } else { + if info.DataDefault == "1" { + c := NewBooleanColumn(info.ColumnName, tagmap, true) + return &c + } else { + c := NewBooleanColumn(info.ColumnName, tagmap, false) + return &c + } + } + } else { + if info.IsAutoIncrement { + if info.AutoIncrementOffset > 0 { + tagmap[sqlchemy.TAG_AUTOINCREMENT] = fmt.Sprintf("%d", info.AutoIncrementOffset) + } else { + tagmap[sqlchemy.TAG_AUTOINCREMENT] = "true" + } + } + c := NewIntegerColumn(info.ColumnName, typeStr, tagmap, false) + return &c + } + } else if typeStr == "REAL" || typeStr == "FLOAT" || typeStr == "DOUBLE" || typeStr == "DOUBLE PRECISION" { + if val, ok := tagmap[sqlchemy.TAG_DEFAULT]; ok { + tagmap[sqlchemy.TAG_DEFAULT] = strings.Trim(val, "()") + } + c := NewFloatColumn(info.ColumnName, typeStr, tagmap, false) + return &c + } else if typeStr == "NUMERIC" || typeStr == "NUMBER" || typeStr == "DECIMAL" || typeStr == "DEC" { + if val, ok := tagmap[sqlchemy.TAG_DEFAULT]; ok { + tagmap[sqlchemy.TAG_DEFAULT] = strings.Trim(val, "()") + } + tagmap[sqlchemy.TAG_WIDTH] = fmt.Sprintf("%d", info.DataPrecision) + tagmap[sqlchemy.TAG_PRECISION] = fmt.Sprintf("%d", info.DataScale) + c := NewDecimalColumn(info.ColumnName, tagmap, false) + return &c + } else if typeStr == "TIMESTAMP" || typeStr == "DATATIME" { + if val, ok := tagmap[sqlchemy.TAG_DEFAULT]; ok { + tagmap[sqlchemy.TAG_DEFAULT] = strings.Trim(val, "'\"") + } + c := NewDateTimeColumn(info.ColumnName, tagmap, false) + return &c + } else if typeStr == "TIME" || typeStr == "DATE" { + if val, ok := tagmap[sqlchemy.TAG_DEFAULT]; ok { + tagmap[sqlchemy.TAG_DEFAULT] = strings.Trim(val, "'\"") + } + c := NewTimeTypeColumn(info.ColumnName, typeStr, tagmap, false) + return &c + } else { + log.Errorf("unsupported column data type %s", typeStr) + return nil + } +} diff --git a/vendor/yunion.io/x/sqlchemy/backends/dameng/dameng.go b/vendor/yunion.io/x/sqlchemy/backends/dameng/dameng.go new file mode 100644 index 0000000000..8fd08a9918 --- /dev/null +++ b/vendor/yunion.io/x/sqlchemy/backends/dameng/dameng.go @@ -0,0 +1,273 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dameng + +import ( + "fmt" + "reflect" + "strconv" + "strings" + + _ "gitee.com/chunanyong/dm" + + "yunion.io/x/pkg/errors" + "yunion.io/x/pkg/gotypes" + "yunion.io/x/pkg/tristate" + "yunion.io/x/pkg/util/regutils" + "yunion.io/x/pkg/utils" + + "yunion.io/x/sqlchemy" +) + +func init() { + sqlchemy.RegisterBackend(&SDamengBackend{}) +} + +type SDamengBackend struct { + sqlchemy.SBaseBackend +} + +func (dameng *SDamengBackend) Name() sqlchemy.DBBackendName { + return sqlchemy.DamengBackend +} + +// CanUpdate returns wether the backend supports update +func (dameng *SDamengBackend) CanUpdate() bool { + return true +} + +// CanInsert returns wether the backend supports Insert +func (dameng *SDamengBackend) CanInsert() bool { + return true +} + +func (dameng *SDamengBackend) CanSupportRowAffected() bool { + return true +} + +// CanInsertOrUpdate returns weather the backend supports InsertOrUpdate +func (dameng *SDamengBackend) CanInsertOrUpdate() bool { + return true +} + +func (dameng *SDamengBackend) InsertOrUpdateSQLTemplate() string { + // use PrepareInsertOrUpdateSQL instead + return "" +} + +func (dameng *SDamengBackend) DropIndexSQLTemplate() string { + return `DROP INDEX "{{ .Index }}"" ON "{{ .Table }}"` +} + +func (dameng *SDamengBackend) InsertSQLTemplate() string { + return `INSERT INTO "{{ .Table }}" ({{ .Columns }}) VALUES ({{ .Values }})` +} + +func (dameng *SDamengBackend) UpdateSQLTemplate() string { + return `UPDATE "{{ .Table }}" SET {{ .Columns }} WHERE {{ .Conditions }}` +} + +func (dameng *SDamengBackend) PrepareInsertOrUpdateSQL(ts sqlchemy.ITableSpec, insertColNames []string, insertFields []string, onPrimaryCols []string, updateSetCols []string, insertValues []interface{}, updateValues []interface{}) (string, []interface{}) { + sqlTemp := `MERGE INTO "{{ .Table }}" T1 USING (SELECT {{ .SelectValues }} FROM DUAL) T2 ON ({{ .OnConditions }}) WHEN NOT MATCHED THEN INSERT({{ .Columns }}) VALUES ({{ .Values }}) WHEN MATCHED THEN UPDATE SET {{ .SetValues }}` + selectValues := make([]string, 0, len(insertColNames)) + onConditions := make([]string, 0, len(onPrimaryCols)) + + for i := range insertColNames { + colName := strings.Trim(insertColNames[i], "'\"") + selectValues = append(selectValues, fmt.Sprintf("%s AS \"%s\"", insertFields[i], colName)) + } + for _, primary := range onPrimaryCols { + onConditions = append(onConditions, fmt.Sprintf("T1.%s=T2.%s", primary, primary)) + } + for i := range updateSetCols { + setCol := updateSetCols[i] + equalPos := strings.Index(setCol, "=") + key := strings.TrimSpace(setCol[0:equalPos]) + val := strings.TrimSpace(setCol[equalPos+1:]) + tkey := fmt.Sprintf("\"T1\".%s", key) + val = strings.ReplaceAll(val, key, tkey) + updateSetCols[i] = fmt.Sprintf("%s = %s", tkey, val) + } + values := make([]interface{}, 0, len(insertValues)*2+len(updateValues)) + values = append(values, insertValues...) + values = append(values, insertValues...) + values = append(values, updateValues...) + sql := sqlchemy.TemplateEval(sqlTemp, struct { + Table string + SelectValues string + OnConditions string + Columns string + Values string + SetValues string + }{ + Table: ts.Name(), + SelectValues: strings.Join(selectValues, ", "), + OnConditions: strings.Join(onConditions, " AND "), + Columns: strings.Join(insertColNames, ", "), + Values: strings.Join(insertFields, ", "), + SetValues: strings.Join(updateSetCols, ", "), + }) + return sql, values +} + +func (dameng *SDamengBackend) GetTableSQL() string { + return `SELECT table_name AS "name" FROM user_tables` +} + +func (dameng *SDamengBackend) CurrentUTCTimeStampString() string { + return "GETUTCDATE()" +} + +func (dameng *SDamengBackend) CurrentTimeStampString() string { + return "GETDATE()" +} + +func (dameng *SDamengBackend) GetCreateSQLs(ts sqlchemy.ITableSpec) []string { + cols := make([]string, 0) + primaries := make([]string, 0) + for _, c := range ts.Columns() { + cols = append(cols, c.DefinitionString()) + if c.IsPrimary() { + primaries = append(primaries, fmt.Sprintf(`"%s"`, c.Name())) + } + } + if len(primaries) > 0 { + cols = append(cols, fmt.Sprintf("NOT CLUSTER PRIMARY KEY (%s)", strings.Join(primaries, ", "))) + } + sqls := []string{ + fmt.Sprintf(`CREATE TABLE IF NOT EXISTS "%s" (%s);`, ts.Name(), strings.Join(cols, ", ")), + } + for _, idx := range ts.Indexes() { + sqls = append(sqls, createIndexSQL(ts, idx)) + } + return sqls +} + +func (msyql *SDamengBackend) IsSupportIndexAndContraints() bool { + return true +} + +func (dameng *SDamengBackend) FetchTableColumnSpecs(ts sqlchemy.ITableSpec) ([]sqlchemy.IColumnSpec, error) { + infos, err := fetchTableColInfo(ts) + if err != nil { + return nil, errors.Wrap(err, "fetchTableColInfo") + } + specs := make([]sqlchemy.IColumnSpec, 0) + for _, info := range infos { + specs = append(specs, info.toColumnSpec()) + } + return specs, nil +} + +func (dameng *SDamengBackend) FetchIndexesAndConstraints(ts sqlchemy.ITableSpec) ([]sqlchemy.STableIndex, []sqlchemy.STableConstraint, error) { + indexes, err := fetchTableIndexes(ts) + if err != nil { + return nil, nil, errors.Wrap(err, "fetchTableIndexes") + } + retIdxes := make([]sqlchemy.STableIndex, 0) + for k := range indexes { + if indexes[k].isPrimary { + continue + } + retIdxes = append(retIdxes, sqlchemy.NewTableIndex(ts, indexes[k].indexName, indexes[k].colnames, false)) + } + return retIdxes, nil, nil +} + +func getTextSqlType(tagmap map[string]string) (string, map[string]string) { + var width int + var sqltype string + tagmap, widthStr, _ := utils.TagPop(tagmap, sqlchemy.TAG_WIDTH) + // widthStr := tagmap[sqlchemy.TAG_WIDTH] + if len(widthStr) > 0 && regutils.MatchInteger(widthStr) { + width, _ = strconv.Atoi(widthStr) + } + if width == 0 || width > 975 { + sqltype = "TEXT" + } else { + tagmap[sqlchemy.TAG_WIDTH] = widthStr + sqltype = "VARCHAR" + } + return sqltype, tagmap +} + +func (dameng *SDamengBackend) GetColumnSpecByFieldType(table *sqlchemy.STableSpec, fieldType reflect.Type, fieldname string, tagmap map[string]string, isPointer bool) sqlchemy.IColumnSpec { + switch fieldType { + case tristate.TriStateType: + col := NewTristateColumn(table.Name(), fieldname, tagmap, isPointer) + return &col + case gotypes.TimeType: + col := NewDateTimeColumn(fieldname, tagmap, isPointer) + return &col + } + switch fieldType.Kind() { + case reflect.String: + sqltype, tagmap := getTextSqlType(tagmap) + col := NewTextColumn(fieldname, sqltype, tagmap, isPointer) + return &col + case reflect.Int, reflect.Int32: + col := NewIntegerColumn(fieldname, "INT", tagmap, isPointer) + return &col + case reflect.Int8: + col := NewIntegerColumn(fieldname, "TINYINT", tagmap, isPointer) + return &col + case reflect.Int16: + col := NewIntegerColumn(fieldname, "SMALLINT", tagmap, isPointer) + return &col + case reflect.Int64: + col := NewIntegerColumn(fieldname, "BIGINT", tagmap, isPointer) + return &col + case reflect.Uint, reflect.Uint32: + col := NewIntegerColumn(fieldname, "INT", tagmap, isPointer) + return &col + case reflect.Uint8: + col := NewIntegerColumn(fieldname, "TINYINT", tagmap, isPointer) + return &col + case reflect.Uint16: + col := NewIntegerColumn(fieldname, "SMALLINT", tagmap, isPointer) + return &col + case reflect.Uint64: + col := NewIntegerColumn(fieldname, "BIGINT", tagmap, isPointer) + return &col + case reflect.Bool: + col := NewBooleanColumn(fieldname, tagmap, isPointer) + return &col + case reflect.Float32, reflect.Float64: + if _, ok := tagmap[sqlchemy.TAG_WIDTH]; ok { + col := NewDecimalColumn(fieldname, tagmap, isPointer) + return &col + } + colType := "REAL" + if fieldType == gotypes.Float64Type { + colType = "DOUBLE" + } + col := NewFloatColumn(fieldname, colType, tagmap, isPointer) + return &col + case reflect.Map, reflect.Slice: + sqltype, tagmap := getTextSqlType(tagmap) + col := NewCompoundColumn(fieldname, sqltype, tagmap, isPointer) + return &col + } + if fieldType.Implements(gotypes.ISerializableType) { + sqltype, tagmap := getTextSqlType(tagmap) + col := NewCompoundColumn(fieldname, sqltype, tagmap, isPointer) + return &col + } + return nil +} + +func (dameng *SDamengBackend) QuoteChar() string { + return "\"" +} diff --git a/vendor/yunion.io/x/sqlchemy/backends/dameng/doc.go b/vendor/yunion.io/x/sqlchemy/backends/dameng/doc.go new file mode 100644 index 0000000000..b2f1eba144 --- /dev/null +++ b/vendor/yunion.io/x/sqlchemy/backends/dameng/doc.go @@ -0,0 +1,15 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dameng // import "yunion.io/x/sqlchemy/backends/dameng" diff --git a/vendor/yunion.io/x/sqlchemy/backends/dameng/errors.go b/vendor/yunion.io/x/sqlchemy/backends/dameng/errors.go new file mode 100644 index 0000000000..ac5356e2d3 --- /dev/null +++ b/vendor/yunion.io/x/sqlchemy/backends/dameng/errors.go @@ -0,0 +1,30 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dameng + +import ( + "github.com/go-sql-driver/mysql" +) + +const ( + mysqlErrorTableNotExist = 0x47a +) + +func isMysqlError(err error, code uint16) bool { + if myErr, ok := err.(*mysql.MySQLError); ok { + return myErr.Number == code + } + return false +} diff --git a/vendor/yunion.io/x/sqlchemy/backends/dameng/functions.go b/vendor/yunion.io/x/sqlchemy/backends/dameng/functions.go new file mode 100644 index 0000000000..916b1e866f --- /dev/null +++ b/vendor/yunion.io/x/sqlchemy/backends/dameng/functions.go @@ -0,0 +1,26 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dameng + +import ( + "fmt" + + "yunion.io/x/sqlchemy" +) + +// GROUP_CONCAT2 represents the SQL function GROUP_CONCAT +func (mysql *SDamengBackend) GROUP_CONCAT2(name string, sep string, field sqlchemy.IQueryField) sqlchemy.IQueryField { + return sqlchemy.NewFunctionField(name, true, fmt.Sprintf("REPLACE(WM_CONCAT(%%s), ',', '%s')", sep), field) +} diff --git a/vendor/yunion.io/x/sqlchemy/backends/dameng/sync.go b/vendor/yunion.io/x/sqlchemy/backends/dameng/sync.go new file mode 100644 index 0000000000..38455a294d --- /dev/null +++ b/vendor/yunion.io/x/sqlchemy/backends/dameng/sync.go @@ -0,0 +1,186 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dameng + +import ( + "fmt" + "sort" + "strings" + + "yunion.io/x/log" + "yunion.io/x/pkg/utils" + "yunion.io/x/sqlchemy" +) + +func (mysql *SDamengBackend) CommitTableChangeSQL(ts sqlchemy.ITableSpec, changes sqlchemy.STableChanges) []string { + ret := make([]string, 0) + + for _, idx := range changes.RemoveIndexes { + sql := fmt.Sprintf(`DROP INDEX "%s"`, idx.Name()) + ret = append(ret, sql) + log.Infof("%s;", sql) + } + + alters := make([]string, 0) + + // first check if primary key is modifed + changePrimary := false + for _, col := range changes.RemoveColumns { + if col.IsPrimary() { + changePrimary = true + break + } + } + if !changePrimary { + for _, cols := range changes.UpdatedColumns { + if cols.OldCol.IsPrimary() != cols.NewCol.IsPrimary() { + changePrimary = true + break + } + } + } + if !changePrimary { + for _, col := range changes.AddColumns { + if col.IsPrimary() { + changePrimary = true + break + } + } + } + // in case of a primary key change, we first need to drop primary key. + // BUT if a mysql table has no primary key at all, + // exec drop primary key will cause error + if changePrimary { + oldHasPrimary := false + for _, col := range changes.OldColumns { + if col.IsPrimary() { + oldHasPrimary = true + break + } + } + if oldHasPrimary { + alters = append(alters, fmt.Sprintf(`ALTER TABLE "%s" DROP PRIMARY KEY;`, ts.Name())) + } + } + + /* IGNORE DROP STATEMENT */ + for _, col := range changes.RemoveColumns { + sql := fmt.Sprintf(`ALTER TABLE "%s" DROP COLUMN "%s";`, ts.Name(), col.Name()) + log.Debugf("skip %s", sql) + // alters = append(alters, sql) + // ignore drop statement + // if the column is auto_increment integer column, + // then need to drop auto_increment attribute + if col.IsAutoIncrement() { + // make sure the column is nullable + col.SetNullable(true) + log.Errorf("column %s is IDENTITY, drop IDENTITY attribute", col.Name()) + col.SetAutoIncrement(false) + sql := fmt.Sprintf(`ALTER TABLE "%s" DROP IDENTITY;`, ts.Name()) + alters = append(alters, sql) + sql = fmt.Sprintf(`ALTER TABLE "%s" MODIFY (%s);`, ts.Name(), col.DefinitionString()) + alters = append(alters, sql) + } + // if the column is not nullable but no default + // then need to drop the not-nullable attribute + if !col.IsNullable() && col.Default() == "" { + col.SetNullable(true) + sql := fmt.Sprintf(`ALTER TABLE "%s" MODIFY (%s);`, ts.Name(), col.DefinitionString()) + alters = append(alters, sql) + log.Errorf("column %s is not nullable but no default, drop not nullable attribute", col.Name()) + } + } + for _, cols := range changes.UpdatedColumns { + if cols.OldCol.Name() != cols.NewCol.Name() { + // rename + sql := fmt.Sprintf(`ALTER TABLE "%s" RENAME COLUMN "%s" TO "%s";`, ts.Name(), cols.OldCol.Name(), cols.NewCol.Name()) + alters = append(alters, sql) + } else if (strings.HasPrefix(cols.OldCol.ColType(), "VARCHAR") && cols.NewCol.ColType() == "TEXT") || (strings.HasPrefix(cols.NewCol.ColType(), "VARCHAR") && cols.OldCol.ColType() == "TEXT") { + // change varchar to text + oldTmpName := fmt.Sprintf("%s_%s", cols.OldCol.Name(), utils.GenRequestId(6)) + alters = append(alters, + // rename oldcol + fmt.Sprintf(`ALTER TABLE "%s" RENAME COLUMN "%s" TO "%s";`, ts.Name(), cols.OldCol.Name(), oldTmpName), + // add a new col + fmt.Sprintf(`ALTER TABLE "%s" ADD %s;`, ts.Name(), cols.NewCol.DefinitionString()), + // copy data + fmt.Sprintf(`UPDATE "%s" SET "%s"=TRIM("%s");`, ts.Name(), cols.NewCol.Name(), oldTmpName), + // drop old col + fmt.Sprintf(`ALTER TABLE "%s" DROP COLUMN "%s";`, ts.Name(), oldTmpName), + ) + } else { + if cols.OldCol.IsAutoIncrement() { + sql := fmt.Sprintf(`ALTER TABLE "%s" DROP IDENTITY;`, ts.Name()) + alters = append(alters, sql) + } + if cols.NewCol.IsAutoIncrement() { + sql := fmt.Sprintf(`ALTER TABLE "%s" ADD COLUMN "%s" IDENTITY(%d, 1);`, ts.Name(), cols.NewCol.Name(), cols.NewCol.AutoIncrementOffset()) + alters = append(alters, sql) + } else { + sql := fmt.Sprintf(`ALTER TABLE "%s" MODIFY (%s)`, ts.Name(), cols.NewCol.DefinitionString()) + alters = append(alters, sql) + } + + if hasDefault(cols.NewCol) && cols.OldCol.Default() != cols.NewCol.Default() { + defStr := cols.NewCol.Default() + if cols.NewCol.IsText() { + defStr = "'" + defStr + "'" + } + sql := fmt.Sprintf(`ALTER TABLE "%s" ALTER COLUMN "%s" SET DEFAULT %s`, ts.Name(), cols.NewCol.Name(), defStr) + alters = append(alters, sql) + } else if !hasDefault(cols.NewCol) && hasDefault(cols.OldCol) { + sql := fmt.Sprintf(`ALTER TABLE "%s" ALTER COLUMN "%s" DROP DEFAULT`, ts.Name(), cols.NewCol.Name()) + alters = append(alters, sql) + } + } + } + for _, col := range changes.AddColumns { + sql := fmt.Sprintf(`ALTER TABLE "%s" ADD %s`, ts.Name(), col.DefinitionString()) + alters = append(alters, sql) + } + if changePrimary { + primaries := make([]string, 0) + primariesQuote := make([]string, 0) + for _, c := range ts.Columns() { + if c.IsPrimary() { + primaries = append(primaries, c.Name()) + primariesQuote = append(primariesQuote, fmt.Sprintf(`"%s"`, c.Name())) + } + } + if len(primaries) > 0 { + sort.Strings(primaries) + pkName := fmt.Sprintf("pk_%s_%s", ts.Name(), strings.Join(primaries, "_")) + sql := fmt.Sprintf(`ALTER TABLE "%s" ADD CONSTRAINT %s PRIMARY KEY(%s)`, ts.Name(), pkName, strings.Join(primariesQuote, ", ")) + alters = append(alters, sql) + } + } + + if len(alters) > 0 { + ret = append(ret, alters...) + log.Infof("%s", strings.Join(alters, "\n")) + } + + for _, idx := range changes.AddIndexes { + sql := createIndexSQL(ts, idx) + ret = append(ret, sql) + log.Infof("%s", sql) + } + + return ret +} + +func createIndexSQL(ts sqlchemy.ITableSpec, idx sqlchemy.STableIndex) string { + return fmt.Sprintf(`CREATE INDEX "%s" ON "%s" (%s);`, idx.Name(), ts.Name(), strings.Join(idx.QuotedColumns(`"`), ",")) +} diff --git a/vendor/yunion.io/x/sqlchemy/backends/loader.go b/vendor/yunion.io/x/sqlchemy/backends/loader.go index ccc7b385a2..8d5b8ab497 100644 --- a/vendor/yunion.io/x/sqlchemy/backends/loader.go +++ b/vendor/yunion.io/x/sqlchemy/backends/loader.go @@ -16,6 +16,7 @@ package backends import ( _ "yunion.io/x/sqlchemy/backends/clickhouse" + _ "yunion.io/x/sqlchemy/backends/dameng" _ "yunion.io/x/sqlchemy/backends/mysql" _ "yunion.io/x/sqlchemy/backends/sqlite" ) diff --git a/vendor/yunion.io/x/sqlchemy/backends/mysql/column.go b/vendor/yunion.io/x/sqlchemy/backends/mysql/column.go index 5b1e324ab3..34a7384b45 100644 --- a/vendor/yunion.io/x/sqlchemy/backends/mysql/column.go +++ b/vendor/yunion.io/x/sqlchemy/backends/mysql/column.go @@ -368,7 +368,10 @@ type SDecimalColumn struct { // ColType implementation of SDecimalColumn for IColumnSpec func (c *SDecimalColumn) ColType() string { str := c.SBaseWidthColumn.ColType() - return fmt.Sprintf("%s, %d)", str[:len(str)-1], c.Precision) + if str[len(str)-1] == ')' { + str = str[:len(str)-1] + } + return fmt.Sprintf("%s, %d)", str, c.Precision) } // IsNumeric implementation of SDecimalColumn for IColumnSpec diff --git a/vendor/yunion.io/x/sqlchemy/backends/mysql/functions.go b/vendor/yunion.io/x/sqlchemy/backends/mysql/functions.go index 59a6b1cf6e..e812849ace 100644 --- a/vendor/yunion.io/x/sqlchemy/backends/mysql/functions.go +++ b/vendor/yunion.io/x/sqlchemy/backends/mysql/functions.go @@ -22,5 +22,5 @@ import ( // GROUP_CONCAT2 represents the SQL function GROUP_CONCAT func (mysql *SMySQLBackend) GROUP_CONCAT2(name string, sep string, field sqlchemy.IQueryField) sqlchemy.IQueryField { - return sqlchemy.NewFunctionField(name, fmt.Sprintf("GROUP_CONCAT(%%s SEPARATOR '%s')", sep), field) + return sqlchemy.NewFunctionField(name, true, fmt.Sprintf("GROUP_CONCAT(%%s SEPARATOR '%s')", sep), field) } diff --git a/vendor/yunion.io/x/sqlchemy/backends/mysql/sync.go b/vendor/yunion.io/x/sqlchemy/backends/mysql/sync.go index 495d7344a2..2e9688dea7 100644 --- a/vendor/yunion.io/x/sqlchemy/backends/mysql/sync.go +++ b/vendor/yunion.io/x/sqlchemy/backends/mysql/sync.go @@ -139,5 +139,5 @@ func (mysql *SMySQLBackend) CommitTableChangeSQL(ts sqlchemy.ITableSpec, changes } func createIndexSQL(ts sqlchemy.ITableSpec, idx sqlchemy.STableIndex) string { - return fmt.Sprintf("CREATE INDEX `%s` ON `%s` (%s)", idx.Name(), ts.Name(), strings.Join(idx.QuotedColumns(), ",")) + return fmt.Sprintf("CREATE INDEX `%s` ON `%s` (%s)", idx.Name(), ts.Name(), strings.Join(idx.QuotedColumns("`"), ",")) } diff --git a/vendor/yunion.io/x/sqlchemy/backends/sqlite/functions.go b/vendor/yunion.io/x/sqlchemy/backends/sqlite/functions.go index a374f471a7..89ff52a42f 100644 --- a/vendor/yunion.io/x/sqlchemy/backends/sqlite/functions.go +++ b/vendor/yunion.io/x/sqlchemy/backends/sqlite/functions.go @@ -22,5 +22,5 @@ import ( // GROUP_CONCAT2 represents the SQL function GROUP_CONCAT func (sqlite *SSqliteBackend) GROUP_CONCAT2(name string, sep string, field sqlchemy.IQueryField) sqlchemy.IQueryField { - return sqlchemy.NewFunctionField(name, fmt.Sprintf("GROUP_CONCAT(%%s, '%s')", sep), field) + return sqlchemy.NewFunctionField(name, true, fmt.Sprintf("GROUP_CONCAT(%%s, '%s')", sep), field) } diff --git a/vendor/yunion.io/x/sqlchemy/backends/sqlite/sync.go b/vendor/yunion.io/x/sqlchemy/backends/sqlite/sync.go index 52e946a390..702f290bed 100644 --- a/vendor/yunion.io/x/sqlchemy/backends/sqlite/sync.go +++ b/vendor/yunion.io/x/sqlchemy/backends/sqlite/sync.go @@ -133,5 +133,5 @@ func (sqlite *SSqliteBackend) CommitTableChangeSQL(ts sqlchemy.ITableSpec, chang } func createIndexSQL(ts sqlchemy.ITableSpec, idx sqlchemy.STableIndex) string { - return fmt.Sprintf("CREATE INDEX `%s` ON `%s` (%s)", idx.Name(), ts.Name(), strings.Join(idx.QuotedColumns(), ",")) + return fmt.Sprintf("CREATE INDEX `%s` ON `%s` (%s)", idx.Name(), ts.Name(), strings.Join(idx.QuotedColumns("`"), ",")) } diff --git a/vendor/yunion.io/x/sqlchemy/backends_base.go b/vendor/yunion.io/x/sqlchemy/backends_base.go index 31d731f103..2d56117c4f 100644 --- a/vendor/yunion.io/x/sqlchemy/backends_base.go +++ b/vendor/yunion.io/x/sqlchemy/backends_base.go @@ -121,22 +121,22 @@ func (bb *SBaseBackend) InsertOrUpdateSQLTemplate() string { } func (bb *SBaseBackend) CAST(field IQueryField, typeStr string, fieldname string) IQueryField { - return NewFunctionField(fieldname, `CAST(%s AS `+typeStr+`)`, field) + return NewFunctionField(fieldname, false, `CAST(%s AS `+typeStr+`)`, field) } // TimestampAdd represents a SQL function TimestampAdd func (bb *SBaseBackend) TIMESTAMPADD(name string, field IQueryField, offsetSeconds int) IQueryField { - return NewFunctionField(name, `TIMESTAMPADD(SECOND, `+fmt.Sprintf("%d", offsetSeconds)+`, %s)`, field) + return NewFunctionField(name, false, `TIMESTAMPADD(SECOND, `+fmt.Sprintf("%d", offsetSeconds)+`, %s)`, field) } // DATE_FORMAT represents a SQL function DATE_FORMAT func (bb *SBaseBackend) DATE_FORMAT(name string, field IQueryField, format string) IQueryField { - return NewFunctionField(name, `DATE_FORMAT(%s, "`+strings.ReplaceAll(format, "%", "%%")+`")`, field) + return NewFunctionField(name, false, `DATE_FORMAT(%s, "`+strings.ReplaceAll(format, "%", "%%")+`")`, field) } // INET_ATON represents a SQL function INET_ATON func (bb *SBaseBackend) INET_ATON(field IQueryField) IQueryField { - return NewFunctionField("", `INET_ATON(%s)`, field) + return NewFunctionField("", false, `INET_ATON(%s)`, field) } // SubStr represents a SQL function SUBSTR @@ -147,19 +147,19 @@ func (bb *SBaseBackend) SUBSTR(name string, field IQueryField, pos, length int) } else { rightStr = fmt.Sprintf("%d, %d)", pos, length) } - return NewFunctionField(name, `SUBSTR(%s, `+rightStr, field) + return NewFunctionField(name, false, `SUBSTR(%s, `+rightStr, field) } // OR_Val represents a SQL function that does binary | operation on a field func (bb *SBaseBackend) OR_Val(name string, field IQueryField, v interface{}) IQueryField { rightStr := fmt.Sprintf("|%v", v) - return NewFunctionField(name, "%s"+rightStr, field) + return NewFunctionField(name, false, "%s"+rightStr, field) } // AND_Val represents a SQL function that does binary & operation on a field func (bb *SBaseBackend) AND_Val(name string, field IQueryField, v interface{}) IQueryField { rightStr := fmt.Sprintf("&%v", v) - return NewFunctionField(name, "%s"+rightStr, field) + return NewFunctionField(name, false, "%s"+rightStr, field) } // CONCAT represents a SQL function CONCAT @@ -168,17 +168,17 @@ func (bb *SBaseBackend) CONCAT(name string, fields ...IQueryField) IQueryField { for i := 0; i < len(fields); i++ { params = append(params, "%s") } - return NewFunctionField(name, `CONCAT(`+strings.Join(params, ",")+`)`, fields...) + return NewFunctionField(name, false, `CONCAT(`+strings.Join(params, ",")+`)`, fields...) } // REPLACE represents a SQL function REPLACE func (bb *SBaseBackend) REPLACE(name string, field IQueryField, old string, new string) IQueryField { - return NewFunctionField(name, fmt.Sprintf(`REPLACE(%s, "%s", "%s")`, "%s", old, new), field) + return NewFunctionField(name, false, fmt.Sprintf(`REPLACE(%s, "%s", "%s")`, "%s", old, new), field) } // DISTINCT represents the SQL function DISTINCT func (bb *SBaseBackend) DISTINCT(name string, field IQueryField) IQueryField { - return NewFunctionField(name, "DISTINCT(%s)", field) + return NewFunctionField(name, false, "DISTINCT(%s)", field) } // COUNT represents the SQL function COUNT @@ -189,44 +189,52 @@ func (bb *SBaseBackend) COUNT(name string, field ...IQueryField) IQueryField { } else { expr = "COUNT(%s)" } - return NewFunctionField(name, expr, field...) + return NewFunctionField(name, true, expr, field...) } // MAX represents the SQL function MAX func (bb *SBaseBackend) MAX(name string, field IQueryField) IQueryField { - return NewFunctionField(name, "MAX(%s)", field) + return NewFunctionField(name, true, "MAX(%s)", field) } // MIN represents the SQL function MIN func (bb *SBaseBackend) MIN(name string, field IQueryField) IQueryField { - return NewFunctionField(name, "MIN(%s)", field) + return NewFunctionField(name, true, "MIN(%s)", field) } // SUM represents the SQL function SUM func (bb *SBaseBackend) SUM(name string, field IQueryField) IQueryField { - return NewFunctionField(name, "SUM(%s)", field) + return NewFunctionField(name, true, "SUM(%s)", field) } // LENGTH represents SQL function LENGTH func (bb *SBaseBackend) LENGTH(name string, field IQueryField) IQueryField { - return NewFunctionField(name, "LENGTH(%s)", field) + return NewFunctionField(name, false, "LENGTH(%s)", field) } func (bb *SBaseBackend) GROUP_CONCAT2(name string, sep string, field IQueryField) IQueryField { - return NewFunctionField(name, fmt.Sprintf("GROUP_CONCAT(%%s SEPARATOR '%s')", sep), field) + return NewFunctionField(name, true, fmt.Sprintf("GROUP_CONCAT(%%s SEPARATOR '%s')", sep), field) } // LOWER represents SQL function of LOWER func (bb *SBaseBackend) LOWER(name string, field IQueryField) IQueryField { - return NewFunctionField(name, "LOWER(%s)", field) + return NewFunctionField(name, false, "LOWER(%s)", field) } // UPPER represents SQL function of UPPER func (bb *SBaseBackend) UPPER(name string, field IQueryField) IQueryField { - return NewFunctionField(name, "UPPER(%s)", field) + return NewFunctionField(name, false, "UPPER(%s)", field) } // DATEDIFF represents SQL function of DATEDIFF func (bb *SBaseBackend) DATEDIFF(unit string, field1, field2 IQueryField) IQueryField { - return NewFunctionField("", fmt.Sprintf("DATEDIFF('%s',%s,%s)", unit, "%s", "%s"), field1, field2) + return NewFunctionField("", false, fmt.Sprintf("DATEDIFF('%s',%s,%s)", unit, "%s", "%s"), field1, field2) +} + +func (bb *SBaseBackend) QuoteChar() string { + return "`" +} + +func (bb *SBaseBackend) PrepareInsertOrUpdateSQL(ts ITableSpec, insertColNames []string, insertFields []string, onPrimaryCols []string, updateSetCols []string, insertValues []interface{}, updateValues []interface{}) (string, []interface{}) { + return "", nil } diff --git a/vendor/yunion.io/x/sqlchemy/backends_mock.go b/vendor/yunion.io/x/sqlchemy/backends_mock.go index 9948512ee4..a370c5ef28 100644 --- a/vendor/yunion.io/x/sqlchemy/backends_mock.go +++ b/vendor/yunion.io/x/sqlchemy/backends_mock.go @@ -124,6 +124,10 @@ func (mock *sMockBackend) InsertOrUpdateSQLTemplate() string { return "INSERT INTO `{{ .Table }}` ({{ .Columns }}) VALUES ({{ .Values }}) ON DUPLICATE KEY UPDATE {{ .SetValues }}" } +func (mock *sMockBackend) PrepareInsertOrUpdateSQL(ts ITableSpec, insertColNames []string, insertFields []string, onPrimaryCols []string, updateSetCols []string, insertValues []interface{}, updateValues []interface{}) (string, []interface{}) { + return "", nil +} + func (mock *sMockBackend) GetTableSQL() string { return "" } @@ -160,3 +164,7 @@ func (mock *sMockBackend) CurrentTimeStampString() string { func (mock *sMockBackend) CommitTableChangeSQL(ts ITableSpec, changes STableChanges) []string { return []string{} } + +func (mock *sMockBackend) QuoteChar() string { + return "`" +} diff --git a/vendor/yunion.io/x/sqlchemy/conditions.go b/vendor/yunion.io/x/sqlchemy/conditions.go index 113ebd4396..31ec0d35fb 100644 --- a/vendor/yunion.io/x/sqlchemy/conditions.go +++ b/vendor/yunion.io/x/sqlchemy/conditions.go @@ -251,7 +251,8 @@ type SIsEmptyCondition struct { // WhereClause implementation of SIsEmptyCondition for ICondition func (c *SIsEmptyCondition) WhereClause() string { - return fmt.Sprintf("%s = 0", c.field.Reference()) + // DAMENG LENGTH('') = NULL + return fmt.Sprintf("%s = 0 OR %s IS NULL", c.field.Reference(), c.field.Reference()) } // IsEmpty method that justifies where a text field is empty, e.g. length is zero @@ -268,7 +269,8 @@ type SIsNullOrEmptyCondition struct { // WhereClause implementation of SIsNullOrEmptyCondition for ICondition func (c *SIsNullOrEmptyCondition) WhereClause() string { originField := c.field.(*SFunctionFieldBase).queryFields()[0] - return fmt.Sprintf("%s IS NULL OR %s = 0", originField.Reference(), c.field.Reference()) + // DAMENG: LENGTH('') = NULL + return fmt.Sprintf("%s IS NULL OR %s = 0 OR %s IS NULL", originField.Reference(), c.field.Reference(), c.field.Reference()) } // IsNullOrEmpty is the ethod justifies a field is null or empty, e.g. a is null or length(a) == 0 diff --git a/vendor/yunion.io/x/sqlchemy/constraint.go b/vendor/yunion.io/x/sqlchemy/constraint.go index 7eef68b5e4..a3fe38f51b 100644 --- a/vendor/yunion.io/x/sqlchemy/constraint.go +++ b/vendor/yunion.io/x/sqlchemy/constraint.go @@ -14,9 +14,7 @@ package sqlchemy -import ( - "strings" -) +import "strings" type STableConstraint struct { name string diff --git a/vendor/yunion.io/x/sqlchemy/debug.go b/vendor/yunion.io/x/sqlchemy/debug.go index d84bce4220..a381728527 100644 --- a/vendor/yunion.io/x/sqlchemy/debug.go +++ b/vendor/yunion.io/x/sqlchemy/debug.go @@ -36,14 +36,18 @@ func sqlDebug(key, sqlstr string, variables []interface{}) { } func _sqlDebug(sqlstr string, variables []interface{}) string { + return SQLPrintf(sqlstr, variables) +} + +func SQLPrintf(sqlstr string, variables []interface{}) string { for _, v := range variables { switch v.(type) { case bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64: - sqlstr = strings.Replace(sqlstr, "?", fmt.Sprintf(`%v`, v), 1) + sqlstr = strings.Replace(sqlstr, "?", fmt.Sprintf("%v", v), 1) case string, time.Time: - sqlstr = strings.Replace(sqlstr, "?", fmt.Sprintf(`'%s'`, v), 1) + sqlstr = strings.Replace(sqlstr, "?", fmt.Sprintf("'%s'", v), 1) default: - sqlstr = strings.Replace(sqlstr, "?", fmt.Sprintf(`'%v'`, v), 1) + sqlstr = strings.Replace(sqlstr, "?", fmt.Sprintf("'%v'", v), 1) } } return sqlstr diff --git a/vendor/yunion.io/x/sqlchemy/delete_batch.go b/vendor/yunion.io/x/sqlchemy/delete_batch.go index ba0e8a1289..2ffb7649df 100644 --- a/vendor/yunion.io/x/sqlchemy/delete_batch.go +++ b/vendor/yunion.io/x/sqlchemy/delete_batch.go @@ -22,7 +22,7 @@ import ( "yunion.io/x/log" ) -func getSQLFilters(filter map[string]interface{}) ([]string, []interface{}) { +func getSQLFilters(filter map[string]interface{}, qChar string) ([]string, []interface{}) { conds := make([]string, 0, len(filter)) params := make([]interface{}, 0, len(filter)) for k, v := range filter { @@ -36,9 +36,9 @@ func getSQLFilters(filter map[string]interface{}) ([]string, []interface{}) { arr[i] = "?" params = append(params, value.Index(i).Interface()) } - conds = append(conds, fmt.Sprintf("`%s` in (%s)", k, strings.Join(arr, ", "))) + conds = append(conds, fmt.Sprintf("%s%s%s in (%s)", qChar, k, qChar, strings.Join(arr, ", "))) } else { - conds = append(conds, fmt.Sprintf("`%s` = ?", k)) + conds = append(conds, fmt.Sprintf("%s%s%s = ?", qChar, k, qChar)) params = append(params, v) } } @@ -48,11 +48,14 @@ func getSQLFilters(filter map[string]interface{}) ([]string, []interface{}) { func (ts *STableSpec) DeleteFrom(filters map[string]interface{}) error { buf := strings.Builder{} - buf.WriteString("DELETE FROM `") - buf.WriteString(ts.Name()) - buf.WriteString("`") + qChar := ts.Database().backend.QuoteChar() - conds, params := getSQLFilters(filters) + buf.WriteString("DELETE FROM ") + buf.WriteString(qChar) + buf.WriteString(ts.Name()) + buf.WriteString(qChar) + + conds, params := getSQLFilters(filters, qChar) if len(conds) > 0 { buf.WriteString(" WHERE ") diff --git a/vendor/yunion.io/x/sqlchemy/field_update.go b/vendor/yunion.io/x/sqlchemy/field_update.go index 09f3e9a2df..004fa96a5f 100644 --- a/vendor/yunion.io/x/sqlchemy/field_update.go +++ b/vendor/yunion.io/x/sqlchemy/field_update.go @@ -86,29 +86,31 @@ func (ts *STableSpec) updateFieldSql(dt interface{}, fields map[string]interface return nil, ErrEmptyPrimaryKey } + qChar := ts.Database().backend.QuoteChar() + vars := make([]interface{}, 0) var buf bytes.Buffer - buf.WriteString(fmt.Sprintf("UPDATE `%s` SET ", ts.name)) + buf.WriteString(fmt.Sprintf("UPDATE %s%s%s SET ", qChar, ts.name, qChar)) for i, k := range cnames { v := cv[k] if i > 0 { buf.WriteString(", ") } - buf.WriteString(fmt.Sprintf("`%s` = ?", k)) + buf.WriteString(fmt.Sprintf("%s%s%s = ?", qChar, k, qChar)) vars = append(vars, v) } for _, versionField := range versionFields { - buf.WriteString(fmt.Sprintf(", `%s` = `%s` + 1", versionField, versionField)) + buf.WriteString(fmt.Sprintf(", %s%s%s = %s%s%s + 1", qChar, versionField, qChar, qChar, versionField, qChar)) } for _, updatedField := range updatedFields { - buf.WriteString(fmt.Sprintf(", `%s` = %s", updatedField, ts.Database().backend.CurrentUTCTimeStampString())) + buf.WriteString(fmt.Sprintf(", %s%s%s = %s", qChar, updatedField, qChar, ts.Database().backend.CurrentUTCTimeStampString())) } buf.WriteString(" WHERE ") for i, pkv := range primaryCols { if i > 0 { buf.WriteString(" AND ") } - buf.WriteString(fmt.Sprintf("`%s` = ?", pkv.key)) + buf.WriteString(fmt.Sprintf("%s%s%s = ?", qChar, pkv.key, qChar)) vars = append(vars, pkv.value) } diff --git a/vendor/yunion.io/x/sqlchemy/functions.go b/vendor/yunion.io/x/sqlchemy/functions.go index 13a082c798..50dabf1ae0 100644 --- a/vendor/yunion.io/x/sqlchemy/functions.go +++ b/vendor/yunion.io/x/sqlchemy/functions.go @@ -21,6 +21,14 @@ import ( "yunion.io/x/log" ) +// IFunctionQueryField is a special type of field that is an aggregate function +type IFunctionQueryField interface { + IQueryField + + // is this an aggregate function? + IsAggregate() bool +} + // IFunction is the interface for a SQL embedded function, such as MIN, MAX, NOW, etc. type IFunction interface { expression() string @@ -42,6 +50,16 @@ func NewFunction(ifunc IFunction, name string) IQueryField { type SFunctionFieldBase struct { IFunction alias string + + aggregate bool +} + +func (ff *SFunctionFieldBase) getQuoteChar() string { + qChar := "" + if ff.database() != nil { + qChar = ff.database().backend.QuoteChar() + } + return qChar } // Reference implementation of SFunctionFieldBase for IQueryField @@ -50,14 +68,16 @@ func (ff *SFunctionFieldBase) Reference() string { // log.Warningf("reference a function field without alias! %s", ff.expression()) return ff.expression() } - return fmt.Sprintf("`%s`", ff.alias) + qChar := ff.getQuoteChar() + return fmt.Sprintf("%s%s%s", qChar, ff.alias, qChar) } // Expression implementation of SFunctionFieldBase for IQueryField func (ff *SFunctionFieldBase) Expression() string { if len(ff.alias) > 0 { + qChar := ff.getQuoteChar() // add alias - return fmt.Sprintf("%s AS `%s`", ff.expression(), ff.alias) + return fmt.Sprintf("%s AS %s%s%s", ff.expression(), qChar, ff.alias, qChar) } // no alias return ff.expression() @@ -84,6 +104,10 @@ func (ff *SFunctionFieldBase) Variables() []interface{} { return ff.variables() } +func (ff *SFunctionFieldBase) IsAggregate() bool { + return ff.aggregate +} + type sExprFunction struct { fields []IQueryField function string @@ -92,7 +116,12 @@ type sExprFunction struct { func (ff *sExprFunction) expression() string { fieldRefs := make([]interface{}, 0) for _, f := range ff.fields { - fieldRefs = append(fieldRefs, f.Reference()) + switch tf := f.(type) { + case *SFunctionFieldBase: + fieldRefs = append(fieldRefs, tf.expression()) + default: + fieldRefs = append(fieldRefs, tf.Reference()) + } } return fmt.Sprintf(ff.function, fieldRefs...) } @@ -122,7 +151,7 @@ func (ff *sExprFunction) queryFields() []IQueryField { } // NewFunctionField returns an instance of query field by calling a SQL embedded function -func NewFunctionField(name string, funcexp string, fields ...IQueryField) IQueryField { +func NewFunctionField(name string, isAggr bool, funcexp string, fields ...IQueryField) IQueryField { funcBase := &sExprFunction{ fields: fields, function: funcexp, @@ -130,6 +159,7 @@ func NewFunctionField(name string, funcexp string, fields ...IQueryField) IQuery return &SFunctionFieldBase{ IFunction: funcBase, alias: name, + aggregate: isAggr, } } @@ -196,7 +226,7 @@ func (s *SConstField) Expression() string { if len(name) == 0 { return s.Reference() } else { - return fmt.Sprintf("%s AS `%s`", s.Reference(), name) + return fmt.Sprintf("%s AS %s", s.Reference(), name) } } @@ -228,6 +258,11 @@ func (s *SConstField) Variables() []interface{} { return nil } +// IsAggregate implementation of SConstField for IFunctionQueryField +func (s *SConstField) IsAggregate() bool { + return true +} + // NewConstField returns an instance of SConstField func NewConstField(variable interface{}) *SConstField { return &SConstField{constVar: variable} @@ -245,7 +280,7 @@ func (s *SStringField) Expression() string { if len(name) == 0 { return s.Reference() } else { - return fmt.Sprintf("%s AS `%s`", s.Reference(), name) + return fmt.Sprintf("%s AS %s", s.Reference(), name) } } @@ -277,6 +312,11 @@ func (s *SStringField) Variables() []interface{} { return nil } +// IsAggregate implementation of SStringField for IFunctionQueryField +func (s *SStringField) IsAggregate() bool { + return true +} + // NewStringField returns an instance of SStringField func NewStringField(strConst string) *SStringField { return &SStringField{strConst: strConst} @@ -343,7 +383,7 @@ func bc(name, op string, fields ...IQueryField) IQueryField { for i := 0; i < len(fields); i++ { exps = append(exps, "%s") } - return NewFunctionField(name, strings.Join(exps, fmt.Sprintf(" %s ", op)), fields...) + return NewFunctionField(name, false, strings.Join(exps, fmt.Sprintf(" %s ", op)), fields...) } func ADD(name string, fields ...IQueryField) IQueryField { @@ -367,5 +407,5 @@ func DATEDIFF(unit string, field1, field2 IQueryField) IQueryField { } func ABS(name string, field IQueryField) IQueryField { - return NewFunctionField(name, "ABS(%s)", field) + return NewFunctionField(name, false, "ABS(%s)", field) } diff --git a/vendor/yunion.io/x/sqlchemy/inc.go b/vendor/yunion.io/x/sqlchemy/inc.go index 43d157f25d..1f3fd9447a 100644 --- a/vendor/yunion.io/x/sqlchemy/inc.go +++ b/vendor/yunion.io/x/sqlchemy/inc.go @@ -54,6 +54,8 @@ func (t *STableSpec) incrementInternalSql(diff interface{}, opcode string, targe targetFields = reflectutils.FetchStructFieldValueSet(targetValue) } + qChar := t.Database().backend.QuoteChar() + primaries := make([]sPrimaryKeyValue, 0) vars := make([]interface{}, 0) versionFields := make([]string, 0) @@ -105,7 +107,7 @@ func (t *STableSpec) incrementInternalSql(diff interface{}, opcode string, targe } var buf bytes.Buffer - buf.WriteString(fmt.Sprintf("UPDATE `%s` SET ", t.name)) + buf.WriteString(fmt.Sprintf("UPDATE %s%s%s SET ", qChar, t.name, qChar)) first := true for _, k := range incFields { if first { @@ -113,13 +115,13 @@ func (t *STableSpec) incrementInternalSql(diff interface{}, opcode string, targe } else { buf.WriteString(", ") } - buf.WriteString(fmt.Sprintf("`%s` = `%s` %s ?", k, k, opcode)) + buf.WriteString(fmt.Sprintf("%s%s%s = %s%s%s %s ?", qChar, k, qChar, qChar, k, qChar, opcode)) } for _, versionField := range versionFields { - buf.WriteString(fmt.Sprintf(", `%s` = `%s` + 1", versionField, versionField)) + buf.WriteString(fmt.Sprintf(", %s%s%s = %s%s%s + 1", qChar, versionField, qChar, qChar, versionField, qChar)) } for _, updatedField := range updatedFields { - buf.WriteString(fmt.Sprintf(", `%s` = %s", updatedField, t.Database().backend.CurrentUTCTimeStampString())) + buf.WriteString(fmt.Sprintf(", %s%s%s = %s", qChar, updatedField, qChar, t.Database().backend.CurrentUTCTimeStampString())) } buf.WriteString(" WHERE ") @@ -127,7 +129,7 @@ func (t *STableSpec) incrementInternalSql(diff interface{}, opcode string, targe if i > 0 { buf.WriteString(" AND ") } - buf.WriteString(fmt.Sprintf("`%s` = ?", pkv.key)) + buf.WriteString(fmt.Sprintf("%s%s%s = ?", qChar, pkv.key, qChar)) vars = append(vars, pkv.value) } diff --git a/vendor/yunion.io/x/sqlchemy/index.go b/vendor/yunion.io/x/sqlchemy/index.go index 2b0a1229f0..9f89ecc9ce 100644 --- a/vendor/yunion.io/x/sqlchemy/index.go +++ b/vendor/yunion.io/x/sqlchemy/index.go @@ -88,10 +88,10 @@ func (index *STableIndex) IsIdentical(cols ...string) bool { return true } -func (index *STableIndex) QuotedColumns() []string { +func (index *STableIndex) QuotedColumns(quoteStr string) []string { ret := make([]string, len(index.columns)) for i := 0; i < len(ret); i++ { - ret[i] = fmt.Sprintf("`%s`", index.columns[i]) + ret[i] = fmt.Sprintf("%s%s%s", quoteStr, index.columns[i], quoteStr) } return ret } diff --git a/vendor/yunion.io/x/sqlchemy/insert.go b/vendor/yunion.io/x/sqlchemy/insert.go index 610a718587..f856cb8ed4 100644 --- a/vendor/yunion.io/x/sqlchemy/insert.go +++ b/vendor/yunion.io/x/sqlchemy/insert.go @@ -75,6 +75,8 @@ func (t *STableSpec) InsertSqlPrep(data interface{}, update bool) (*InsertSqlRes primaryKeys := make([]string, 0) primaries := make(map[string]interface{}) + qChar := t.Database().backend.QuoteChar() + for _, c := range t.Columns() { isAutoInc := false if c.IsAutoIncrement() { @@ -90,13 +92,13 @@ func (t *STableSpec) InsertSqlPrep(data interface{}, update bool) (*InsertSqlRes } if c.IsPrimary() { - primaryKeys = append(primaryKeys, fmt.Sprintf("`%s`", k)) + primaryKeys = append(primaryKeys, fmt.Sprintf("%s%s%s", qChar, k, qChar)) } // created_at or updated_at but must not be a primary key if c.IsCreatedAt() || c.IsUpdatedAt() { createdAtFields = append(createdAtFields, k) - names = append(names, fmt.Sprintf("`%s`", k)) + names = append(names, fmt.Sprintf("%s%s%s", qChar, k, qChar)) if c.IsZero(ov) { if t.Database().backend.SupportMixedInsertVariables() { format = append(format, t.Database().backend.CurrentUTCTimeStampString()) @@ -111,10 +113,10 @@ func (t *STableSpec) InsertSqlPrep(data interface{}, update bool) (*InsertSqlRes if update && c.IsUpdatedAt() && !c.IsPrimary() { if c.IsZero(ov) { - updates = append(updates, fmt.Sprintf("`%s` = %s", k, t.Database().backend.CurrentUTCTimeStampString())) + updates = append(updates, fmt.Sprintf("%s%s%s = %s", qChar, k, qChar, t.Database().backend.CurrentUTCTimeStampString())) // updateValues = append(updateValues, now) } else { - updates = append(updates, fmt.Sprintf("`%s` = ?", k)) + updates = append(updates, fmt.Sprintf("%s%s%s = ?", qChar, k, qChar)) updateValues = append(updateValues, ov) } } @@ -132,7 +134,7 @@ func (t *STableSpec) InsertSqlPrep(data interface{}, update bool) (*InsertSqlRes // auto_version and must not be a primary key if update && c.IsAutoVersion() { - updates = append(updates, fmt.Sprintf("`%s` = `%s` + 1", k, k)) + updates = append(updates, fmt.Sprintf("%s%s%s = %s%s%s + 1", qChar, k, qChar, qChar, k, qChar)) continue } @@ -140,11 +142,11 @@ func (t *STableSpec) InsertSqlPrep(data interface{}, update bool) (*InsertSqlRes if c.IsSupportDefault() && (len(c.Default()) > 0 || c.IsString()) && !gotypes.IsNil(ov) && c.IsZero(ov) && !c.AllowZero() { // empty text value val := c.ConvertFromString(c.Default()) values = append(values, val) - names = append(names, fmt.Sprintf("`%s`", k)) + names = append(names, fmt.Sprintf("%s%s%s", qChar, k, qChar)) format = append(format, "?") if update && !c.IsPrimary() { - updates = append(updates, fmt.Sprintf("`%s` = ?", k)) + updates = append(updates, fmt.Sprintf("%s%s%s = ?", qChar, k, qChar)) updateValues = append(updateValues, val) } @@ -158,11 +160,11 @@ func (t *STableSpec) InsertSqlPrep(data interface{}, update bool) (*InsertSqlRes if !gotypes.IsNil(ov) && (!c.IsZero(ov) || (!c.IsPointer() && !c.IsText())) && !isAutoInc { v := c.ConvertFromValue(ov) values = append(values, v) - names = append(names, fmt.Sprintf("`%s`", k)) + names = append(names, fmt.Sprintf("%s%s%s", qChar, k, qChar)) format = append(format, "?") if update && !c.IsPrimary() { - updates = append(updates, fmt.Sprintf("`%s` = ?", k)) + updates = append(updates, fmt.Sprintf("%s%s%s = ?", qChar, k, qChar)) updateValues = append(updateValues, v) } @@ -181,7 +183,7 @@ func (t *STableSpec) InsertSqlPrep(data interface{}, update bool) (*InsertSqlRes autoIncField = k } else if c.IsText() { values = append(values, "") - names = append(names, fmt.Sprintf("`%s`", k)) + names = append(names, fmt.Sprintf("%s%s%s", qChar, k, qChar)) format = append(format, "?") primaries[k] = "" } else { @@ -192,14 +194,14 @@ func (t *STableSpec) InsertSqlPrep(data interface{}, update bool) (*InsertSqlRes // empty without default if update { - updates = append(updates, fmt.Sprintf("`%s` = NULL", k)) + updates = append(updates, fmt.Sprintf("%s%s%s = NULL", qChar, k, qChar)) continue } } var insertSql string if !update { - insertSql = templateEval(t.Database().backend.InsertSQLTemplate(), struct { + insertSql = TemplateEval(t.Database().backend.InsertSQLTemplate(), struct { Table string Columns string Values string @@ -209,20 +211,27 @@ func (t *STableSpec) InsertSqlPrep(data interface{}, update bool) (*InsertSqlRes Values: strings.Join(format, ", "), }) } else { - insertSql = templateEval(t.Database().backend.InsertOrUpdateSQLTemplate(), struct { - Table string - Columns string - Values string - PrimaryKeys string - SetValues string - }{ - Table: t.name, - Columns: strings.Join(names, ", "), - Values: strings.Join(format, ", "), - PrimaryKeys: strings.Join(primaryKeys, ", "), - SetValues: strings.Join(updates, ", "), - }) - values = append(values, updateValues...) + sqlTemp := t.Database().backend.InsertOrUpdateSQLTemplate() + if len(sqlTemp) > 0 { + // insert into ... on duplicate update ... pattern + insertSql = TemplateEval(sqlTemp, struct { + Table string + Columns string + Values string + PrimaryKeys string + SetValues string + }{ + Table: t.name, + Columns: strings.Join(names, ", "), + Values: strings.Join(format, ", "), + PrimaryKeys: strings.Join(primaryKeys, ", "), + SetValues: strings.Join(updates, ", "), + }) + values = append(values, updateValues...) + } else { + // customize pattern + insertSql, values = t.Database().backend.PrepareInsertOrUpdateSQL(t, names, format, primaryKeys, updates, values, updateValues) + } } return &InsertSqlResult{ diff --git a/vendor/yunion.io/x/sqlchemy/insert_batch.go b/vendor/yunion.io/x/sqlchemy/insert_batch.go index b9a54a077e..77a5200c88 100644 --- a/vendor/yunion.io/x/sqlchemy/insert_batch.go +++ b/vendor/yunion.io/x/sqlchemy/insert_batch.go @@ -32,14 +32,18 @@ const ( ) func (t *STableSpec) InsertBatch(dataList []interface{}) error { + qChar := t.Database().backend.QuoteChar() + var sql string var fieldCount int { buffer := new(bytes.Buffer) - buffer.WriteString("INSERT INTO `") + buffer.WriteString("INSERT INTO ") + buffer.WriteString(qChar) buffer.WriteString(t.Name()) - buffer.WriteString("` (") + buffer.WriteString(qChar) + buffer.WriteString(" (") headers := make([]string, 0) format := make([]string, 0) @@ -48,7 +52,7 @@ func (t *STableSpec) InsertBatch(dataList []interface{}) error { continue } name := col.Name() - headers = append(headers, fmt.Sprintf("`%s`", name)) + headers = append(headers, fmt.Sprintf("%s%s%s", qChar, name, qChar)) if col.IsCreatedAt() || col.IsUpdatedAt() { if t.Database().backend.SupportMixedInsertVariables() { format = append(format, t.Database().backend.CurrentUTCTimeStampString()) diff --git a/vendor/yunion.io/x/sqlchemy/query.go b/vendor/yunion.io/x/sqlchemy/query.go index 9ea7083985..e30b46b276 100644 --- a/vendor/yunion.io/x/sqlchemy/query.go +++ b/vendor/yunion.io/x/sqlchemy/query.go @@ -18,6 +18,7 @@ import ( "database/sql" "fmt" "reflect" + "runtime/debug" "strings" "yunion.io/x/log" @@ -417,6 +418,7 @@ func (tq *SQuery) Field(name string) IQueryField { f := tq.findField(name) if f == nil { log.Errorf("SQuery %s cannot find Field %s", tq.String(), name) + debug.PrintStack() } return f } diff --git a/vendor/yunion.io/x/sqlchemy/querydefs.go b/vendor/yunion.io/x/sqlchemy/querydefs.go index 530ddc160e..b82a15a885 100644 --- a/vendor/yunion.io/x/sqlchemy/querydefs.go +++ b/vendor/yunion.io/x/sqlchemy/querydefs.go @@ -102,6 +102,8 @@ func queryString(tq *SQuery, tmpFields ...IQueryField) string { return tq.rawSql } + qChar := tq.database().backend.QuoteChar() + var buf bytes.Buffer buf.WriteString("SELECT ") if tq.distinct { @@ -110,9 +112,10 @@ func queryString(tq *SQuery, tmpFields ...IQueryField) string { fields := tmpFields if len(fields) == 0 { - fields = tq.fields - if len(fields) == 0 { - fields = tq.from.Fields() + if len(tq.fields) > 0 { + fields = append(fields, tq.fields...) + } else { + fields = append(fields, tq.from.Fields()...) for i := range fields { tq.from.Field(fields[i].Name()) } @@ -135,19 +138,45 @@ func queryString(tq *SQuery, tmpFields ...IQueryField) string { fields = append(fields, refFields...) } + groupFields := make(map[string]IQueryField) + if len(tq.groupBy) > 0 { + for i := range tq.groupBy { + f := tq.groupBy[i] + groupFields[f.Name()] = f + } + } + for i := range fields { if i > 0 { buf.WriteString(", ") } - buf.WriteString(fields[i].Expression()) + f := fields[i] + if len(tq.groupBy) > 0 { + if gf, ok := groupFields[f.Name()]; ok && f.Reference() == gf.Reference() { + // in group by, normal + buf.WriteString(f.Expression()) + } else { + // not in group by, check if the field is a group aggregate function + if gf, ok := f.(IFunctionQueryField); ok && gf.IsAggregate() { + // is a aggregate function field + buf.WriteString(f.Expression()) + } else { + f = MAX(f.Name(), f) + buf.WriteString(f.Expression()) + } + } + } else { + // normal + buf.WriteString(f.Expression()) + } } buf.WriteString(" FROM ") - buf.WriteString(fmt.Sprintf("%s AS `%s`", tq.from.Expression(), tq.from.Alias())) + buf.WriteString(fmt.Sprintf("%s AS %s%s%s", tq.from.Expression(), qChar, tq.from.Alias(), qChar)) for _, join := range tq.joins { buf.WriteByte(' ') buf.WriteString(string(join.jointype)) buf.WriteByte(' ') - buf.WriteString(fmt.Sprintf("%s AS `%s`", join.from.Expression(), join.from.Alias())) + buf.WriteString(fmt.Sprintf("%s AS %s%s%s", join.from.Expression(), qChar, join.from.Alias(), qChar)) whereCls := join.condition.WhereClause() if len(whereCls) > 0 { buf.WriteString(" ON ") diff --git a/vendor/yunion.io/x/sqlchemy/queryfield.go b/vendor/yunion.io/x/sqlchemy/queryfield.go index d62c29ec1b..95a575c27c 100644 --- a/vendor/yunion.io/x/sqlchemy/queryfield.go +++ b/vendor/yunion.io/x/sqlchemy/queryfield.go @@ -24,11 +24,13 @@ type sQueryField struct { // the string after select func (sqf *sQueryField) Expression() string { + qChar := sqf.from.database().backend.QuoteChar() + alias := sqf.name if len(sqf.alias) > 0 { alias = sqf.alias } - return fmt.Sprintf("`%s`.`%s` AS `%s`", sqf.from.Alias(), sqf.name, alias) + return fmt.Sprintf("%s%s%s.%s%s%s AS %s%s%s", qChar, sqf.from.Alias(), qChar, qChar, sqf.name, qChar, qChar, alias, qChar) } // the name of thie field @@ -41,7 +43,8 @@ func (sqf *sQueryField) Name() string { // the reference string in where clause func (sqf *sQueryField) Reference() string { - return fmt.Sprintf("`%s`.`%s`", sqf.from.Alias(), sqf.Name()) + qChar := sqf.from.database().backend.QuoteChar() + return fmt.Sprintf("%s%s%s.%s%s%s", qChar, sqf.from.Alias(), qChar, qChar, sqf.Name(), qChar) } // give this field an alias name diff --git a/vendor/yunion.io/x/sqlchemy/sql.go b/vendor/yunion.io/x/sqlchemy/sql.go index ae552fbf40..27b4952445 100644 --- a/vendor/yunion.io/x/sqlchemy/sql.go +++ b/vendor/yunion.io/x/sqlchemy/sql.go @@ -16,6 +16,7 @@ package sqlchemy import ( "database/sql" + "strings" "yunion.io/x/log" "yunion.io/x/pkg/errors" @@ -132,7 +133,7 @@ func (db *SDatabase) GetTables() []string { } ret := make([]string, len(tables)) for i, t := range tables { - ret[i] = t.Name + ret[i] = strings.ToLower(t.Name) } return ret } @@ -159,9 +160,10 @@ func (db *SDatabase) TxBatchExec(sqlstr string, varsList [][]interface{}) ([]SSq return nil, errors.Wrap(err, "Begin transaction") } defer tx.Rollback() + stmt, err := tx.Prepare(sqlstr) if err != nil { - return nil, errors.Wrapf(err, "Prepare sql %s", sqlstr) + return nil, errors.Wrapf(err, "Prepare sql %s", SQLPrintf(sqlstr, varsList[0])) } defer stmt.Close() diff --git a/vendor/yunion.io/x/sqlchemy/subquery.go b/vendor/yunion.io/x/sqlchemy/subquery.go index 69051f5c4c..d1da45aba2 100644 --- a/vendor/yunion.io/x/sqlchemy/subquery.go +++ b/vendor/yunion.io/x/sqlchemy/subquery.go @@ -30,11 +30,13 @@ type SSubQueryField struct { // Expression implementation of SSubQueryField for IQueryField func (sqf *SSubQueryField) Expression() string { + qChar := sqf.query.database().backend.QuoteChar() + alias := sqf.field.Name() if len(sqf.alias) > 0 { alias = sqf.alias } - return fmt.Sprintf("`%s`.`%s` AS `%s`", sqf.query.alias, sqf.field.Name(), alias) + return fmt.Sprintf("%s%s%s.%s%s%s AS %s%s%s", qChar, sqf.query.alias, qChar, qChar, sqf.field.Name(), qChar, qChar, alias, qChar) } // Name implementation of SSubQueryField for IQueryField @@ -47,7 +49,9 @@ func (sqf *SSubQueryField) Name() string { // Reference implementation of SSubQueryField for IQueryField func (sqf *SSubQueryField) Reference() string { - return fmt.Sprintf("`%s`.`%s`", sqf.query.alias, sqf.Name()) + qChar := sqf.query.database().backend.QuoteChar() + + return fmt.Sprintf("%s%s%s.%s%s%s", qChar, sqf.query.alias, qChar, qChar, sqf.Name(), qChar) } // Label implementation of SSubQueryField for IQueryField diff --git a/vendor/yunion.io/x/sqlchemy/sync.go b/vendor/yunion.io/x/sqlchemy/sync.go index a18b81f550..c5e7cc472f 100644 --- a/vendor/yunion.io/x/sqlchemy/sync.go +++ b/vendor/yunion.io/x/sqlchemy/sync.go @@ -160,6 +160,9 @@ func (ts *STableSpec) DropForeignKeySQL() []string { if db.backend == nil { panic("DropForeignKeySQL empty backend") } + + qChar := db.backend.QuoteChar() + if db.backend.IsSupportIndexAndContraints() { _, constraints, err := ts.fetchIndexesAndConstraints() if err != nil { @@ -170,7 +173,7 @@ func (ts *STableSpec) DropForeignKeySQL() []string { } for _, constraint := range constraints { - sql := fmt.Sprintf("ALTER TABLE `%s` DROP FOREIGN KEY `%s`", ts.name, constraint.name) + sql := fmt.Sprintf("ALTER TABLE %s%s%s DROP FOREIGN KEY %s%s%s", qChar, ts.name, qChar, qChar, constraint.name, qChar) ret = append(ret, sql) log.Infof("%s;", sql) } diff --git a/vendor/yunion.io/x/sqlchemy/table.go b/vendor/yunion.io/x/sqlchemy/table.go index dbfaded3b2..3fa121870a 100644 --- a/vendor/yunion.io/x/sqlchemy/table.go +++ b/vendor/yunion.io/x/sqlchemy/table.go @@ -162,7 +162,8 @@ func (ts *STableSpec) Name() string { // Expression implementation of STableSpec for ITableSpec func (ts *STableSpec) Expression() string { - return fmt.Sprintf("`%s`", ts.name) + qChar := ts.Database().backend.QuoteChar() + return fmt.Sprintf("%s%s%s", qChar, ts.name, qChar) } func (ts *STableSpec) SyncColumnIndexes() error { @@ -358,7 +359,8 @@ func (c *STableField) Expression() string { if len(c.alias) > 0 { alias = c.alias } - return fmt.Sprintf("`%s`.`%s` AS `%s`", c.table.Alias(), c.spec.Name(), alias) + qChar := c.database().backend.QuoteChar() + return fmt.Sprintf("%s%s%s.%s%s%s AS %s%s%s", qChar, c.table.Alias(), qChar, qChar, c.spec.Name(), qChar, qChar, alias, qChar) } // Name implementation of STableField for IQueryField @@ -371,7 +373,8 @@ func (c *STableField) Name() string { // Reference implementation of STableField for IQueryField func (c *STableField) Reference() string { - return fmt.Sprintf("`%s`.`%s`", c.table.Alias(), c.Name()) + qChar := c.database().backend.QuoteChar() + return fmt.Sprintf("%s%s%s.%s%s%s", qChar, c.table.Alias(), qChar, qChar, c.Name(), qChar) } // Label implementation of STableField for IQueryField diff --git a/vendor/yunion.io/x/sqlchemy/template.go b/vendor/yunion.io/x/sqlchemy/template.go index 845e77b311..43cb53f149 100644 --- a/vendor/yunion.io/x/sqlchemy/template.go +++ b/vendor/yunion.io/x/sqlchemy/template.go @@ -23,7 +23,7 @@ var ( templateTbl = make(map[string]*template.Template) ) -func templateEval(temp string, variables interface{}) string { +func TemplateEval(temp string, variables interface{}) string { if eval, ok := templateTbl[temp]; !ok { eval = template.Must(template.New(temp).Parse(temp)) templateTbl[temp] = eval diff --git a/vendor/yunion.io/x/sqlchemy/union.go b/vendor/yunion.io/x/sqlchemy/union.go index 905ba57997..171b3f6f0c 100644 --- a/vendor/yunion.io/x/sqlchemy/union.go +++ b/vendor/yunion.io/x/sqlchemy/union.go @@ -32,11 +32,13 @@ type SUnionQueryField struct { // Expression implementation of SUnionQueryField for IQueryField func (sqf *SUnionQueryField) Expression() string { + qChar := sqf.union.database().backend.QuoteChar() + alias := sqf.name if len(sqf.alias) > 0 { alias = sqf.alias } - return fmt.Sprintf("`%s`.`%s` AS `%s`", sqf.union.Alias(), sqf.name, alias) + return fmt.Sprintf("%s%s%s.%s%s%s AS %s%s%s", qChar, sqf.union.Alias(), qChar, qChar, sqf.name, qChar, qChar, alias, qChar) } // Name implementation of SUnionQueryField for IQueryField @@ -49,7 +51,9 @@ func (sqf *SUnionQueryField) Name() string { // Reference implementation of SUnionQueryField for IQueryField func (sqf *SUnionQueryField) Reference() string { - return fmt.Sprintf("`%s`.`%s`", sqf.union.Alias(), sqf.Name()) + qChar := sqf.union.database().backend.QuoteChar() + + return fmt.Sprintf("%s%s%s.%s%s%s", qChar, sqf.union.Alias(), qChar, qChar, sqf.Name(), qChar) } // Label implementation of SUnionQueryField for IQueryField diff --git a/vendor/yunion.io/x/sqlchemy/update.go b/vendor/yunion.io/x/sqlchemy/update.go index fb1ea59f79..30958edc5b 100644 --- a/vendor/yunion.io/x/sqlchemy/update.go +++ b/vendor/yunion.io/x/sqlchemy/update.go @@ -189,29 +189,31 @@ func (us *SUpdateSession) SaveUpdateSql(dt interface{}) (*SUpdateSQLResult, erro return nil, ErrEmptyPrimaryKey } + qChar := us.tableSpec.Database().backend.QuoteChar() + vars := make([]interface{}, 0) colsets := make([]string, 0) conditions := make([]string, 0) for _, udif := range setters { if gotypes.IsNil(udif.new) { - colsets = append(colsets, fmt.Sprintf("`%s` = NULL", udif.col.Name())) + colsets = append(colsets, fmt.Sprintf("%s%s%s = NULL", qChar, udif.col.Name(), qChar)) } else { - colsets = append(colsets, fmt.Sprintf("`%s` = ?", udif.col.Name())) + colsets = append(colsets, fmt.Sprintf("%s%s%s = ?", qChar, udif.col.Name(), qChar)) vars = append(vars, udif.col.ConvertFromValue(udif.new)) } } for _, versionField := range versionFields { - colsets = append(colsets, fmt.Sprintf("`%s` = `%s` + 1", versionField, versionField)) + colsets = append(colsets, fmt.Sprintf("%s%s%s = %s%s%s + 1", qChar, versionField, qChar, qChar, versionField, qChar)) } for _, updatedField := range updatedFields { - colsets = append(colsets, fmt.Sprintf("`%s` = %s", updatedField, us.tableSpec.Database().backend.CurrentUTCTimeStampString())) + colsets = append(colsets, fmt.Sprintf("%s%s%s = %s", qChar, updatedField, qChar, us.tableSpec.Database().backend.CurrentUTCTimeStampString())) } for _, pkv := range primaries { - conditions = append(conditions, fmt.Sprintf("`%s` = ?", pkv.key)) + conditions = append(conditions, fmt.Sprintf("%s%s%s = ?", qChar, pkv.key, qChar)) vars = append(vars, pkv.value) } - updateSql := templateEval(us.tableSpec.Database().backend.UpdateSQLTemplate(), struct { + updateSql := TemplateEval(us.tableSpec.Database().backend.UpdateSQLTemplate(), struct { Table string Columns string Conditions string diff --git a/vendor/yunion.io/x/sqlchemy/update_batch.go b/vendor/yunion.io/x/sqlchemy/update_batch.go index c4f4e041b0..0ae7d3aed7 100644 --- a/vendor/yunion.io/x/sqlchemy/update_batch.go +++ b/vendor/yunion.io/x/sqlchemy/update_batch.go @@ -26,20 +26,24 @@ func (ts *STableSpec) UpdateBatch(data map[string]interface{}, filter map[string return nil } + qChar := ts.Database().backend.QuoteChar() + params := make([]interface{}, 0, len(data)) setter := make([]string, 0, len(data)) for k, v := range data { - setter = append(setter, fmt.Sprintf("`%s` = ?", k)) + setter = append(setter, fmt.Sprintf("%s%s%s = ?", qChar, k, qChar)) params = append(params, v) } - conds, condparams := getSQLFilters(filter) + conds, condparams := getSQLFilters(filter, qChar) params = append(params, condparams...) buf := strings.Builder{} - buf.WriteString("UPDATE `") + buf.WriteString("UPDATE ") + buf.WriteString(qChar) buf.WriteString(ts.Name()) - buf.WriteString("` SET ") + buf.WriteString(qChar) + buf.WriteString(" SET ") buf.WriteString(strings.Join(setter, ", ")) if len(conds) > 0 {