gbase8sdb 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gbase8sdb-1.0.0/LICENSE.txt +21 -0
- gbase8sdb-1.0.0/MANIFEST.in +4 -0
- gbase8sdb-1.0.0/PKG-INFO +74 -0
- gbase8sdb-1.0.0/README.md +57 -0
- gbase8sdb-1.0.0/pyproject.toml +3 -0
- gbase8sdb-1.0.0/setup.cfg +26 -0
- gbase8sdb-1.0.0/setup.py +40 -0
- gbase8sdb-1.0.0/src/gbase8sdb/__init__.py +112 -0
- gbase8sdb-1.0.0/src/gbase8sdb/column_metadata.py +111 -0
- gbase8sdb-1.0.0/src/gbase8sdb/connection.py +192 -0
- gbase8sdb-1.0.0/src/gbase8sdb/connection_async.py +162 -0
- gbase8sdb-1.0.0/src/gbase8sdb/constructors.py +35 -0
- gbase8sdb-1.0.0/src/gbase8sdb/cursor.py +355 -0
- gbase8sdb-1.0.0/src/gbase8sdb/cursor_async.py +136 -0
- gbase8sdb-1.0.0/src/gbase8sdb/defaults.py +45 -0
- gbase8sdb-1.0.0/src/gbase8sdb/driver.pxd +57 -0
- gbase8sdb-1.0.0/src/gbase8sdb/driver.pyx +73 -0
- gbase8sdb-1.0.0/src/gbase8sdb/dsn.py +53 -0
- gbase8sdb-1.0.0/src/gbase8sdb/errors.py +305 -0
- gbase8sdb-1.0.0/src/gbase8sdb/exceptions.py +41 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/bind_var.pyx +87 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/connection.pyx +413 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/constants.pxi +3979 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/conversions.pyx +92 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/cursor.pyx +613 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/defaults.pyx +16 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/exceptions.pyx +21 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/lob.pyx +178 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/lob_struct.pyx +136 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/message.pyx +1006 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/packet.pyx +491 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/protocol.pyx +281 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/protocol_header.pxi +191 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/sqli.pyx +1186 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/sqli_trace.pyx +40 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/sqltype.pyx +939 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/transport.pyx +66 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/types.pyx +191 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/utils.pyx +224 -0
- gbase8sdb-1.0.0/src/gbase8sdb/impl/var.pyx +138 -0
- gbase8sdb-1.0.0/src/gbase8sdb/lob.py +80 -0
- gbase8sdb-1.0.0/src/gbase8sdb/lob_async.py +60 -0
- gbase8sdb-1.0.0/src/gbase8sdb/pool.py +166 -0
- gbase8sdb-1.0.0/src/gbase8sdb/pool_async.py +169 -0
- gbase8sdb-1.0.0/src/gbase8sdb/utils.py +16 -0
- gbase8sdb-1.0.0/src/gbase8sdb/utils_async.py +12 -0
- gbase8sdb-1.0.0/src/gbase8sdb/var.py +51 -0
- gbase8sdb-1.0.0/src/gbase8sdb/version.py +7 -0
- gbase8sdb-1.0.0/src/gbase8sdb.egg-info/PKG-INFO +74 -0
- gbase8sdb-1.0.0/src/gbase8sdb.egg-info/SOURCES.txt +53 -0
- gbase8sdb-1.0.0/src/gbase8sdb.egg-info/dependency_links.txt +1 -0
- gbase8sdb-1.0.0/src/gbase8sdb.egg-info/not-zip-safe +1 -0
- gbase8sdb-1.0.0/src/gbase8sdb.egg-info/requires.txt +1 -0
- gbase8sdb-1.0.0/src/gbase8sdb.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (C) 2025 GBASE Technologies Co.,Ltd.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
gbase8sdb-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: gbase8sdb
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Python interface to GBase 8s Database
|
|
5
|
+
Home-page: UNKNOWN
|
|
6
|
+
License: UNKNOWN
|
|
7
|
+
Keywords: GBase 8s,database
|
|
8
|
+
Platform: UNKNOWN
|
|
9
|
+
Classifier: Programming Language :: Python
|
|
10
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
11
|
+
Classifier: Programming Language :: Cython
|
|
12
|
+
Classifier: Topic :: Database
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE.txt
|
|
15
|
+
|
|
16
|
+
# python-gbase8sdb
|
|
17
|
+
|
|
18
|
+
python-gbase8sdb 是一个 [Python 编程语言][python] 扩展模块,允许 Python 程序连接到 GBase 8s 数据库。
|
|
19
|
+
|
|
20
|
+
该模块符合 [Python 数据库 API 2.0 规范][pep249],并且包含大量扩展和少数排除项。
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## 安装
|
|
24
|
+
|
|
25
|
+
运行 `python -m pip install gbase8sdb` 安装。
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## 依赖和互操作性
|
|
29
|
+
|
|
30
|
+
- 支持的 GBase 8s 数据库版本:GBase 8s V8.8_3.6.2版本及以上。
|
|
31
|
+
|
|
32
|
+
- 支持的操作系统:Linux x86_64、 Linux AArch64、 Windows 64位操作系统 。
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
#### 使用说明
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
#### 入门
|
|
39
|
+
在您的Python应用程序中,可以通过以下方式连接到数据库:
|
|
40
|
+
```python
|
|
41
|
+
import gbase8sdb
|
|
42
|
+
|
|
43
|
+
# 生成数据库连接字符串
|
|
44
|
+
dsn = gbase8sdb.makedsn(
|
|
45
|
+
db_name="testdbutf8", # 数据库名称,如果不连库,设置为None
|
|
46
|
+
host="192.168.xxx.xxx", # 数据库实例所在服务器的IP地址或域名,连接组时不需要提供此参数
|
|
47
|
+
port=9088, # 数据库实例的端口号,连接组时不需要提供此参数
|
|
48
|
+
db_locale='zh_CN.utf8', # 数据库字符集, 缺省值为utf8
|
|
49
|
+
sqlmode='oracle', # 数据库模式, 缺省值为oracle
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
user = "gbasedbt" # 数据库用户名
|
|
53
|
+
password = "xxxxxx" # 数据库用户密码
|
|
54
|
+
|
|
55
|
+
# 连接数据库
|
|
56
|
+
conn = gbase8sdb.connect(dsn, user, password)
|
|
57
|
+
# 创建游标
|
|
58
|
+
cursor = conn.cursor()
|
|
59
|
+
# 执行SQL语句
|
|
60
|
+
cursor.execute("drop table if exists t")
|
|
61
|
+
cursor.execute("create table t (id int, name varchar(20))")
|
|
62
|
+
cursor.execute("insert into t values (?, ?)", (1, "zhangsan")) # sqlmode=mysql时使用%s作为占位符
|
|
63
|
+
# 提交事务
|
|
64
|
+
conn.commit()
|
|
65
|
+
cursor.execute("select * from t")
|
|
66
|
+
# 获取查询结果
|
|
67
|
+
print(cursor.fetchall())
|
|
68
|
+
# 关闭游标和连接
|
|
69
|
+
cursor.close()
|
|
70
|
+
conn.close()
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# python-gbase8sdb
|
|
2
|
+
|
|
3
|
+
python-gbase8sdb 是一个 [Python 编程语言][python] 扩展模块,允许 Python 程序连接到 GBase 8s 数据库。
|
|
4
|
+
|
|
5
|
+
该模块符合 [Python 数据库 API 2.0 规范][pep249],并且包含大量扩展和少数排除项。
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## 安装
|
|
9
|
+
|
|
10
|
+
运行 `python -m pip install gbase8sdb` 安装。
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## 依赖和互操作性
|
|
14
|
+
|
|
15
|
+
- 支持的 GBase 8s 数据库版本:GBase 8s V8.8_3.6.2版本及以上。
|
|
16
|
+
|
|
17
|
+
- 支持的操作系统:Linux x86_64、 Linux AArch64、 Windows 64位操作系统 。
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
#### 使用说明
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
#### 入门
|
|
24
|
+
在您的Python应用程序中,可以通过以下方式连接到数据库:
|
|
25
|
+
```python
|
|
26
|
+
import gbase8sdb
|
|
27
|
+
|
|
28
|
+
# 生成数据库连接字符串
|
|
29
|
+
dsn = gbase8sdb.makedsn(
|
|
30
|
+
db_name="testdbutf8", # 数据库名称,如果不连库,设置为None
|
|
31
|
+
host="192.168.xxx.xxx", # 数据库实例所在服务器的IP地址或域名,连接组时不需要提供此参数
|
|
32
|
+
port=9088, # 数据库实例的端口号,连接组时不需要提供此参数
|
|
33
|
+
db_locale='zh_CN.utf8', # 数据库字符集, 缺省值为utf8
|
|
34
|
+
sqlmode='oracle', # 数据库模式, 缺省值为oracle
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
user = "gbasedbt" # 数据库用户名
|
|
38
|
+
password = "xxxxxx" # 数据库用户密码
|
|
39
|
+
|
|
40
|
+
# 连接数据库
|
|
41
|
+
conn = gbase8sdb.connect(dsn, user, password)
|
|
42
|
+
# 创建游标
|
|
43
|
+
cursor = conn.cursor()
|
|
44
|
+
# 执行SQL语句
|
|
45
|
+
cursor.execute("drop table if exists t")
|
|
46
|
+
cursor.execute("create table t (id int, name varchar(20))")
|
|
47
|
+
cursor.execute("insert into t values (?, ?)", (1, "zhangsan")) # sqlmode=mysql时使用%s作为占位符
|
|
48
|
+
# 提交事务
|
|
49
|
+
conn.commit()
|
|
50
|
+
cursor.execute("select * from t")
|
|
51
|
+
# 获取查询结果
|
|
52
|
+
print(cursor.fetchall())
|
|
53
|
+
# 关闭游标和连接
|
|
54
|
+
cursor.close()
|
|
55
|
+
conn.close()
|
|
56
|
+
```
|
|
57
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[metadata]
|
|
2
|
+
name = gbase8sdb
|
|
3
|
+
description = Python interface to GBase 8s Database
|
|
4
|
+
long_description = file: README.md
|
|
5
|
+
long_description_content_type = text/markdown
|
|
6
|
+
keywords = GBase 8s, database
|
|
7
|
+
classifiers =
|
|
8
|
+
Programming Language :: Python
|
|
9
|
+
Programming Language :: Python :: Implementation :: CPython
|
|
10
|
+
Programming Language :: Cython
|
|
11
|
+
Topic :: Database
|
|
12
|
+
|
|
13
|
+
[options]
|
|
14
|
+
zip_safe = false
|
|
15
|
+
install_requires = six
|
|
16
|
+
packages = find:
|
|
17
|
+
package_dir =
|
|
18
|
+
=src
|
|
19
|
+
|
|
20
|
+
[options.packages.find]
|
|
21
|
+
where = src
|
|
22
|
+
|
|
23
|
+
[egg_info]
|
|
24
|
+
tag_build =
|
|
25
|
+
tag_date = 0
|
|
26
|
+
|
gbase8sdb-1.0.0/setup.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
from setuptools import setup, Extension
|
|
5
|
+
|
|
6
|
+
gdb_debug = False
|
|
7
|
+
source_dir = "src/gbase8sdb"
|
|
8
|
+
sys.path.append(source_dir)
|
|
9
|
+
|
|
10
|
+
import version
|
|
11
|
+
|
|
12
|
+
# driver
|
|
13
|
+
driver_dir = os.path.join(source_dir, "impl")
|
|
14
|
+
driver_depends = []
|
|
15
|
+
for f in os.listdir(driver_dir):
|
|
16
|
+
if f.endswith((".pyx", "pxd", "pxi")):
|
|
17
|
+
driver_depends.append(os.path.join(driver_dir, f))
|
|
18
|
+
driver_pxd = os.path.join(source_dir, "driver.pxd")
|
|
19
|
+
driver_depends.append(driver_pxd)
|
|
20
|
+
|
|
21
|
+
ext_modules = [
|
|
22
|
+
Extension(
|
|
23
|
+
"gbase8sdb.driver",
|
|
24
|
+
sources=[os.path.join(source_dir, "driver.pyx")],
|
|
25
|
+
depends=driver_depends,
|
|
26
|
+
extra_compile_args=["-std=c99", "-g0"],
|
|
27
|
+
),
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
is_sdist = "sdist" in sys.argv
|
|
31
|
+
if not is_sdist:
|
|
32
|
+
from Cython.Build import cythonize
|
|
33
|
+
ext_modules = cythonize(ext_modules, gdb_debug=gdb_debug)
|
|
34
|
+
else:
|
|
35
|
+
ext_modules = ext_modules
|
|
36
|
+
setup(
|
|
37
|
+
version=version.__version__,
|
|
38
|
+
ext_modules=ext_modules,
|
|
39
|
+
)
|
|
40
|
+
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
"""
|
|
3
|
+
the package of gbase8sdb __init__ module
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import sys, os
|
|
7
|
+
import collections
|
|
8
|
+
|
|
9
|
+
apilevel = "2.0"
|
|
10
|
+
paramstyle = "qmark"
|
|
11
|
+
threadsafety = 2
|
|
12
|
+
|
|
13
|
+
# version info
|
|
14
|
+
from .version import __version__
|
|
15
|
+
version = __version__
|
|
16
|
+
|
|
17
|
+
from . import driver
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
from .driver import (
|
|
21
|
+
DB_TYPE_BINARY_DOUBLE,
|
|
22
|
+
DB_TYPE_BINARY_FLOAT,
|
|
23
|
+
DB_TYPE_BINARY_INTEGER,
|
|
24
|
+
DB_TYPE_BLOB,
|
|
25
|
+
DB_TYPE_CHAR,
|
|
26
|
+
DB_TYPE_CLOB,
|
|
27
|
+
DB_TYPE_CURSOR,
|
|
28
|
+
DB_TYPE_DATE,
|
|
29
|
+
DB_TYPE_INTERVAL_DS,
|
|
30
|
+
DB_TYPE_INTERVAL_YM,
|
|
31
|
+
DB_TYPE_LONG_NVARCHAR,
|
|
32
|
+
DB_TYPE_LVARCHAR,
|
|
33
|
+
DB_TYPE_NCHAR,
|
|
34
|
+
DB_TYPE_NCLOB,
|
|
35
|
+
DB_TYPE_NUMBER,
|
|
36
|
+
DB_TYPE_NVARCHAR,
|
|
37
|
+
DB_TYPE_TIMESTAMP,
|
|
38
|
+
DB_TYPE_TIMESTAMP_TZ,
|
|
39
|
+
DB_TYPE_VARCHAR,
|
|
40
|
+
DB_TYPE_BYTE,
|
|
41
|
+
DB_TYPE_TEXT,
|
|
42
|
+
DB_TYPE_BOOLEAN,
|
|
43
|
+
DB_TYPE_LONG,
|
|
44
|
+
DB_TYPE_RAW,
|
|
45
|
+
DB_TYPE_JSON,
|
|
46
|
+
DB_TYPE_CLOB2,
|
|
47
|
+
# DB API
|
|
48
|
+
BINARY,
|
|
49
|
+
DATETIME,
|
|
50
|
+
NUMBER,
|
|
51
|
+
ROWID,
|
|
52
|
+
STRING,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
from .exceptions import (
|
|
56
|
+
Warning as Warning,
|
|
57
|
+
Error as Error,
|
|
58
|
+
DatabaseError as DatabaseError,
|
|
59
|
+
DataError as DataError,
|
|
60
|
+
IntegrityError as IntegrityError,
|
|
61
|
+
InterfaceError as InterfaceError,
|
|
62
|
+
InternalError as InternalError,
|
|
63
|
+
NotSupportedError as NotSupportedError,
|
|
64
|
+
OperationalError as OperationalError,
|
|
65
|
+
ProgrammingError as ProgrammingError,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
from .defaults import defaults
|
|
69
|
+
|
|
70
|
+
from .connection import connect, Connection
|
|
71
|
+
|
|
72
|
+
from .cursor import Cursor
|
|
73
|
+
|
|
74
|
+
from .lob import LOB
|
|
75
|
+
|
|
76
|
+
from .pool import create_pool
|
|
77
|
+
|
|
78
|
+
if sys.version_info >= (3, 5):
|
|
79
|
+
from .connection_async import connect_async, AsyncConnection
|
|
80
|
+
from .cursor_async import AsyncCursor
|
|
81
|
+
from .lob_async import AsyncLOB
|
|
82
|
+
from .pool_async import create_pool_async
|
|
83
|
+
|
|
84
|
+
from .column_metadata import ColumnMetaData
|
|
85
|
+
|
|
86
|
+
from .var import Var
|
|
87
|
+
|
|
88
|
+
from .dsn import makedsn
|
|
89
|
+
|
|
90
|
+
from .constructors import (
|
|
91
|
+
Binary as Binary,
|
|
92
|
+
Date as Date,
|
|
93
|
+
DateFromTicks as DateFromTicks,
|
|
94
|
+
Time as Time,
|
|
95
|
+
TimeFromTicks as TimeFromTicks,
|
|
96
|
+
Timestamp as Timestamp,
|
|
97
|
+
TimestampFromTicks as TimestampFromTicks,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
IntervalYM = collections.namedtuple("IntervalYM", ["years", "months"])
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
package = sys.modules[__name__]
|
|
105
|
+
driver.init_driver(package)
|
|
106
|
+
|
|
107
|
+
del package
|
|
108
|
+
del sys
|
|
109
|
+
del driver, connection, constructors
|
|
110
|
+
del cursor, dsn, exceptions, column_metadata
|
|
111
|
+
del lob
|
|
112
|
+
del var
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
from . import __name__ as MODULE_NAME
|
|
3
|
+
|
|
4
|
+
from .driver import (
|
|
5
|
+
DbType,
|
|
6
|
+
DB_TYPE_NUMBER,
|
|
7
|
+
DB_TYPE_BINARY_INTEGER,
|
|
8
|
+
DB_TYPE_BINARY_DOUBLE,
|
|
9
|
+
DB_TYPE_BINARY_FLOAT,
|
|
10
|
+
DB_TYPE_TIMESTAMP_TZ,
|
|
11
|
+
DB_TYPE_TIMESTAMP_LTZ,
|
|
12
|
+
DB_TYPE_TIMESTAMP,
|
|
13
|
+
DB_TYPE_DATE,
|
|
14
|
+
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ColumnMetaData(object):
|
|
19
|
+
|
|
20
|
+
__module__ = MODULE_NAME
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def __str__(self):
|
|
24
|
+
return str(tuple(self))
|
|
25
|
+
|
|
26
|
+
def __repr__(self):
|
|
27
|
+
return repr(tuple(self))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def __len__(self):
|
|
31
|
+
return 7
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def __eq__(self, other):
|
|
35
|
+
return tuple(self) == other
|
|
36
|
+
|
|
37
|
+
def __getitem__(self, index):
|
|
38
|
+
description = (
|
|
39
|
+
self.name,
|
|
40
|
+
self.type_code,
|
|
41
|
+
self.display_size,
|
|
42
|
+
self.internal_size,
|
|
43
|
+
self.precision,
|
|
44
|
+
self.scale,
|
|
45
|
+
self.null_ok,
|
|
46
|
+
)
|
|
47
|
+
return description[index]
|
|
48
|
+
|
|
49
|
+
@classmethod
|
|
50
|
+
def _create_with_cyobj(cls, cyobj):
|
|
51
|
+
info = cls.__new__(cls)
|
|
52
|
+
info._type = None
|
|
53
|
+
info._cyobj = cyobj
|
|
54
|
+
return info
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def _is_date_type(dbtype):
|
|
58
|
+
return dbtype in {DB_TYPE_DATE, DB_TYPE_TIMESTAMP, DB_TYPE_TIMESTAMP_LTZ, DB_TYPE_TIMESTAMP_TZ}
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def _is_numeric_type(dbtype):
|
|
62
|
+
return dbtype in {DB_TYPE_BINARY_FLOAT, DB_TYPE_BINARY_DOUBLE, DB_TYPE_BINARY_INTEGER, DB_TYPE_NUMBER}
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def internal_size(self):
|
|
66
|
+
if self._cyobj.size > 0:
|
|
67
|
+
return self._cyobj.buffer_size
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def name(self):
|
|
71
|
+
return self._cyobj.name
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def precision(self):
|
|
75
|
+
if self._cyobj.precision or self._cyobj.scale:
|
|
76
|
+
return self._cyobj.precision
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def type(self):
|
|
80
|
+
if self._type is None:
|
|
81
|
+
self._type = self._cyobj.dbtype
|
|
82
|
+
return self._type
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def type_code(self):
|
|
86
|
+
return self._cyobj.dbtype
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def display_size(self):
|
|
90
|
+
if self._cyobj.size > 0:
|
|
91
|
+
return self._cyobj.size
|
|
92
|
+
dbtype = self._cyobj.dbtype
|
|
93
|
+
if self._is_numeric_type(dbtype):
|
|
94
|
+
if self._cyobj.precision:
|
|
95
|
+
display_size = self._cyobj.precision + 1
|
|
96
|
+
if self._cyobj.scale > 0:
|
|
97
|
+
display_size += self._cyobj.scale + 1
|
|
98
|
+
else:
|
|
99
|
+
display_size = 127
|
|
100
|
+
return display_size
|
|
101
|
+
elif self._is_date_type(dbtype):
|
|
102
|
+
return 23
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def scale(self):
|
|
106
|
+
if self._cyobj.precision or self._cyobj.scale:
|
|
107
|
+
return self._cyobj.scale
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def null_ok(self):
|
|
111
|
+
return self._cyobj.nulls_allowed
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
import re, os, sys
|
|
3
|
+
from . import __name__ as MODULE_NAME
|
|
4
|
+
from . import errors
|
|
5
|
+
from .import driver
|
|
6
|
+
from .cursor import Cursor
|
|
7
|
+
from .lob import LOB
|
|
8
|
+
from .driver import DB_TYPE_BLOB, DB_TYPE_CLOB, DB_TYPE_NCLOB, DB_TYPE_LONG
|
|
9
|
+
|
|
10
|
+
locale_mapping = {
|
|
11
|
+
"zh_cn.57372": "utf8",
|
|
12
|
+
"zh_cn.utf8": "utf8",
|
|
13
|
+
"zh_cn.utf-8": "utf8",
|
|
14
|
+
"zh_cn.5488": "gb18030",
|
|
15
|
+
"zh_cn.gb18030": "gb18030",
|
|
16
|
+
"zh_cn.gb18030-2000": "gb18030",
|
|
17
|
+
"zh_cn.5510": "gb18030",
|
|
18
|
+
"zh_cn.gb18030-2022": "gb18030",
|
|
19
|
+
"en_us.819": "utf8",
|
|
20
|
+
"8859-1": "utf8",
|
|
21
|
+
"gb": "gbk",
|
|
22
|
+
"gb2312-80": "gbk",
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
def get_client_locale(dsn_dict):
|
|
26
|
+
locale_8s = dsn_dict.get('CLIENT_LOCALE', 'zh_CN.utf8')
|
|
27
|
+
client_locale = locale_mapping.get(locale_8s.lower(), 'utf8')
|
|
28
|
+
if isinstance(client_locale, bytes):
|
|
29
|
+
client_locale = client_locale.decode()
|
|
30
|
+
return client_locale
|
|
31
|
+
|
|
32
|
+
def _convert_dsn_to_dict(dsn):
|
|
33
|
+
p_dsn = re.compile(r'^gbase8s:(([\w]+)=(.*?);)+$')
|
|
34
|
+
match = p_dsn.findall(dsn)
|
|
35
|
+
if not match:
|
|
36
|
+
errors.raise_error(errors.ERR_INVALID_DSN)
|
|
37
|
+
kv = re.findall(r'([\w]+)=(.*?);', dsn[8:])
|
|
38
|
+
params_dict = dict(kv)
|
|
39
|
+
return params_dict
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class Connection(object):
|
|
43
|
+
__module__ = MODULE_NAME
|
|
44
|
+
|
|
45
|
+
def __init__(self, dsn, user, password):
|
|
46
|
+
self._cyobj = None
|
|
47
|
+
self._version = None
|
|
48
|
+
dsn_dict = _convert_dsn_to_dict(dsn)
|
|
49
|
+
self.sqlmode = dsn_dict.get("SQLMODE", "oracle")
|
|
50
|
+
if isinstance(dsn, bytes):
|
|
51
|
+
dsn = dsn.decode()
|
|
52
|
+
if isinstance(user, bytes):
|
|
53
|
+
user = user.decode()
|
|
54
|
+
if isinstance(password, bytes):
|
|
55
|
+
password = password.decode()
|
|
56
|
+
cy_conn = driver.CyConnection(dsn, user, password)
|
|
57
|
+
cy_conn.client_locale = get_client_locale(dsn_dict)
|
|
58
|
+
cy_conn.connect()
|
|
59
|
+
self._cyobj = cy_conn
|
|
60
|
+
self._client_locale = cy_conn.client_locale
|
|
61
|
+
|
|
62
|
+
def __repr__(self):
|
|
63
|
+
if sys.version_info >= (3, 3):
|
|
64
|
+
cls_name = "{}.{}".format(self.__class__.__module__, self.__class__.__qualname__)
|
|
65
|
+
else:
|
|
66
|
+
cls_name = "{}.{}".format(self.__class__.__module__, self.__class__.__name__)
|
|
67
|
+
if self._cyobj is None:
|
|
68
|
+
return "<{} disconnected>".format(cls_name)
|
|
69
|
+
return "<{} to {}@{}>".format(cls_name, self.username, self.dsn)
|
|
70
|
+
|
|
71
|
+
def __del__(self):
|
|
72
|
+
if self._cyobj is not None:
|
|
73
|
+
self._cyobj.close(in_del=True)
|
|
74
|
+
self._cyobj = None
|
|
75
|
+
|
|
76
|
+
def __enter__(self):
|
|
77
|
+
self._verify_connected()
|
|
78
|
+
return self
|
|
79
|
+
|
|
80
|
+
def __exit__(self, exc_type, exc_value, exc_tb):
|
|
81
|
+
if self._cyobj is not None:
|
|
82
|
+
self._cyobj.close(in_del=True)
|
|
83
|
+
self._cyobj = None
|
|
84
|
+
|
|
85
|
+
def _verify_connected(self):
|
|
86
|
+
if self._cyobj is None:
|
|
87
|
+
errors.raise_error(errors.ERR_NOT_CONNECTED)
|
|
88
|
+
|
|
89
|
+
def close(self):
|
|
90
|
+
self._verify_connected()
|
|
91
|
+
self._cyobj.close()
|
|
92
|
+
self._cyobj = None
|
|
93
|
+
|
|
94
|
+
def commit(self):
|
|
95
|
+
self._verify_connected()
|
|
96
|
+
self._cyobj.commit()
|
|
97
|
+
|
|
98
|
+
def createlob(
|
|
99
|
+
self, lob_type, data = None
|
|
100
|
+
):
|
|
101
|
+
self._verify_connected()
|
|
102
|
+
if lob_type not in (DB_TYPE_CLOB, DB_TYPE_NCLOB, DB_TYPE_BLOB, DB_TYPE_LONG):
|
|
103
|
+
message = (
|
|
104
|
+
"lob type should be one of gbase8sdb.DB_TYPE_BLOB, "
|
|
105
|
+
"gbase8sdb.DB_TYPE_CLOB, gbase8sdb.DB_TYPE_NCLOB or "
|
|
106
|
+
"gbase8sdb.DB_TYPE_LONG"
|
|
107
|
+
)
|
|
108
|
+
raise TypeError(message)
|
|
109
|
+
impl = self._cyobj.create_temp_lob_impl(lob_type)
|
|
110
|
+
lob = LOB._create_with_cyobj(impl)
|
|
111
|
+
if data:
|
|
112
|
+
lob.write(data)
|
|
113
|
+
return lob
|
|
114
|
+
|
|
115
|
+
def cursor(self, scrollable=False):
|
|
116
|
+
self._verify_connected()
|
|
117
|
+
return Cursor(self, scrollable)
|
|
118
|
+
|
|
119
|
+
def ping(self):
|
|
120
|
+
self._verify_connected()
|
|
121
|
+
self._cyobj.ping()
|
|
122
|
+
|
|
123
|
+
def rollback(self):
|
|
124
|
+
self._verify_connected()
|
|
125
|
+
self._cyobj.rollback()
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def autocommit(self):
|
|
130
|
+
self._verify_connected()
|
|
131
|
+
return self._cyobj.autocommit
|
|
132
|
+
|
|
133
|
+
@autocommit.setter
|
|
134
|
+
def autocommit(self, value):
|
|
135
|
+
self._verify_connected()
|
|
136
|
+
self._cyobj.autocommit = value
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def dsn(self):
|
|
140
|
+
self._verify_connected()
|
|
141
|
+
return self._cyobj.dsn
|
|
142
|
+
|
|
143
|
+
@property
|
|
144
|
+
def inputtypehandler(self):
|
|
145
|
+
self._verify_connected()
|
|
146
|
+
return self._cyobj.inputtypehandler
|
|
147
|
+
|
|
148
|
+
@inputtypehandler.setter
|
|
149
|
+
def inputtypehandler(self, value):
|
|
150
|
+
self._verify_connected()
|
|
151
|
+
self._cyobj.inputtypehandler = value
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@property
|
|
155
|
+
def outputtypehandler(self):
|
|
156
|
+
self._verify_connected()
|
|
157
|
+
return self._cyobj.outputtypehandler
|
|
158
|
+
|
|
159
|
+
@outputtypehandler.setter
|
|
160
|
+
def outputtypehandler(self, value):
|
|
161
|
+
self._verify_connected()
|
|
162
|
+
self._cyobj.outputtypehandler = value
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def transaction_in_progress(self):
|
|
166
|
+
self._verify_connected()
|
|
167
|
+
return self._cyobj.get_transaction_in_progress()
|
|
168
|
+
|
|
169
|
+
@property
|
|
170
|
+
def username(self):
|
|
171
|
+
self._verify_connected()
|
|
172
|
+
return self._cyobj.username
|
|
173
|
+
|
|
174
|
+
@property
|
|
175
|
+
def version(self):
|
|
176
|
+
if self._version is None:
|
|
177
|
+
self._verify_connected()
|
|
178
|
+
self._version = ".".join(str(c) for c in self._cyobj.server_version)
|
|
179
|
+
return self._version
|
|
180
|
+
|
|
181
|
+
@property
|
|
182
|
+
def client_locale(self):
|
|
183
|
+
return self._client_locale
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def connect(dsn, user, password):
|
|
187
|
+
"""
|
|
188
|
+
创建数据库连接,并返回连接对象
|
|
189
|
+
"""
|
|
190
|
+
if len(dsn) == 0 or len(user) == 0 or len(password) == 0:
|
|
191
|
+
raise errors.raise_error(errors.ERR_INVALID_CONNECT_PARAMS)
|
|
192
|
+
return Connection(dsn=dsn, user=user, password=password)
|