def add_table_data(self, txn, table, identity):
        """ 
        Add a table to the backend if it doesn't exist and insert the data.
        This is executed using adbapi in a thread pool.
        """

        start_time = time.time()

        # For when we hit lock contention - only retry so many times.

        table.init_retry(5)

        tablename = table.get_tablename()

        if tablename is None:
            logging.info("SqlConnections: Unknown tablename from '%s'", identity)
            return

        update = table.get_property('update')
        static = table.get_property('static')
        persist = table.get_property('persist')

        # Check if we need to save the table in case of persistence.

        self.data_manager.check_save_table(table, identity)

        # Now check if we've already added the table.

        try:
            if not update and not static and self.connections[identity]["tables"][tablename] > 0:
                logging.info("SqlConnections: '%s' has already sent an update or is persisted for table '%s'", identity, tablename)
                return
        except KeyError:
            # Ignore
            pass

        try:
            # Wrap the create, alter tables and inserts or updates in
            # a transaction... All or none please.

            txn.execute("BEGIN;")

            # Use this to detect if the table already exists - we
            # could just not do this and use the create table to
            # detect if a table is already there or not but a error on
            # the create table would mean having to restart the
            # transaction and require some weird retry logic..

            create_sql = "CREATE TABLE IF NOT EXISTS '%s' ( \n" % tablename

            columns = []
            
            for column_name, column_type in table.zip_columns():
                columns.append( "'%s' %s DEFAULT NULL" % (column_name, column_type) )

            create_sql += ",\n".join( columns )

            create_sql += ")"

            try:
                result = self.do_sql(txn, create_sql)
            except Exception as e:
                errorstr = str(e)

                # Is this a "table already exists" error?  Then its a race condition between checking if a table exists and actually creating it.
                # This should never happen now - we are using CREATE IF NOT EXISTS ...
                if "already exists" in errorstr:
                    # Don't need to log this as it is fairly common.
                    ##logging.info("SqlConnections: Warning: Create table race condition '%s' for %s: '%s' ... retrying", tablename, identity, errorstr)
                    raise CreateTableException("Create table race condition '%s' for %s: '%s'" % (tablename, identity, errorstr,))
                
                else:
                    # Otherwise some kind of sql error, pass the exception up
                    raise e


            # Merge the schemas of what might be already there and our update.
            schema = self.get_schema(txn, tablename)

            self.data_manager.table_merger.merge_table(txn, table, schema, self)

            # Now update the table.
            # Truncate and re-insert if this is static.
            # Call do_update if this is an update type.
            # Otherwise we insert.

            if static:
                txn.execute("DELETE FROM '%s';" % tablename)
                rowcount = self.do_insert_table(txn, table)

            else:
                if update:
                    rowcount = self.do_update_table(txn, table, identity)
                else:
                    rowcount = self.do_insert_table(txn, table)

            txn.execute("COMMIT;")

        except apsw.BusyError as e:
            # This should only happen if we exceed the busy timeout.
            logging.info("SqlConnections: Warning: Lock contention for adding table '%s': %s for %s", tablename, str(e), identity)

            try:
                txn.execute("ROLLBACK;")
            except:
                pass

            # Should we try again?
            if table.test_retry():
                logging.info("SqlConnections: ERROR: Retries failed for table '%s'", tablename)
                return 0

            # Place this request back on the event queue for a retry.
            self.async_add_table_data(table, identity)

            return 0

        except CreateTableException as e:
            # Message when raised

            try:
                txn.execute("ROLLBACK;")
            except:
                pass

            # Should we try again?
            if table.test_retry():
                logging.info("SqlConnections: ERROR: Retries failed for table '%s'", tablename)
                return 0

            # Place this request back on the event queue for a retry.
            self.async_add_table_data(table, identity)

            return 0

        except Exception as e:
            logging.info("SqlConnections: ERROR: Failed to add table '%s': %s", tablename, e)

            try:
                txn.execute("ROLLBACK;")
            except:
                pass

            return 0

        now = time.time()

        nr_rows = table.get_nr_rows()

        properties_str = ''
        if static: properties_str += ' static'
        if update: properties_str += ' update'
        if persist: properties_str += ' persist'

        logging.info("SqlConnections: New data%s for table '%s' %d rows from '%s' (%.02f seconds)", 
                     properties_str, tablename, rowcount, identity, now - start_time)

        # Update some informational stats used for making the tables
        # and connections tables.

        self.update_table_stats(tablename, rowcount, identity=identity,
                                sum=not update and not static, now=now)
            
        return 1
dataset/ETHPy150Open MediaMath/qasino/lib/sqlite_backend.py/SqlConnections.add_table_data/original