11import datetime
22from telnetlib import BINARY
3+ from iris .dbapi ._DBAPI import Cursor
4+ from iris .dbapi ._ResultSetRow import _ResultSetRow
5+ from iris .dbapi ._DBAPI import SQLType as IRISSQLType
6+ import iris ._IRISNative as irisnative
7+ import iris .dbapi ._DBAPI as dbapi
38from . import information_schema as ischema
49from sqlalchemy import exc
510from sqlalchemy .orm import aliased
914from sqlalchemy .sql import util as sql_util
1015from sqlalchemy .sql import between
1116from sqlalchemy .sql import func
17+ from sqlalchemy .sql import expression
1218from sqlalchemy import sql , text
1319from sqlalchemy import util
1420from sqlalchemy import types as sqltypes
@@ -501,8 +507,41 @@ def __init__(self, dialect):
501507 dialect , omit_schema = False )
502508
503509
510+ class CursorWrapper (Cursor ):
511+ def __init__ (self , connection ):
512+ super (CursorWrapper , self ).__init__ (connection )
513+
514+ def fetchone (self ):
515+ retval = super (CursorWrapper , self ).fetchone ()
516+ if retval is None :
517+ return None
518+ if not isinstance (retval , _ResultSetRow .DataRow ):
519+ return retval
520+
521+ # Workaround for fetchone, which returns values in row not from 0
522+ row = []
523+ for c in self ._columns :
524+ value = retval [c .name ]
525+ # Workaround for issue, when int returned as string
526+ if value is not None and c .type in (IRISSQLType .INTEGER , IRISSQLType .BIGINT ,) and type (value ) is not int :
527+ value = int (value )
528+ row .append (value )
529+ return row
530+
531+
504532class IRISExecutionContext (default .DefaultExecutionContext ):
505- pass
533+
534+ def get_lastrowid (self ):
535+ cursor = self .create_cursor ()
536+ cursor .execute ("SELECT LAST_IDENTITY()" )
537+ lastrowid = cursor .fetchone ()[0 ]
538+ cursor .close ()
539+ return lastrowid
540+
541+ def create_cursor (self ):
542+ # cursor = self._dbapi_connection.cursor()
543+ cursor = CursorWrapper (self ._dbapi_connection )
544+ return cursor
506545
507546
508547HOROLOG_ORDINAL = datetime .date (1840 , 12 , 31 ).toordinal ()
@@ -594,7 +633,7 @@ class IRISDialect(default.DefaultDialect):
594633
595634 supports_sequences = False
596635
597- postfetch_lastrowid = False
636+ postfetch_lastrowid = True
598637 non_native_boolean_check_constraint = False
599638 supports_simple_order_by_label = False
600639 supports_empty_insert = False
@@ -612,11 +651,58 @@ class IRISDialect(default.DefaultDialect):
612651
613652 def __init__ (self , ** kwargs ):
614653 default .DefaultDialect .__init__ (self , ** kwargs )
654+ self ._auto_parallel = 1
655+
656+ _isolation_lookup = set (
657+ [
658+ "READ UNCOMMITTED" ,
659+ "READ COMMITTED" ,
660+ "READ VERIFIED" ,
661+ ]
662+ )
663+
664+ def _get_option (self , connection , option ):
665+ cursor = CursorWrapper (connection )
666+ # cursor = connection.cursor()
667+ cursor .execute ('SELECT %SYSTEM_SQL.Util_GetOption(?)' , [option , ])
668+ row = cursor .fetchone ()
669+ if row :
670+ return row [0 ]
671+ return None
672+
673+ def _set_option (self , connection , option , value ):
674+ cursor = CursorWrapper (connection )
675+ # cursor = connection.cursor()
676+ cursor .execute ('SELECT %SYSTEM_SQL.Util_SetOption(?, ?)' , [option , value , ])
677+ row = cursor .fetchone ()
678+ if row :
679+ return row [0 ]
680+ return None
681+
682+ def get_isolation_level (self , connection ):
683+ level = int (self ._get_option (connection , 'IsolationMode' ))
684+ if level == 0 :
685+ return 'READ UNCOMMITTED'
686+ elif level == 1 :
687+ return 'READ COMMITTED'
688+ elif level == 3 :
689+ return 'READ VERIFIED'
690+ return None
691+
692+ def set_isolation_level (self , connection , level_str ):
693+ if level_str == "AUTOCOMMIT" :
694+ connection .setAutoCommit (True )
695+ else :
696+ connection .setAutoCommit (False )
697+ level = 0
698+ if level_str == 'READ COMMITTED' :
699+ level = 1
700+ elif level_str == 'READ VERIFIED' :
701+ level = 3
702+ self ._set_option (connection , 'IsolationMode' , level )
615703
616704 @classmethod
617705 def dbapi (cls ):
618- import iris ._IRISNative as irisnative
619- import iris .dbapi ._DBAPI as dbapi
620706 dbapi .connect = irisnative .connect
621707 dbapi .paramstyle = "format"
622708 return dbapi
@@ -629,6 +715,8 @@ def create_connect_args(self, url):
629715 opts ["username" ] = url .username if url .username else ''
630716 opts ["password" ] = url .password if url .password else ''
631717
718+ opts ['autoCommit' ] = False
719+
632720 return ([], opts )
633721
634722 def _fix_for_params (self , query , params , many = False ):
@@ -659,6 +747,21 @@ def do_executemany(self, cursor, query, params, context=None):
659747 query , params = self ._fix_for_params (query , params , True )
660748 cursor .executemany (query , params )
661749
750+ def do_begin (self , connection ):
751+ pass
752+
753+ def do_rollback (self , connection ):
754+ connection .rollback ()
755+
756+ def do_commit (self , connection ):
757+ connection .commit ()
758+
759+ def do_savepoint (self , connection , name ):
760+ connection .execute (expression .SavepointClause (name ))
761+
762+ def do_release_savepoint (self , connection , name ):
763+ pass
764+
662765 def get_schema (self , schema = None ):
663766 if schema is None :
664767 return 'SQLUser'
0 commit comments