Example #1
0
 def __contains__(self, key):
     """return True if we have a job by this key"""
     try:
         with transaction_context(self.database_class) as conn:
             single_value_sql(
                 conn, """SELECT app_name
                 FROM cron_job
                 WHERE app_name = %s""", (key, ))
             return True
     except SQLDidNotReturnSingleValue:
         return False
Example #2
0
    def test_single_value_sql2(self):
        m_execute = Mock()
        m_fetchall = Mock(return_value=((17,),))
        m_cursor = MagicMock()
        m_cursor.execute = m_execute
        m_cursor.fetchall = m_fetchall
        conn = MagicMock()
        conn.cursor.return_value.__enter__.return_value = m_cursor

        dbutil.single_value_sql(conn, "select 17", (1, 2, 3))
        assert conn.cursor.call_count == 1
        assert m_cursor.execute.call_count == 1
        m_cursor.execute.assert_called_once_with('select 17', (1, 2, 3))
Example #3
0
    def test_single_value_sql2(self):
        m_execute = Mock()
        m_fetchall = Mock(return_value=((17,),))
        m_cursor = MagicMock()
        m_cursor.execute = m_execute
        m_cursor.fetchall = m_fetchall
        conn = MagicMock()
        conn.cursor.return_value.__enter__.return_value = m_cursor

        dbutil.single_value_sql(conn, "select 17", (1, 2, 3))
        assert conn.cursor.call_count == 1
        assert m_cursor.execute.call_count == 1
        m_cursor.execute.assert_called_once_with('select 17', (1, 2, 3))
Example #4
0
 def __contains__(self, key):
     """return True if we have a job by this key"""
     try:
         with transaction_context(self.database_class) as conn:
             single_value_sql(
                 conn,
                 """SELECT app_name
                 FROM cron_job
                 WHERE app_name = %s""",
                 (key,)
             )
             return True
     except SQLDidNotReturnSingleValue:
         return False
Example #5
0
    def test_single_value_sql3(self):
        m_execute = Mock()
        m_fetchall = Mock(return_value=None)
        m_cursor = MagicMock()
        m_cursor.execute = m_execute
        m_cursor.fetchall = m_fetchall
        conn = MagicMock()
        conn.cursor.return_value.__enter__.return_value = m_cursor

        with pytest.raises(dbutil.SQLDidNotReturnSingleValue):
            dbutil.single_value_sql(conn, 'select 17', (1, 2, 3))

        assert conn.cursor.call_count == 1
        assert m_cursor.execute.call_count == 1
        m_cursor.execute.assert_called_once_with('select 17', (1, 2, 3))
Example #6
0
    def test_single_value_sql3(self):
        m_execute = Mock()
        m_fetchall = Mock(return_value=None)
        m_cursor = MagicMock()
        m_cursor.execute = m_execute
        m_cursor.fetchall = m_fetchall
        conn = MagicMock()
        conn.cursor.return_value.__enter__.return_value = m_cursor

        with pytest.raises(dbutil.SQLDidNotReturnSingleValue):
            dbutil.single_value_sql(conn, 'select 17', (1, 2, 3))

        assert conn.cursor.call_count == 1
        assert m_cursor.execute.call_count == 1
        m_cursor.execute.assert_called_once_with('select 17', (1, 2, 3))
Example #7
0
    def __delitem__(self, key):
        """remove the item by key or raise KeyError"""
        with transaction_context(self.database_class) as connection:
            try:
                # result intentionally ignored
                single_value_sql(
                    connection, """SELECT app_name
                       FROM cron_job
                       WHERE
                            app_name = %s""", (key, ))
            except SQLDidNotReturnSingleValue:
                raise KeyError(key)

            # item exists
            execute_no_results(
                connection, """DELETE FROM cron_job
                   WHERE app_name = %s""", (key, ))
Example #8
0
    def __delitem__(self, key):
        """remove the item by key or raise KeyError"""
        with transaction_context(self.database_class) as connection:
            try:
                # result intentionally ignored
                single_value_sql(
                    connection,
                    """SELECT app_name
                       FROM cron_job
                       WHERE
                            app_name = %s""",
                    (key,)
                )
            except SQLDidNotReturnSingleValue:
                raise KeyError(key)

            # item exists
            execute_no_results(
                connection,
                """DELETE FROM cron_job
                   WHERE app_name = %s""",
                (key,)
            )
