@@ -146,7 +146,8 @@ def get_exposed_url_endpoints(self):
146146 'sqleditor.get_new_connection_user' ,
147147 'sqleditor._check_server_connection_status' ,
148148 'sqleditor.get_new_connection_role' ,
149- 'sqleditor.connect_server'
149+ 'sqleditor.connect_server' ,
150+ 'sqleditor.server_cursor' ,
150151 ]
151152
152153 def on_logout (self ):
@@ -203,9 +204,14 @@ def initialize_viewdata(trans_id, cmd_type, obj_type, sgid, sid, did, obj_id):
203204 """
204205
205206 if request .data :
206- filter_sql = json .loads (request .data )
207+ _data = json .loads (request .data )
207208 else :
208- filter_sql = request .args or request .form
209+ _data = request .args or request .form
210+
211+ filter_sql = _data ['filter_sql' ] if 'filter_sql' in _data else None
212+ server_cursor = _data ['server_cursor' ] if \
213+ 'server_cursor' in _data and (_data ['server_cursor' ] == 'true' or
214+ _data ['server_cursor' ] is True ) else False
209215
210216 # Create asynchronous connection using random connection id.
211217 conn_id = str (secrets .choice (range (1 , 9999999 )))
@@ -242,8 +248,9 @@ def initialize_viewdata(trans_id, cmd_type, obj_type, sgid, sid, did, obj_id):
242248 command_obj = ObjectRegistry .get_object (
243249 obj_type , conn_id = conn_id , sgid = sgid , sid = sid ,
244250 did = did , obj_id = obj_id , cmd_type = cmd_type ,
245- sql_filter = filter_sql
251+ sql_filter = filter_sql , server_cursor = server_cursor
246252 )
253+
247254 except ObjectGone :
248255 raise
249256 except Exception as e :
@@ -354,6 +361,8 @@ def panel(trans_id):
354361 if 'database_name' in params :
355362 params ['database_name' ] = (
356363 underscore_escape (params ['database_name' ]))
364+ params ['server_cursor' ] = params [
365+ 'server_cursor' ] if 'server_cursor' in params else False
357366
358367 return render_template (
359368 "sqleditor/index.html" ,
@@ -485,6 +494,8 @@ def _init_sqleditor(trans_id, connect, sgid, sid, did, dbname=None, **kwargs):
485494 kwargs ['auto_commit' ] = pref .preference ('auto_commit' ).get ()
486495 if kwargs .get ('auto_rollback' , None ) is None :
487496 kwargs ['auto_rollback' ] = pref .preference ('auto_rollback' ).get ()
497+ if kwargs .get ('server_cursor' , None ) is None :
498+ kwargs ['server_cursor' ] = pref .preference ('server_cursor' ).get ()
488499
489500 try :
490501 conn = manager .connection (conn_id = conn_id ,
@@ -544,6 +555,7 @@ def _init_sqleditor(trans_id, connect, sgid, sid, did, dbname=None, **kwargs):
544555 # Set the value of auto commit and auto rollback specified in Preferences
545556 command_obj .set_auto_commit (kwargs ['auto_commit' ])
546557 command_obj .set_auto_rollback (kwargs ['auto_rollback' ])
558+ command_obj .set_server_cursor (kwargs ['server_cursor' ])
547559
548560 # Set the value of database name, that will be used later
549561 command_obj .dbname = dbname if dbname else None
@@ -909,8 +921,13 @@ def start_view_data(trans_id):
909921
910922 update_session_grid_transaction (trans_id , session_obj )
911923
924+ if trans_obj .server_cursor :
925+ conn .execute_void ("BEGIN;" )
926+
912927 # Execute sql asynchronously
913- status , result = conn .execute_async (sql )
928+ status , result = conn .execute_async (
929+ sql ,
930+ server_cursor = trans_obj .server_cursor )
914931 else :
915932 status = False
916933 result = error_msg
@@ -947,6 +964,7 @@ def start_query_tool(trans_id):
947964 )
948965
949966 connect = 'connect' in request .args and request .args ['connect' ] == '1'
967+
950968 is_error , errmsg = check_and_upgrade_to_qt (trans_id , connect )
951969 if is_error :
952970 return make_json_response (success = 0 , errormsg = errmsg ,
@@ -1209,6 +1227,7 @@ def poll(trans_id):
12091227 'transaction_status' : transaction_status ,
12101228 'data_obj' : data_obj ,
12111229 'pagination' : pagination ,
1230+ 'server_cursor' : trans_obj .server_cursor ,
12121231 }
12131232 )
12141233
@@ -1466,6 +1485,9 @@ def save(trans_id):
14661485 session_obj ['columns_info' ],
14671486 session_obj ['client_primary_key' ],
14681487 conn )
1488+ # trans_obj.set_thread_native_id(None)
1489+ # session_obj['command_obj'] = pickle.dumps(trans_obj, -1)
1490+ # update_session_grid_transaction(trans_id, session_obj)
14691491 else :
14701492 status = False
14711493 res = error_msg
@@ -1825,6 +1847,11 @@ def check_and_upgrade_to_qt(trans_id, connect):
18251847
18261848 if 'gridData' in session and str (trans_id ) in session ['gridData' ]:
18271849 data = pickle .loads (session ['gridData' ][str (trans_id )]['command_obj' ])
1850+ session ['gridData' ][str (trans_id )] = {
1851+ # -1 specify the highest protocol version available
1852+ 'command_obj' : pickle .dumps (data , - 1 )
1853+ }
1854+
18281855 if data .object_type in ['table' , 'foreign_table' , 'view' , 'mview' ]:
18291856 manager = get_driver (PG_DEFAULT_DRIVER ).connection_manager (
18301857 data .sid )
@@ -1837,27 +1864,17 @@ def check_and_upgrade_to_qt(trans_id, connect):
18371864 'conn_id' : data .conn_id
18381865 }
18391866 is_error , errmsg , _ , _ = _init_sqleditor (
1840- trans_id , connect , data .sgid , data .sid , data .did , ** kwargs )
1867+ trans_id , connect , data .sgid , data .sid , data .did ,
1868+ ** kwargs )
18411869
18421870 return is_error , errmsg
18431871
18441872
1845- @blueprint .route (
1846- '/auto_commit/<int:trans_id>' ,
1847- methods = ["PUT" , "POST" ], endpoint = 'auto_commit'
1848- )
1849- @pga_login_required
1850- def set_auto_commit (trans_id ):
1851- """
1852- This method is used to set the value for auto commit .
1853-
1854- Args:
1855- trans_id: unique transaction id
1856- """
1873+ def set_pref_options (trans_id , operation ):
18571874 if request .data :
1858- auto_commit = json .loads (request .data )
1875+ _data = json .loads (request .data )
18591876 else :
1860- auto_commit = request .args or request .form
1877+ _data = request .args or request .form
18611878
18621879 connect = 'connect' in request .args and request .args ['connect' ] == '1'
18631880
@@ -1877,12 +1894,17 @@ def set_auto_commit(trans_id):
18771894 status = 404 )
18781895
18791896 if status and conn is not None and \
1880- trans_obj is not None and session_obj is not None :
1897+ trans_obj is not None and session_obj is not None :
18811898
18821899 res = None
18831900
1884- # Call the set_auto_commit method of transaction object
1885- trans_obj .set_auto_commit (auto_commit )
1901+ if operation == 'auto_commit' :
1902+ # Call the set_auto_commit method of transaction object
1903+ trans_obj .set_auto_commit (_data )
1904+ elif operation == 'auto_rollback' :
1905+ trans_obj .set_auto_rollback (_data )
1906+ elif operation == 'server_cursor' :
1907+ trans_obj .set_server_cursor (_data )
18861908
18871909 # As we changed the transaction object we need to
18881910 # restore it and update the session variable.
@@ -1896,56 +1918,48 @@ def set_auto_commit(trans_id):
18961918
18971919
18981920@blueprint .route (
1899- '/auto_rollback /<int:trans_id>' ,
1900- methods = ["PUT" , "POST" ], endpoint = 'auto_rollback '
1921+ '/auto_commit /<int:trans_id>' ,
1922+ methods = ["PUT" , "POST" ], endpoint = 'auto_commit '
19011923)
19021924@pga_login_required
1903- def set_auto_rollback (trans_id ):
1925+ def set_auto_commit (trans_id ):
19041926 """
19051927 This method is used to set the value for auto commit .
19061928
19071929 Args:
19081930 trans_id: unique transaction id
19091931 """
1910- if request .data :
1911- auto_rollback = json .loads (request .data )
1912- else :
1913- auto_rollback = request .args or request .form
1914-
1915- connect = 'connect' in request .args and request .args ['connect' ] == '1'
1932+ return set_pref_options (trans_id , 'auto_commit' )
19161933
1917- is_error , errmsg = check_and_upgrade_to_qt (trans_id , connect )
1918- if is_error :
1919- return make_json_response (success = 0 , errormsg = errmsg ,
1920- info = ERROR_MSG_FAIL_TO_PROMOTE_QT ,
1921- status = 404 )
19221934
1923- # Check the transaction and connection status
1924- status , error_msg , conn , trans_obj , session_obj = \
1925- check_transaction_status (trans_id )
1926-
1927- if error_msg == ERROR_MSG_TRANS_ID_NOT_FOUND :
1928- return make_json_response (success = 0 , errormsg = error_msg ,
1929- info = 'DATAGRID_TRANSACTION_REQUIRED' ,
1930- status = 404 )
1931-
1932- if status and conn is not None and \
1933- trans_obj is not None and session_obj is not None :
1935+ @blueprint .route (
1936+ '/auto_rollback/<int:trans_id>' ,
1937+ methods = ["PUT" , "POST" ], endpoint = 'auto_rollback'
1938+ )
1939+ @pga_login_required
1940+ def set_auto_rollback (trans_id ):
1941+ """
1942+ This method is used to set the value for auto commit .
19341943
1935- res = None
1944+ Args:
1945+ trans_id: unique transaction id
1946+ """
1947+ return set_pref_options (trans_id , 'auto_rollback' )
19361948
1937- # Call the set_auto_rollback method of transaction object
1938- trans_obj .set_auto_rollback (auto_rollback )
19391949
1940- # As we changed the transaction object we need to
1941- # restore it and update the session variable.
1942- session_obj ['command_obj' ] = pickle .dumps (trans_obj , - 1 )
1943- update_session_grid_transaction (trans_id , session_obj )
1944- else :
1945- status = False
1946- res = error_msg
1950+ @blueprint .route (
1951+ '/server_cursor/<int:trans_id>' ,
1952+ methods = ["PUT" , "POST" ], endpoint = 'server_cursor'
1953+ )
1954+ @pga_login_required
1955+ def set_server_cursor (trans_id ):
1956+ """
1957+ This method is used to set the value for server_cursor.
19471958
1948- return make_json_response (data = {'status' : status , 'result' : res })
1959+ Args:
1960+ trans_id: unique transaction id
1961+ """
1962+ return set_pref_options (trans_id , 'server_cursor' )
19491963
19501964
19511965@blueprint .route (
@@ -2181,12 +2195,18 @@ def start_query_download_tool(trans_id):
21812195 if not sql :
21822196 sql = trans_obj .get_sql (sync_conn )
21832197 if sql and query_commited :
2198+ if trans_obj .server_cursor :
2199+ sync_conn .release_async_cursor ()
2200+ sync_conn .execute_void ("BEGIN;" )
21842201 # Re-execute the query to ensure the latest data is included
2185- sync_conn .execute_async (sql )
2202+ sync_conn .execute_async (sql , server_cursor = trans_obj . server_cursor )
21862203 # This returns generator of records.
21872204 status , gen , conn_obj = \
21882205 sync_conn .execute_on_server_as_csv (records = 10 )
21892206
2207+ if trans_obj .server_cursor and query_commited :
2208+ sync_conn .execute_void ("COMMIT;" )
2209+
21902210 if not status :
21912211 return make_json_response (
21922212 data = {
0 commit comments