11""" Module to interact with remote SqliteCloud database
22
33"""
4- from typing import Optional
5- from urllib import parse
4+ from typing import Dict , Optional , Tuple , Union
65
76from sqlitecloud .driver import Driver
87from sqlitecloud .resultset import SqliteCloudResultSet
98from sqlitecloud .types import (
10- SQCLOUD_DEFAULT ,
119 SQCloudConfig ,
1210 SQCloudConnect ,
1311 SQCloudException ,
1412 SqliteCloudAccount ,
13+ SQLiteCloudDataTypes ,
1514)
1615
1716
@@ -39,10 +38,11 @@ def __init__(
3938 self .config = SQCloudConfig ()
4039
4140 if connection_str :
42- self .config = self . _parse_connection_string (connection_str )
41+ self .config = SQCloudConfig (connection_str )
4342 elif cloud_account :
4443 self .config .account = cloud_account
45- else :
44+
45+ if self .config .account is None :
4646 raise SQCloudException ("Missing connection parameters" )
4747
4848 def open_connection (self ) -> SQCloudConnect :
@@ -80,7 +80,7 @@ def exec_query(self, query: str, conn: SQCloudConnect) -> SqliteCloudResultSet:
8080 """Executes a SQL query on the SQLite Cloud database.
8181
8282 Args:
83- query (str): The SQL query to be executed .
83+ query (str): The SQL query to execute .
8484
8585 Returns:
8686 SqliteCloudResultSet: The result set of the executed query.
@@ -92,6 +92,41 @@ def exec_query(self, query: str, conn: SQCloudConnect) -> SqliteCloudResultSet:
9292
9393 return SqliteCloudResultSet (result )
9494
95+ def exec_statement (
96+ self ,
97+ query : str ,
98+ parameters : Union [
99+ Tuple [SQLiteCloudDataTypes ], Dict [Union [str , int ], SQLiteCloudDataTypes ]
100+ ],
101+ conn : SQCloudConnect ,
102+ ) -> SqliteCloudResultSet :
103+ """
104+ Prepare and execute a SQL statement (either a query or command) to the SQLite Cloud database.
105+ This function supports two styles of parameter markers:
106+
107+ 1. Question Mark Style: Parameters are passed as a tuple. For example:
108+ "SELECT * FROM table WHERE id = ?"
109+
110+ 2. Named Style: Parameters are passed as a dictionary. For example:
111+ "SELECT * FROM table WHERE id = :id"
112+
113+ In both cases, the parameters replace the placeholders in the SQL statement.
114+
115+ Args:
116+ query (str): The SQL query to execute.
117+ parameters (Union[Tuple[SQLiteCloudDataTypes], Dict[Union[str, int], SQLiteCloudDataTypes]]):
118+ The parameters to be used in the query. It can be a tuple or a dictionary.
119+ conn (SQCloudConnect): The connection object to use for executing the query.
120+
121+ Returns:
122+ SqliteCloudResultSet: The result set obtained from executing the query.
123+ """
124+ prepared_statement = self ._driver .prepare_statement (query , parameters )
125+
126+ result = self ._driver .execute (prepared_statement , conn )
127+
128+ return SqliteCloudResultSet (result )
129+
95130 def sendblob (self , blob : bytes , conn : SQCloudConnect ) -> SqliteCloudResultSet :
96131 """Sends a blob to the SQLite database.
97132
@@ -100,58 +135,3 @@ def sendblob(self, blob: bytes, conn: SQCloudConnect) -> SqliteCloudResultSet:
100135 conn (SQCloudConnect): The connection to the database.
101136 """
102137 return self ._driver .send_blob (blob , conn )
103-
104- def _parse_connection_string (self , connection_string ) -> SQCloudConfig :
105- # URL STRING FORMAT
106- # sqlitecloud://user:[email protected] :port/dbname?timeout=10&key2=value2&key3=value3 107- # or sqlitecloud://host.sqlite.cloud:8860/dbname?apikey=zIiAARzKm9XBVllbAzkB1wqrgijJ3Gx0X5z1A4m4xBA
108-
109- config = SQCloudConfig ()
110- config .account = SqliteCloudAccount ()
111-
112- try :
113- params = parse .urlparse (connection_string )
114-
115- options = {}
116- query = params .query
117- options = parse .parse_qs (query )
118- for option , values in options .items ():
119- opt = option .lower ()
120- value = values .pop ()
121-
122- if value .lower () in ["true" , "false" ]:
123- value = bool (value )
124- elif value .isdigit ():
125- value = int (value )
126- else :
127- value = value
128-
129- if hasattr (config , opt ):
130- setattr (config , opt , value )
131- elif hasattr (config .account , opt ):
132- setattr (config .account , opt , value )
133-
134- # apikey or username/password is accepted
135- if not config .account .apikey :
136- config .account .username = (
137- parse .unquote (params .username ) if params .username else ""
138- )
139- config .account .password = (
140- parse .unquote (params .password ) if params .password else ""
141- )
142-
143- path = params .path
144- database = path .strip ("/" )
145- if database :
146- config .account .dbname = database
147-
148- config .account .hostname = params .hostname
149- config .account .port = (
150- int (params .port ) if params .port else SQCLOUD_DEFAULT .PORT .value
151- )
152-
153- return config
154- except Exception as e :
155- raise SQCloudException (
156- f"Invalid connection string { connection_string } "
157- ) from e
0 commit comments