11import datetime
2- from telnetlib import BINARY
2+ from decimal import Decimal
33import intersystems_iris .dbapi ._DBAPI as dbapi
44from . import information_schema as ischema
55from sqlalchemy import exc
2424from sqlalchemy .types import TIME
2525from sqlalchemy .types import NUMERIC
2626from sqlalchemy .types import FLOAT
27+ from sqlalchemy .types import BINARY
2728from sqlalchemy .types import VARBINARY
2829from sqlalchemy .types import TEXT
2930from sqlalchemy .types import SMALLINT
@@ -440,6 +441,14 @@ def order_by_clause(self, select, **kw):
440441 else :
441442 return ""
442443
444+ def visit_column (self , column , within_columns_clause = False , ** kwargs ):
445+ text = super ().visit_column (column , within_columns_clause = within_columns_clause , ** kwargs )
446+ if within_columns_clause :
447+ return text
448+ if isinstance (column .type , sqltypes .Text ):
449+ text = 'CONVERT(VARCHAR, %s)' % (text , )
450+ return text
451+
443452
444453class IRISDDLCompiler (sql .compiler .DDLCompiler ):
445454 """IRIS syntactic idiosyncrasies"""
@@ -487,12 +496,12 @@ def get_column_specification(self, column, **kwargs):
487496 literal = self .sql_compiler .render_literal_value (
488497 comment , sqltypes .String ()
489498 )
490- colspec .append ("%% DESCRIPTION " + literal )
499+ colspec .append ("%DESCRIPTION " + literal )
491500
492501 return " " .join (colspec )
493502
494503 def post_create_table (self , table ):
495- return " WITH %% CLASSPARAMETER ALLOWIDENTITYINSERT = 1"
504+ return " WITH %CLASSPARAMETER ALLOWIDENTITYINSERT = 1"
496505
497506
498507class IRISTypeCompiler (compiler .GenericTypeCompiler ):
@@ -555,19 +564,47 @@ def process(value):
555564 return process
556565
557566
567+ class _IRISTimeStamp (sqltypes .DateTime ):
568+ def bind_processor (self , dialect ):
569+ def process (value : datetime .datetime ):
570+ if value is not None :
571+ # value = int(value.timestamp() * 1000000)
572+ # value += (2 ** 60) if value > 0 else -(2 ** 61 * 3)
573+ return value .strftime ('%Y-%m-%d %H:%M:%S.%f' )
574+ return value
575+
576+ return process
577+
578+ def result_processor (self , dialect , coltype ):
579+ def process (value ):
580+ if isinstance (value , str ):
581+ if '.' not in value :
582+ value += '.0'
583+ return datetime .datetime .strptime (value , '%Y-%m-%d %H:%M:%S.%f' )
584+ if isinstance (value , int ):
585+ value -= (2 ** 60 ) if value > 0 else - (2 ** 61 * 3 )
586+ value = value / 1000000
587+ value = datetime .datetime .utcfromtimestamp (value )
588+ return value
589+
590+ return process
591+
592+
558593class _IRISDateTime (sqltypes .DateTime ):
559594 def bind_processor (self , dialect ):
560595 def process (value ):
561596 if value is not None :
562- return value .strftime ('%Y-%m-%d %H:%M:%S' )
597+ return value .strftime ('%Y-%m-%d %H:%M:%S.%f ' )
563598 return value
564599
565600 return process
566601
567602 def result_processor (self , dialect , coltype ):
568603 def process (value ):
569- if value is not None :
570- return datetime .datetime .strptime (value , '%Y-%m-%d %H:%M:%S' )
604+ if isinstance (value , str ):
605+ if '.' not in value :
606+ value += '.0'
607+ return datetime .datetime .strptime (value , '%Y-%m-%d %H:%M:%S.%f' )
571608 return value
572609
573610 return process
@@ -577,20 +614,25 @@ class _IRISTime(sqltypes.DateTime):
577614 def bind_processor (self , dialect ):
578615 def process (value ):
579616 if value is not None :
580- return value .strftime ('%H:%M:%S' )
617+ return value .strftime ('%H:%M:%S.%f ' )
581618 return value
582619
583620 return process
584621
585622 def result_processor (self , dialect , coltype ):
586623 def process (value ):
587- if value is not None :
624+ if isinstance (value , str ):
625+ if '.' not in value :
626+ value += '.0'
627+ return datetime .datetime .strptime (value , '%H:%M:%S.%f' ).time ()
628+ if isinstance (value , int ) or isinstance (value , Decimal ):
588629 horolog = value
589- hour = horolog // 3600
590- horolog -= hour * 3600
591- minute = horolog // 60
592- second = horolog % 60
593- return datetime .time (hour , minute , second )
630+ hour = int (horolog // 3600 )
631+ horolog -= int (hour * 3600 )
632+ minute = int (horolog // 60 )
633+ second = int (horolog % 60 )
634+ micro = int (value % 1 * 1000000 )
635+ return datetime .time (hour , minute , second , micro )
594636 return value
595637
596638 return process
@@ -599,6 +641,7 @@ def process(value):
599641colspecs = {
600642 sqltypes .Date : _IRISDate ,
601643 sqltypes .DateTime : _IRISDateTime ,
644+ sqltypes .TIMESTAMP : _IRISTimeStamp ,
602645 sqltypes .Time : _IRISTime ,
603646}
604647
@@ -653,7 +696,7 @@ def __init__(self, **kwargs):
653696 def _get_option (self , connection , option ):
654697 cursor = connection .cursor ()
655698 # cursor = connection.cursor()
656- cursor .execute ('SELECT %SYSTEM_SQL.Util_GetOption(?)' , [ option , ] )
699+ cursor .execute ('SELECT %SYSTEM_SQL.Util_GetOption(?)' , option )
657700 row = cursor .fetchone ()
658701 if row :
659702 return row [0 ]
@@ -662,7 +705,7 @@ def _get_option(self, connection, option):
662705 def _set_option (self , connection , option , value ):
663706 cursor = connection .cursor ()
664707 # cursor = connection.cursor()
665- cursor .execute ('SELECT %SYSTEM_SQL.Util_SetOption(?, ?)' , [ option , value , ] )
708+ cursor .execute ('SELECT %SYSTEM_SQL.Util_SetOption(?, ?)' , option , value )
666709 row = cursor .fetchone ()
667710 if row :
668711 return row [0 ]
@@ -692,8 +735,7 @@ def set_isolation_level(self, connection, level_str):
692735
693736 @classmethod
694737 def dbapi (cls ):
695- dbapi .connect = irisnative .connect
696- dbapi .paramstyle = "format"
738+ # dbapi.paramstyle = "format"
697739 return dbapi
698740
699741 def create_connect_args (self , url ):
@@ -708,36 +750,15 @@ def create_connect_args(self, url):
708750
709751 return ([], opts )
710752
711- def _fix_for_params (self , query , params , many = False ):
712- if query .endswith (';' ):
713- query = query [:- 1 ]
714- if params is None :
715- params = []
716- elif hasattr (params , 'keys' ):
717- # Handle params as dict
718- args = {k : "?" % k for k in params }
719- query = query % args
720- else :
721- # Handle params as sequence
722- args = ['?' for i in range (len (params if not many else params [0 ]))]
723- query = query % tuple (args )
724- newparams = list ()
725- for p in params :
726- newparams .append (p if not many else list (p )
727- if len (p ) > 1 else p [0 ])
728- return query , newparams
729-
730753 def do_execute (self , cursor , query , params , context = None ):
731- query , params = self ._fix_for_params (query , params )
732- # print('do_execute', query, params)
733- cursor .execute (query , params )
754+ cursor .execute (query , * params )
734755
735756 def do_executemany (self , cursor , query , params , context = None ):
736- query , params = self ._fix_for_params (query , params , True )
737757 cursor .executemany (query , params )
738758
739759 def do_begin (self , connection ):
740760 pass
761+ # connection.cursor().execute("START TRANSACTION")
741762
742763 def do_rollback (self , connection ):
743764 connection .rollback ()
0 commit comments