<s> import sqlalchemy <EOL> from sqlalchemy . exc import IntegrityError , ProgrammingError <EOL> from corehq . apps . userreports . exceptions import TableRebuildError , TableNotFoundWarning <EOL> from corehq . apps . userreports . sql . columns import column_to_sql <EOL> from corehq . apps . userreports . sql . connection import get_engine_id <EOL> from corehq . apps . userreports . sql . util import get_table_name <EOL> from corehq . sql_db . connections import connection_manager <EOL> from dimagi . utils . decorators . memoized import memoized <EOL> from dimagi . utils . logging import notify_exception <EOL> metadata = sqlalchemy . MetaData ( ) <EOL> class IndicatorSqlAdapter ( object ) : <EOL> def __init__ ( self , config ) : <EOL> self . config = config <EOL> self . engine_id = get_engine_id ( config ) <EOL> self . session_helper = connection_manager . get_session_helper ( self . engine_id ) <EOL> self . engine = self . session_helper . engine <EOL> @ memoized <EOL> def get_table ( self ) : <EOL> return get_indicator_table ( self . config ) <EOL> def rebuild_table ( self ) : <EOL> self . session_helper . Session . remove ( ) <EOL> try : <EOL> rebuild_table ( self . engine , self . get_table ( ) ) <EOL> except ProgrammingError , e : <EOL> raise TableRebuildError ( '<STR_LIT>' . format ( self . config , e ) ) <EOL> finally : <EOL> self . session_helper . Session . commit ( ) <EOL> def drop_table ( self ) : <EOL> self . session_helper . Session . remove ( ) <EOL> with self . engine . begin ( ) as connection : <EOL> self . get_table ( ) . drop ( connection , checkfirst = True ) <EOL> def get_query_object ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . session_helper . Session . query ( self . get_table ( ) ) <EOL> def best_effort_save ( self , doc ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> self . save ( doc ) <EOL> except IntegrityError : <EOL> pass <EOL> except Exception as e : <EOL> self . handle_exception ( doc , e ) <EOL> def handle_exception ( self , doc , exception ) : <EOL> notify_exception ( None , u'<STR_LIT>' . format ( <EOL> exception , <EOL> self . config . domain , <EOL> doc . get ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> '<STR_LIT>' . format ( self . config . display_name , self . config . _id ) <EOL> ) ) <EOL> def save ( self , doc ) : <EOL> """<STR_LIT>""" <EOL> indicator_rows = self . config . get_all_values ( doc ) <EOL> if indicator_rows : <EOL> table = self . get_table ( ) <EOL> with self . engine . begin ( ) as connection : <EOL> delete = table . delete ( table . c . doc_id == doc [ '<STR_LIT>' ] ) <EOL> connection . execute ( delete ) <EOL> for indicator_row in indicator_rows : <EOL> all_values = { i . column . database_column_name : i . value for i in indicator_row } <EOL> insert = table . insert ( ) . values ( ** all_values ) <EOL> connection . execute ( insert ) <EOL> def delete ( self , doc ) : <EOL> table = self . get_table ( ) <EOL> with self . engine . begin ( ) as connection : <EOL> delete = table . delete ( table . c . doc_id == doc [ '<STR_LIT>' ] ) <EOL> connection . execute ( delete ) <EOL> class ErrorRaisingIndicatorSqlAdapter ( IndicatorSqlAdapter ) : <EOL> def handle_exception ( self , doc , exception ) : <EOL> if isinstance ( exception , ProgrammingError ) : <EOL> orig = getattr ( exception , '<STR_LIT>' ) <EOL> if orig : <EOL> error_code = getattr ( orig , '<STR_LIT>' ) <EOL> if error_code == '<STR_LIT>' : <EOL> raise TableNotFoundWarning <EOL> super ( ErrorRaisingIndicatorSqlAdapter , self ) . handle_exception ( doc , exception ) <EOL> def get_indicator_table ( indicator_config , custom_metadata = None ) : <EOL> sql_columns = [ column_to_sql ( col ) for col in indicator_config . get_columns ( ) ] <EOL> table_name = get_table_name ( indicator_config . domain , indicator_config . table_id ) <EOL> return sqlalchemy . Table ( <EOL> table_name , <EOL> custom_metadata or metadata , <EOL> extend_existing = True , <EOL> * sql_columns <EOL> ) <EOL> def rebuild_table ( engine , table ) : <EOL> with engine . begin ( ) as connection : <EOL> table . drop ( connection , checkfirst = True ) <EOL> table . create ( connection ) </s>
