def test_prepare_sql_stmt_unregistered(self):
     """
     Given a function that generates SQL has not been registered with the PreparedStatementController
     When  prepare_sql_stmt is called for that function
     Then  a StatementNotRegistered error will be raised
     """
     psc = PreparedStatementController()
     with self.assertRaises(StatementNotRegistered):
         psc.prepare_sql_stmt("unregistered_sql", force=False)
    def test_execute_prepared_stmt(self):
        """
        Given a statement has been prepared in the database
        When  execute() is called for that statement
        Then  then the execute method of the PreparedStatement object will be called
        """
        psc = PreparedStatementController()
        psc.register_sql("gen_sql", lambda: None)

        with patch.object(PreparedStatement, "prepare", return_value=None):
            psc.prepare_sql_stmt("gen_sql", force=False)
            self.assertTrue("gen_sql" in psc.prepared_statements)

        with patch.object(PreparedStatement, "execute",
                          return_value=None) as mock_execute:
            psc.execute("gen_sql")
        mock_execute.assert_called_once()
    def test_prepare_sql_stmt(self):
        """
        Given a function that generates SQL has been registered with the PreparedStatementController
        When  prepare_sql_stmt is called
        Then  a PreparedStatement object should be created
        And   the PreparedStatement should be added to the prepared_statements dict
        And   the prepare method of the PreparedStatement will be called
        """
        psc = PreparedStatementController()
        psc.register_sql("gen_sql", lambda: None)

        with patch.object(PreparedStatement, "prepare",
                          return_value=None) as mock_prepare:
            psc.prepare_sql_stmt("gen_sql", force=False)
            self.assertTrue("gen_sql" in psc.prepared_statements)
            self.assertTrue(
                isinstance(psc.prepared_statements["gen_sql"],
                           PreparedStatement))
        mock_prepare.assert_called_once()
    def test_prepare_sql_stmt_force(self):
        """
        Given a SQL statement has already been prepared in the database
        When  prepare_sql_stmt is called for the same function
        And   force is False
        Then  a StatementAlreadyPreparedException error will be raised
        ---
        Given a SQL statement has already been prepared in the database
        When  prepare_sql_stmt is called for the same function
        And   force is True
        Then  the existing statement will be deallocated
        And   the statement will be re-prepared
        """
        psc = PreparedStatementController()
        psc.register_sql("gen_sql", lambda: None)

        with patch.object(PreparedStatement, "prepare", return_value=None):
            psc.prepare_sql_stmt("gen_sql", force=False)
            self.assertTrue("gen_sql" in psc.prepared_statements)

        with self.assertRaises(StatementAlreadyPreparedException):
            psc.prepare_sql_stmt("gen_sql", force=False)

        with patch.object(PreparedStatement, "prepare",
                          return_value=None) as mock_prepare:
            with patch.object(PreparedStatement,
                              "deallocate",
                              return_value=None) as mock_deallocate:
                psc.prepare_sql_stmt("gen_sql", force=True)
        mock_deallocate.assert_called_once()
        mock_prepare.assert_called_once()
    def test_deallocate_all(self):
        """
        Given there are prepared statements
        When  deallocate_all() is called
        Then  the deallocate method will be called on every PreparedStatement object
        And   the prepared_statements dict will be empty
        """
        psc = PreparedStatementController()
        psc.register_sql("gen_sql", lambda: None)
        psc.register_sql("gen_sql2", lambda: None)
        psc.register_sql("gen_sql3", lambda: None)

        with patch.object(PreparedStatement, "prepare", return_value=None):
            psc.prepare_sql_stmt("gen_sql", force=False)
            psc.prepare_sql_stmt("gen_sql2", force=False)
            psc.prepare_sql_stmt("gen_sql3", force=False)

        with patch.object(PreparedStatement, "deallocate",
                          return_value=None) as mock_deallocate:
            psc.deallocate_all()
        self.assertEqual(mock_deallocate.call_count, 3)

        self.assertEqual(psc.prepared_statements, {})