Example #9
0
    def __setitem__(self, key, value):
        class LastErrorEncoder(json.JSONEncoder):
            def default(self, obj):
                if isinstance(obj, type):
                    return repr(obj)
                return json.JSONEncoder.default(self, obj)

        with transaction_context(self.database_class) as connection:
            try:
                single_value_sql(
                    connection, """
                    SELECT ongoing
                    FROM cron_job
                    WHERE
                        app_name = %s
                    FOR UPDATE NOWAIT
                    """, (key, ))
                # If the above single_value_sql() didn't raise a
                # SQLDidNotReturnSingleValue exception, it means
                # there is a row by this app_name.
                # Therefore, the next SQL is an update.
                next_sql = """
                    UPDATE cron_job
                    SET
                        next_run = %(next_run)s,
                        first_run = %(first_run)s,
                        last_run = %(last_run)s,
                        last_success = %(last_success)s,
                        depends_on = %(depends_on)s,
                        error_count = %(error_count)s,
                        last_error = %(last_error)s,
                        ongoing = %(ongoing)s
                    WHERE
                        app_name = %(app_name)s
                """
            except OperationalError as exception:
                if 'could not obtain lock' in exception.args[0]:
                    raise RowLevelLockError(exception.args[0])
                else:
                    raise
            except SQLDidNotReturnSingleValue:
                # the key does not exist, do an insert
                next_sql = """
                    INSERT INTO cron_job (
                        app_name,
                        next_run,
                        first_run,
                        last_run,
                        last_success,
                        depends_on,
                        error_count,
                        last_error,
                        ongoing
                    ) VALUES (
                        %(app_name)s,
                        %(next_run)s,
                        %(first_run)s,
                        %(last_run)s,
                        %(last_success)s,
                        %(depends_on)s,
                        %(error_count)s,
                        %(last_error)s,
                        %(ongoing)s
                    )
                """

            # serialize last_error if it's a {}
            last_error = value['last_error']
            if isinstance(last_error, dict):
                last_error = json.dumps(value['last_error'],
                                        cls=LastErrorEncoder)

            parameters = {
                'app_name': key,
                'next_run': value['next_run'],
                'first_run': value['first_run'],
                'last_run': value['last_run'],
                'last_success': value.get('last_success'),
                'depends_on': value['depends_on'],
                'error_count': value['error_count'],
                'last_error': last_error,
                'ongoing': value.get('ongoing'),
            }
            try:
                execute_no_results(connection, next_sql, parameters)
            except IntegrityError as exception:
                # See CREATE_CRONTABBER_APP_NAME_UNIQUE_INDEX for why
                # we know to look for this mentioned in the error message.
                if 'crontabber_unique_app_name_idx' in exception.args[0]:
                    raise RowLevelLockError(exception.args[0])
                raise
Example #10
0
 def has_data(self):
     with transaction_context(self.database_class) as conn:
         return bool(single_value_sql(conn,
                                      'SELECT count(*) FROM cron_job'))
Example #11
0
    def __setitem__(self, key, value):
        class LastErrorEncoder(json.JSONEncoder):
            def default(self, obj):
                if isinstance(obj, type):
                    return repr(obj)
                return json.JSONEncoder.default(self, obj)

        with transaction_context(self.database_class) as connection:
            try:
                single_value_sql(
                    connection,
                    """
                    SELECT ongoing
                    FROM cron_job
                    WHERE
                        app_name = %s
                    FOR UPDATE NOWAIT
                    """,
                    (key,)
                )
                # If the above single_value_sql() didn't raise a
                # SQLDidNotReturnSingleValue exception, it means
                # there is a row by this app_name.
                # Therefore, the next SQL is an update.
                next_sql = """
                    UPDATE cron_job
                    SET
                        next_run = %(next_run)s,
                        first_run = %(first_run)s,
                        last_run = %(last_run)s,
                        last_success = %(last_success)s,
                        depends_on = %(depends_on)s,
                        error_count = %(error_count)s,
                        last_error = %(last_error)s,
                        ongoing = %(ongoing)s
                    WHERE
                        app_name = %(app_name)s
                """
            except OperationalError as exception:
                if 'could not obtain lock' in exception.args[0]:
                    raise RowLevelLockError(exception.args[0])
                else:
                    raise
            except SQLDidNotReturnSingleValue:
                # the key does not exist, do an insert
                next_sql = """
                    INSERT INTO cron_job (
                        app_name,
                        next_run,
                        first_run,
                        last_run,
                        last_success,
                        depends_on,
                        error_count,
                        last_error,
                        ongoing
                    ) VALUES (
                        %(app_name)s,
                        %(next_run)s,
                        %(first_run)s,
                        %(last_run)s,
                        %(last_success)s,
                        %(depends_on)s,
                        %(error_count)s,
                        %(last_error)s,
                        %(ongoing)s
                    )
                """

            # serialize last_error if it's a {}
            last_error = value['last_error']
            if isinstance(last_error, dict):
                last_error = json.dumps(value['last_error'], cls=LastErrorEncoder)

            parameters = {
                'app_name': key,
                'next_run': value['next_run'],
                'first_run': value['first_run'],
                'last_run': value['last_run'],
                'last_success': value.get('last_success'),
                'depends_on': value['depends_on'],
                'error_count': value['error_count'],
                'last_error': last_error,
                'ongoing': value.get('ongoing'),
            }
            try:
                execute_no_results(connection, next_sql, parameters)
            except IntegrityError as exception:
                # See CREATE_CRONTABBER_APP_NAME_UNIQUE_INDEX for why
                # we know to look for this mentioned in the error message.
                if 'crontabber_unique_app_name_idx' in exception.args[0]:
                    raise RowLevelLockError(exception.args[0])
                raise
Example #12
0
 def has_data(self):
     with transaction_context(self.database_class) as conn:
         return bool(single_value_sql(conn, 'SELECT count(*) FROM cron_job'))