'Helper for store classes to do a background index addition
To use:
1. use a schema delta file to add a background update. Example:
INSERT INTO background_updates (update_name, progress_json) VALUES
(\'my_new_index\', \'{}\');
2. In the Store constructor, call this method
Args:
update_name (str): update_name to register for
index_name (str): name of index to add
table (str): table to add index to
columns (list[str]): columns/expressions to include in index
unique (bool): true to make a UNIQUE index
psql_only: true to only create this index on psql databases (useful
for virtual sqlite tables)'

def register_background_index_update(self, update_name, index_name, table, columns, where_clause=None, unique=False, psql_only=False):

    def create_index_psql(conn):
        conn.rollback()
        conn.set_session(autocommit=True)
        try:
            c = conn.cursor()
            sql = ('DROP    INDEX    IF    EXISTS    %s' % (index_name,))
            logger.debug('[SQL]    %s', sql)
            c.execute(sql)
            sql = ('CREATE    %(unique)s    INDEX    CONCURRENTLY    %(name)s    ON    %(table)s    (%(columns)s)    %(where_clause)s' % {'unique': ('UNIQUE' if unique else ''), 'name': index_name, 'table': table, 'columns': ',    '.join(columns), 'where_clause': (('WHERE    ' + where_clause) if where_clause else '')})
            logger.debug('[SQL]    %s', sql)
            c.execute(sql)
        finally:
            conn.set_session(autocommit=False)
    def create_index_sqlite(conn):
        sql = ('CREATE    %(unique)s    INDEX    IF    NOT    EXISTS    %(name)s    ON    %(table)s    (%(columns)s)' % {'unique': ('UNIQUE' if unique else ''), 'name': index_name, 'table': table, 'columns': ',    '.join(columns)})
        c = conn.cursor()
        logger.debug('[SQL]    %s', sql)
        c.execute(sql)
    if isinstance(self.database_engine, engines.PostgresEngine):
        runner = create_index_psql
    elif psql_only:
        runner = None
    else:
        runner = create_index_sqlite
    @defer.inlineCallbacks
    def updater(progress, batch_size):
        if (runner is not None):
            logger.info('Adding    index    %s    to    %s', index_name, table)
            (yield self.runWithConnection(runner))
        (yield self._end_background_update(update_name))
        defer.returnValue(1)
    self.register_background_update_handler(update_name, updater)
