Skip to content

Commit 2bb2823

Browse files
authored
Merge pull request #20 from zhanghaitao3/master
Supplementary example
2 parents 41d9b2c + 54dcd44 commit 2bb2823

File tree

5 files changed

+200
-6
lines changed

5 files changed

+200
-6
lines changed

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,4 @@ This library includes enhanced support for GaussDB and openGauss databases:
107107
asyncio.run(run())
108108
109109
async-gaussdb is developed and distributed under the Apache 2.0 license
110-
by MagicStack Inc. and the HuaweiCloudDeveloper team.
110+
by MagicStack Inc. and the HuaweiCloudDeveloper team.

async_gaussdb/gaussdbproto/types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def from_int(cls: typing.Type[_BitString], x: int, length: int,
208208
def __repr__(self) -> str:
209209
return '<BitString {}>'.format(self.as_string())
210210

211-
__str__: typing.Callable[['BitString'], str] = __repr__
211+
__str__ = __repr__
212212

213213
def __eq__(self, other: object) -> bool:
214214
if not isinstance(other, BitString):

examples/demo.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
2+
import asyncio
3+
import async_gaussdb
4+
# -----------------------------------------------------------------------------
5+
# Database Connection Configuration
6+
# -----------------------------------------------------------------------------
7+
DB_CONFIG = {
8+
'user': 'root',
9+
'password': 'password', # Replace with your actual password
10+
'database': 'postgres',
11+
'host': '127.0.0.1',
12+
'port': 8000
13+
}
14+
15+
async def main():
16+
print(f"Connecting to GaussDB at {DB_CONFIG['host']}:{DB_CONFIG['port']}...")
17+
18+
# 1. Establish Connection
19+
# async_gaussdb automatically handles openGauss/GaussDB specific protocols (e.g., SHA256 auth)
20+
conn = await async_gaussdb.connect(**DB_CONFIG)
21+
print("✅ Connection established successfully!")
22+
23+
try:
24+
# ---------------------------------------------------------------------
25+
# Step 1: Clean up old data (Drop Table)
26+
# ---------------------------------------------------------------------
27+
drop_table_sql = "DROP TABLE IF EXISTS test"
28+
print(f"\n[Executing] {drop_table_sql}")
29+
await conn.execute(drop_table_sql)
30+
print(" -> Table 'test' dropped.")
31+
32+
# ---------------------------------------------------------------------
33+
# Step 2: Create new table (Create Table)
34+
# ---------------------------------------------------------------------
35+
create_table_sql = (
36+
"CREATE TABLE test (id serial PRIMARY KEY, num integer, data text)"
37+
)
38+
print(f"\n[Executing] {create_table_sql}")
39+
await conn.execute(create_table_sql)
40+
print(" -> Table 'test' created.")
41+
42+
# ---------------------------------------------------------------------
43+
# Step 3: Insert Data
44+
# Note: Async drivers for Postgres/GaussDB typically use $1, $2 placeholders
45+
# instead of %s used in standard synchronous drivers.
46+
# ---------------------------------------------------------------------
47+
insert_data_sql = "INSERT INTO test (num, data) VALUES ($1, $2)"
48+
49+
# Preparing sample data
50+
data_to_insert = [
51+
(1, 'initial_data'),
52+
(2, 'data_to_be_updated'), # This row (num=2) will be updated later
53+
(3, 'other_data')
54+
]
55+
56+
print(f"\n[Executing] {insert_data_sql}")
57+
for num, data in data_to_insert:
58+
await conn.execute(insert_data_sql, num, data)
59+
print(f" -> Inserted row: num={num}, data='{data}'")
60+
61+
# ---------------------------------------------------------------------
62+
# Step 4: Update Data
63+
# ---------------------------------------------------------------------
64+
update_data_sql = "UPDATE test SET data = 'gaussdb' WHERE num = 2"
65+
print(f"\n[Executing] {update_data_sql}")
66+
result = await conn.execute(update_data_sql)
67+
# 'result' usually contains the command tag (e.g., "UPDATE 1")
68+
print(f" -> Update complete: {result}")
69+
70+
# ---------------------------------------------------------------------
71+
# Step 5: Select and Verify Data
72+
# ---------------------------------------------------------------------
73+
select_sql = "SELECT * FROM test ORDER BY id"
74+
print(f"\n[Executing] {select_sql}")
75+
76+
# fetch() returns a list of Record objects
77+
rows = await conn.fetch(select_sql)
78+
79+
print("\n--- Query Results ---")
80+
for row in rows:
81+
# Access data by column name or index
82+
print(f"ID: {row['id']} | Num: {row['num']} | Data: {row['data']}")
83+
84+
except Exception as e:
85+
print(f"\n❌ An error occurred: {e}")
86+
finally:
87+
# ---------------------------------------------------------------------
88+
# Close Connection
89+
# ---------------------------------------------------------------------
90+
print("\nClosing connection...")
91+
await conn.close()
92+
print("✅ Connection closed.")
93+
94+
if __name__ == "__main__":
95+
asyncio.run(main())

examples/ssl_demo.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
2+
import asyncio
3+
import async_gaussdb
4+
import os
5+
6+
# -----------------------------------------------------------------------------
7+
# Scenario: Configuring SSL using DSN (Data Source Name)
8+
# This method is simpler than creating a raw ssl.SSLContext and mimics
9+
# standard PostgreSQL connection strings.
10+
# -----------------------------------------------------------------------------
11+
12+
# Path to your server's CA certificate.
13+
# If 'sslrootcert' is not provided, the driver defaults to looking at:
14+
# ~/.postgresql/root.crt (Linux/Mac) or %APPDATA%\postgresql\root.crt (Windows)
15+
CERTS = os.path.join(os.path.dirname(__file__), '../tests/certs')
16+
SSL_CERT_FILE = os.path.join(CERTS, 'server.cert.pem')
17+
async def main():
18+
# -------------------------------------------------------------------------
19+
# Constructing the DSN Connection String
20+
# Format: gaussdb://user:password@host:port/database?param=value
21+
#
22+
# Key Parameters:
23+
# 1. sslmode=verify-ca -> Verifies the server's certificate signature.
24+
# (Use 'verify-full' to also verify the hostname)
25+
# 2. sslrootcert=... -> Explicitly tells the driver where the CA file is.
26+
# -------------------------------------------------------------------------
27+
28+
dsn = (
29+
f"gaussdb://testuser:Test%40123@127.0.0.1:5432/postgres"
30+
f"?sslmode=verify-ca&sslrootcert={SSL_CERT_FILE}"
31+
)
32+
33+
print(f"Connecting via DSN: ...sslmode=verify-ca&sslrootcert={os.path.basename(SSL_CERT_FILE)}")
34+
35+
try:
36+
# Connect to the database
37+
# We do not need to pass a 'ssl=' context object here because the DSN
38+
# contains all the necessary configuration.
39+
conn = await async_gaussdb.connect(dsn)
40+
41+
print("SSL Connection Successful (via sslmode)!")
42+
print(f" Encryption Status: {conn._protocol.is_ssl}")
43+
44+
# ---------------------------------------------------------------------
45+
# Core Tasks (Drop -> Create -> Insert -> Update -> Select)
46+
# ---------------------------------------------------------------------
47+
48+
# 1. Clean up old data
49+
drop_table_sql = "DROP TABLE IF EXISTS test"
50+
print(f"\n[Executing] {drop_table_sql}")
51+
await conn.execute(drop_table_sql)
52+
53+
# 2. Create new table
54+
create_table_sql = (
55+
"CREATE TABLE test (id serial PRIMARY KEY, num integer, data text)"
56+
)
57+
print(f"\n[Executing] {create_table_sql}")
58+
await conn.execute(create_table_sql)
59+
60+
# 3. Insert Data (Using $1, $2 placeholders for async driver)
61+
insert_data_sql = "INSERT INTO test (num, data) VALUES ($1, $2)"
62+
print(f"\n[Executing] {insert_data_sql}")
63+
64+
await conn.execute(insert_data_sql, 1, "sslmode_demo")
65+
await conn.execute(insert_data_sql, 2, "wait_for_update") # num=2 will be updated
66+
print(" -> Inserted 2 rows.")
67+
68+
# 4. Update Data
69+
update_data_sql = "UPDATE test SET data = 'gaussdb' WHERE num = 2"
70+
print(f"\n[Executing] {update_data_sql}")
71+
await conn.execute(update_data_sql)
72+
print(" -> Update complete.")
73+
74+
# 5. Select and Verify
75+
select_sql = "SELECT * FROM test ORDER BY id"
76+
print(f"\n[Executing] {select_sql}")
77+
rows = await conn.fetch(select_sql)
78+
79+
print("\n--- Query Results ---")
80+
for row in rows:
81+
print(f"ID: {row['id']} | Num: {row['num']} | Data: {row['data']}")
82+
83+
except Exception as e:
84+
print(f"\nERROR Connection or Execution Failed: {e}")
85+
print(" Hint: Check if 'server.crt' exists and if the server supports SSL.")
86+
87+
finally:
88+
if 'conn' in locals():
89+
print("\nClosing connection...")
90+
await conn.close()
91+
print("✅ Connection closed.")
92+
93+
if __name__ == "__main__":
94+
# Check for file existence just for this tutorial to be helpful
95+
if not os.path.exists(SSL_CERT_FILE):
96+
print(f"⚠️ WARNING: The certificate file was not found at: {SSL_CERT_FILE}")
97+
print(" (The code will attempt to connect, but will likely fail)")
98+
99+
asyncio.run(main())

tests/test_pool.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -721,14 +721,14 @@ async def test_pool_max_inactive_time_05(self):
721721
# the max inactive lifetime.
722722
async with self.create_pool(
723723
database='postgres', min_size=2, max_size=2,
724-
max_inactive_connection_lifetime=0.3) as pool:
724+
max_inactive_connection_lifetime=0.5) as pool:
725725

726-
await asyncio.sleep(0.02)
726+
await asyncio.sleep(0.1)
727727
self.assertIsNotNone(pool._holders[0]._con)
728728
self.assertIsNotNone(pool._holders[1]._con)
729729

730-
await pool.execute('SELECT pg_sleep(0.3)')
731-
await asyncio.sleep(0.3)
730+
await pool.execute('SELECT pg_sleep(0.5)')
731+
await asyncio.sleep(0.5)
732732

733733
self.assertIs(pool._holders[0]._con, None)
734734
# The connection in the second holder was never used,

0 commit comments

Comments
 (0)