示例#1
0
    def execute(
        self,
        sql: str,
        params: Optional[Dict[str, Any]] = None,
        database_name: Optional[str] = None,
        include_result_metadata: bool = False,
    ) -> ExecuteStatementResponse:
        try:
            if database_name:
                self.use_database(database_name)

            cursor: Optional[jaydebeapi.Cursor] = None
            try:
                cursor = self.connection.cursor()

                if self.autocommit:
                    self.autocommit_off(cursor)

                self.reset_generated_id(cursor)
                if params:
                    cursor.execute(self.create_query(sql, params))
                else:
                    cursor.execute(str(text(sql)))
                if cursor.description:
                    response = ExecuteStatementResponse(
                        numberOfRecordsUpdated=0,
                        records=[[Field.from_value(column) for column in row]
                                 for row in cursor.fetchall()],
                    )
                    if include_result_metadata:
                        meta = getattr(cursor, '_meta')
                        response.columnMetadata = create_column_metadata_set(
                            meta)
                    return response
                else:
                    rowcount: int = cursor.rowcount
                    last_generated_id: int = self.last_generated_id(cursor)
                    generated_fields: List[Field] = []
                    if last_generated_id > 0:
                        generated_fields.append(
                            Field.from_value(last_generated_id))
                    return ExecuteStatementResponse(
                        numberOfRecordsUpdated=rowcount,
                        generatedFields=generated_fields,
                    )
            finally:
                if cursor:  # pragma: no cover
                    cursor.close()

        except jaydebeapi.DatabaseError as e:
            message: str = 'Unknown'
            if len(getattr(e, 'args', [])):
                message = e.args[0]
                if len(getattr(e.args[0], 'args', [])):
                    message = e.args[0].args[0]
                    if getattr(e.args[0].args[0], 'cause', None):
                        message = e.args[0].args[0].cause.message
            raise BadRequestException(str(message))
示例#2
0
 def get_field_from_value(self, value: Any) -> Field:
     if type(value).__name__.endswith('UUID'):
         return Field(stringValue=str(value))
     elif type(value).__name__.endswith('PGobject'):
         return Field(stringValue=str(value))
     elif type(value).__name__.endswith('PgArray'):
         return Field(stringValue=str(value))
     else:
         return super().get_field_from_value(value)
示例#3
0
    def execute(
        self,
        sql: str,
        params: Optional[Dict[str, Any]] = None,
        database_name: Optional[str] = None,
        include_result_metadata: bool = False,
    ) -> ExecuteStatementResponse:

        try:
            if database_name:
                self.use_database(database_name)

            cursor: Optional[Cursor] = None
            try:
                cursor = self.connection.cursor()
                if params:
                    cursor.execute(self.create_query(sql, params))
                else:
                    cursor.execute(str(text(sql)))

                if cursor.description:
                    response: ExecuteStatementResponse = ExecuteStatementResponse(
                        numberOfRecordsUpdated=0,
                        records=[[Field.from_value(column) for column in row]
                                 for row in cursor.fetchall()],
                    )
                    if include_result_metadata:
                        response.columnMetadata = [
                            create_column_metadata(*d)
                            for d in cursor.description
                        ]
                    return response
                else:
                    rowcount: int = cursor.rowcount
                    last_generated_id: int = cursor.lastrowid
                    generated_fields: List[Field] = []
                    if last_generated_id > 0:
                        generated_fields.append(
                            Field.from_value(last_generated_id))
                    return ExecuteStatementResponse(
                        numberOfRecordsUpdated=rowcount,
                        generatedFields=generated_fields,
                    )
            finally:
                if cursor:  # pragma: no cover
                    cursor.close()

        except Exception as e:
            message: str = 'Unknown'
            if hasattr(e, 'orig') and hasattr(e.orig, 'args'):  # type: ignore
                message = str(e.orig.args[1])  # type: ignore
            elif len(getattr(e, 'args', [])) and e.args[0]:
                message = str(e.args[0])
            raise BadRequestException(message)
示例#4
0
 def get_filed_from_jdbc_type(self, value: Any,
                              jdbc_type: Optional[int]) -> Field:
     type_ = type(value)
     if type_.__name__.endswith('UUID'):
         return Field(stringValue=str(value))
     elif type_.__name__.endswith('PGobject'):
         return Field(stringValue=str(value))
     elif type_.__name__.endswith('PgArray'):
         return Field(stringValue=str(value))
     else:
         return super().get_filed_from_jdbc_type(value, jdbc_type)
示例#5
0
def test_execute_select(clear, mocker):
    connection_mock = mocker.Mock()
    cursor_mock = mocker.Mock()
    connection_mock.cursor.side_effect = [cursor_mock]
    cursor_mock.description = 1, 1, 1, 1, 1, 1, 1
    cursor_mock.fetchall.side_effect = [((1, 'abc'),)]
    dummy = DummyResource(connection_mock, transaction_id='123')
    assert dummy.execute("select * from users",) == ExecuteStatementResponse(
        numberOfRecordsUpdated=0,
        records=[[Field.from_value(1), Field.from_value('abc')]],
    )
    cursor_mock.execute.assert_called_once_with('select * from users')
    cursor_mock.close.assert_called_once_with()
示例#6
0
def test_execute_select(mocked_connection, mocked_cursor, mocker):
    mocked_cursor.description = 1, 1, 1, 1, 1, 1, 1
    mocked_cursor.fetchall.side_effect = [((1, 'abc'), )]
    dummy = PostgreSQLJDBC(mocked_connection, transaction_id='123')
    assert dummy.execute("select * from users", ) == ExecuteStatementResponse(
        numberOfRecordsUpdated=0,
        records=[[Field.from_value(1),
                  Field.from_value('abc')]],
    )

    mocked_cursor.execute.assert_has_calls(
        [mocker.call('select * from users')])
    mocked_cursor.close.assert_called_once_with()
示例#7
0
def test_execute_select_with_include_metadata(clear, mocker):
    connection_mock = mocker.Mock()
    cursor_mock = mocker.Mock()
    connection_mock.cursor.side_effect = [cursor_mock]
    cursor_mock.description = (1, 2, 3, 4, 5, 6, 7), (8, 9, 10, 11, 12, 13, 14)
    cursor_mock.fetchall.side_effect = [((1, 'abc'), )]
    dummy = DummyResource(connection_mock, transaction_id='123')
    dummy.use_database = mocker.Mock()
    assert dummy.execute(
        "select * from users",
        database_name='test',
        include_result_metadata=True).dict() == ExecuteStatementResponse(
            numberOfRecordsUpdated=0,
            records=[[Field.from_value(1),
                      Field.from_value('abc')]],
            columnMetadata=[
                ColumnMetadata(
                    arrayBaseColumnType=0,
                    isAutoIncrement=False,
                    isCaseSensitive=False,
                    isCurrency=False,
                    isSigned=False,
                    label='1',
                    name='1',
                    nullable=1,
                    precision=5,
                    scale=6,
                    tableName=None,
                    type=None,
                    typeName=None,
                ),
                ColumnMetadata(
                    arrayBaseColumnType=0,
                    isAutoIncrement=False,
                    isCaseSensitive=False,
                    isCurrency=False,
                    isSigned=False,
                    label='8',
                    name='8',
                    nullable=1,
                    precision=12,
                    scale=13,
                    tableName=None,
                    type=None,
                    typeName=None,
                ),
            ],
        )

    cursor_mock.execute.assert_called_once_with('select * from users')
    cursor_mock.close.assert_called_once_with()
示例#8
0
 def get_filed_from_jdbc_type(self, value: Any,
                              jdbc_type: Optional[int]) -> Field:
     type_ = type(value)
     for pg_type in PG_TYPES:
         if type_.__name__.endswith(pg_type):
             return Field(stringValue=str(value))
     return super().get_filed_from_jdbc_type(value, jdbc_type)
def test_from_value(mocker) -> None:
    connection_mock = mocker.Mock()
    dummy = PostgreSQLJDBC(connection_mock)

    class JavaUUID:
        def __init__(self, val: str):
            self._val: str = val

        def __str__(self) -> str:
            return self._val

    uuid = 'e9e1df6b-c6d3-4a34-9227-c27056d596c6'
    assert dummy.get_filed_from_jdbc_type(JavaUUID(uuid),
                                          None) == Field(stringValue=uuid)

    class PGobject:
        def __init__(self, val: str):
            self._val: str = val

        def __str__(self) -> str:
            return self._val

    assert dummy.get_filed_from_jdbc_type(PGobject("{}"),
                                          None) == Field(stringValue="{}")

    class PgArray:
        def __init__(self, val: str):
            self._val: str = val

        def __str__(self) -> str:
            return self._val

    assert dummy.get_filed_from_jdbc_type(
        PgArray("{ITEM1,ITEM2}"), None) == Field(stringValue="{ITEM1,ITEM2}")

    class PGpoint:
        def __init__(self, val: str):
            self._val: str = val

        def __str__(self) -> str:
            return self._val

    assert dummy.get_filed_from_jdbc_type(
        PGpoint("(50.074534,14.444137)"),
        None) == Field(stringValue="(50.074534,14.444137)")
    helper_default_test_field(dummy)
示例#10
0
    def get_filed_from_jdbc_type(self, value: Any, jdbc_type: Optional[int]) -> Field:
        type_: Optional[JDBCType] = None
        if jdbc_type:
            try:
                type_ = JDBCType(jdbc_type)
            except ValueError:
                pass
        if type_:
            if value is None:
                return Field(isNull=True)
            elif type_ in LONG:
                return Field(longValue=value)
            elif type_ in DOUBLE:
                return Field(doubleValue=value)
            elif type_ in STRING:
                return Field(stringValue=value)
            elif type_ in BOOLEAN:
                return Field(booleanValue=value)
            elif type_ in TIMESTAMP:
                return Field(stringValue=self._format_datetime(value))
            elif type_ in BLOB:
                if isinstance(value, str):  # pragma: no cover
                    value = value.encode()
                return Field(blobValue=b64encode(value))

        return self.get_field_from_value(value)
示例#11
0
def test_execute_select(mocked_connection, mocked_cursor, mocker):
    mocked_cursor.description = 1, 1, 1, 1, 1, 1, 1
    mocked_cursor.fetchall.side_effect = [((1, 'abc'), )]
    dummy = MySQLJDBC(mocked_connection, transaction_id='123')
    dummy.use_database = mocker.Mock()
    assert dummy.execute(
        "select * from users",
        database_name='test') == ExecuteStatementResponse(
            numberOfRecordsUpdated=0,
            records=[[Field.from_value(1),
                      Field.from_value('abc')]],
        )

    mocked_cursor.execute.assert_has_calls([
        mocker.call('SELECT LAST_INSERT_ID(NULL)'),
        mocker.call('select * from users')
    ])
    mocked_cursor.close.assert_called_once_with()
示例#12
0
    def get_filed_from_jdbc_type(self, value: Any,
                                 jdbc_type: Optional[int]) -> Field:
        type_: Optional[JDBCType] = None
        if jdbc_type:
            try:
                type_ = JDBCType(jdbc_type)
            except ValueError:
                pass
        if type_:
            if type_ in LONG:
                return Field(longValue=value)
            elif type_ in DOUBLE:
                return Field(doubleValue=value)
            elif type_ in STRING:
                return Field(stringValue=value)
            elif type_ in BOOLEAN:
                return Field(booleanValue=value)
            elif type_ in BLOB:
                return Field(blobValue=b64encode(value))

        return self.get_field_from_value(value)
示例#13
0
def test_from_value(mocker) -> None:
    connection_mock = mocker.Mock()
    dummy = MySQLJDBC(connection_mock)

    class BigInteger:
        def __init__(self, val: int):
            self._val: int = val

        def __str__(self) -> int:
            return self._val

    assert dummy.get_filed_from_jdbc_type(BigInteger("55"), None) == Field(longValue=55)

    helper_default_test_field(dummy)
示例#14
0
def test_execute_insert_with_generated(clear, mocker):
    connection_mock = mocker.Mock()
    cursor_mock = mocker.Mock()
    connection_mock.cursor.side_effect = [cursor_mock]
    cursor_mock.description = ''
    cursor_mock.rowcount = 1
    cursor_mock.lastrowid = 1
    dummy = DummyResource(connection_mock)
    assert dummy.execute("insert into users ('name') values ('abc')"
                         ) == ExecuteStatementResponse(
                             numberOfRecordsUpdated=1,
                             generatedFields=[Field(longValue=1)])
    cursor_mock.execute.assert_called_once_with(
        "insert into users ('name') values ('abc')")
    cursor_mock.close.assert_called_once_with()
示例#15
0
def test_execute_insert_with_generated_field(mocked_connection, mocked_cursor,
                                             mocker):
    mocked_cursor.description = ''
    mocked_cursor.rowcount = 1
    mocked_cursor.fetchone.side_effect = [[1]]
    dummy = MySQLJDBC(mocked_connection)
    assert dummy.execute(
        "insert into users (name) values ('abc')") == ExecuteStatementResponse(
            numberOfRecordsUpdated=1, generatedFields=[Field(longValue=1)])
    mocked_cursor.execute.assert_has_calls([
        mocker.call('SELECT LAST_INSERT_ID(NULL)'),
        mocker.call("insert into users (name) values ('abc')"),
        mocker.call('SELECT LAST_INSERT_ID()'),
    ])
    mocked_cursor.close.assert_called_once_with()
示例#16
0
def test_valid_field() -> None:
    assert SqlParameter(name='abc',
                        value=Field(stringValue='abc')).valid_value == 'abc'
    assert SqlParameter(name='abc',
                        value=Field(blobValue='abc')).valid_value == 'abc'
    assert SqlParameter(name='abc',
                        value=Field(doubleValue=0.1)).valid_value == 0.1
    assert SqlParameter(name='abc',
                        value=Field(isNull=True)).valid_value is None
    assert SqlParameter(name='abc',
                        value=Field(longValue=123)).valid_value == 123
    assert SqlParameter(name='abc',
                        value=Field(longValue=123)).valid_value == 123
    assert SqlParameter(name='abc', value=Field()).valid_value is None
示例#17
0
def helper_default_test_field(dummyResource: Resource) -> None:
    assert dummyResource.get_field_from_value('str') == Field(stringValue='str')
    assert dummyResource.get_field_from_value(123) == Field(longValue=123)
    assert dummyResource.get_field_from_value(1.23) == Field(doubleValue=1.23)
    assert dummyResource.get_field_from_value(True) == Field(booleanValue=True)
    assert dummyResource.get_field_from_value(False) == Field(booleanValue=False)
    assert dummyResource.get_field_from_value(b'bytes') == Field(
        blobValue=b64encode(b'bytes')
    )
    assert dummyResource.get_field_from_value(None) == Field(isNull=True)
    assert dummyResource.get_field_from_value(
        datetime(2019, 5, 18, 15, 17, 8)
    ) == Field(stringValue='2019-05-18 15:17:08')

    class Dummy:
        pass

    with pytest.raises(Exception):
        dummyResource.get_field_from_value(Dummy())
示例#18
0
 def get_field_from_value(self, value: Any) -> Field:
     if isinstance(value, bool):
         return Field(booleanValue=value)
     elif isinstance(value, str):
         return Field(stringValue=value)
     elif type(value).__name__ == 'datetime':
         return Field(stringValue=str(value))
     elif isinstance(value, int):
         return Field(longValue=value)
     elif isinstance(value, float):
         return Field(doubleValue=value)
     elif isinstance(value, bytes):
         return Field(blobValue=b64encode(value))
     elif value is None:
         return Field(isNull=True)
     else:
         raise Exception(f'unsupported type {type(value)}: {value} ')
示例#19
0
def test_execute_select_with_include_metadata(mocked_connection, mocked_cursor,
                                              mocker):
    meta_mock = mocker.Mock()
    mocked_cursor._meta = meta_mock
    mocked_cursor.description = (1, 2, 3, 4, 5, 6, 7), (8, 9, 10, 11, 12, 13,
                                                        14)
    mocked_cursor.fetchall.side_effect = [((1, 'abc'), )]
    dummy = MySQLJDBC(mocked_connection, transaction_id='123')
    dummy.use_database = mocker.Mock()
    create_column_metadata_set_mock = mocker.patch(
        'local_data_api.resources.jdbc.create_column_metadata_set')
    create_column_metadata_set_mock.side_effect = [[
        ColumnMetadata(
            arrayBaseColumnType=0,
            isAutoIncrement=False,
            isCaseSensitive=False,
            isCurrency=False,
            isSigned=False,
            label=1,
            name=1,
            precision=5,
            scale=6,
            tableName=None,
            type=None,
            typeName=None,
        ),
        ColumnMetadata(
            arrayBaseColumnType=0,
            isAutoIncrement=False,
            isCaseSensitive=False,
            isCurrency=False,
            isSigned=False,
            label=8,
            name=8,
            precision=12,
            scale=13,
            tableName=None,
            type=None,
            typeName=None,
        ),
    ]]

    assert dummy.execute(
        "select * from users",
        database_name='test',
        include_result_metadata=True) == ExecuteStatementResponse(
            numberOfRecordsUpdated=0,
            records=[[Field.from_value(1),
                      Field.from_value('abc')]],
            columnMetadata=[
                ColumnMetadata(
                    arrayBaseColumnType=0,
                    isAutoIncrement=False,
                    isCaseSensitive=False,
                    isCurrency=False,
                    isSigned=False,
                    label=1,
                    name=1,
                    precision=5,
                    scale=6,
                    tableName=None,
                    type=None,
                    typeName=None,
                ),
                ColumnMetadata(
                    arrayBaseColumnType=0,
                    isAutoIncrement=False,
                    isCaseSensitive=False,
                    isCurrency=False,
                    isSigned=False,
                    label=8,
                    name=8,
                    precision=12,
                    scale=13,
                    tableName=None,
                    type=None,
                    typeName=None,
                ),
            ],
        )

    create_column_metadata_set_mock.assert_called_once_with(meta_mock)
    mocked_cursor.execute.assert_has_calls([
        mocker.call('SELECT LAST_INSERT_ID(NULL)'),
        mocker.call('select * from users')
    ])
    mocked_cursor.close.assert_called_once_with()
示例#20
0
 def get_filed_from_jdbc_type(self, value: Any, jdbc_type: Optional[int]) -> Field:
     if type(value).__name__.endswith('BigInteger'):
         return Field(longValue=int(str(value)))
     else:
         return super().get_filed_from_jdbc_type(value, jdbc_type)
示例#21
0
def test_valid_field() -> None:
    assert SqlParameter(name='abc',
                        value=Field(stringValue='abc')).valid_value == 'abc'
    assert SqlParameter(name='abc',
                        value=Field(blobValue='abc')).valid_value == 'abc'
    assert SqlParameter(name='abc',
                        value=Field(doubleValue=0.1)).valid_value == 0.1
    assert SqlParameter(name='abc',
                        value=Field(isNull=True)).valid_value is None
    assert SqlParameter(name='abc',
                        value=Field(longValue=123)).valid_value == 123
    assert SqlParameter(name='abc',
                        value=Field(longValue=123)).valid_value == 123
    assert SqlParameter(name='abc', value=Field()).valid_value is None
    assert (SqlParameter(name='abc',
                         value=Field(stringValue='123456789'),
                         typeHint='DECIMAL').valid_value == '123456789')
    assert (SqlParameter(
        name='abc',
        value=Field(stringValue='2020-02-27 00:30:15.290'),
        typeHint='TIMESTAMP',
    ).valid_value == '2020-02-27 00:30:15.290')
    assert (SqlParameter(name='abc',
                         value=Field(stringValue='00:30:15.290'),
                         typeHint='TIME').valid_value == '00:30:15.290')
    assert (SqlParameter(name='abc',
                         value=Field(stringValue='2020-02-27'),
                         typeHint='DATE').valid_value == '2020-02-27')
示例#22
0
def test_from_value() -> None:
    assert Field.from_value('str') == Field(stringValue='str')
    assert Field.from_value(123) == Field(longValue=123)
    assert Field.from_value(1.23) == Field(doubleValue=1.23)
    assert Field.from_value(True) == Field(booleanValue=True)
    assert Field.from_value(False) == Field(booleanValue=False)
    assert Field.from_value(b'bytes') == Field(blobValue=b64encode(b'bytes'))
    assert Field.from_value(None) == Field(isNull=True)

    class JavaUUID:
        def __init__(self, val: str):
            self._val: str = val

        def __str__(self) -> str:
            return self._val

    uuid = 'e9e1df6b-c6d3-4a34-9227-c27056d596c6'
    assert Field.from_value(JavaUUID(uuid)) == Field(stringValue=uuid)

    class PGobject:
        def __init__(self, val: str):
            self._val: str = val

        def __str__(self) -> str:
            return self._val

    assert Field.from_value(PGobject("{}")) == Field(stringValue="{}")

    class BigInteger:
        def __init__(self, val: int):
            self._val: int = val

        def __str__(self) -> int:
            return self._val

    assert Field.from_value(BigInteger("55")) == Field(longValue=55)

    class Dummy:
        pass

    with pytest.raises(Exception):
        Field.from_value(Dummy())
示例#23
0
def test_execute_select_with_include_metadata(clear, mocker):

    connection_mock = mocker.Mock()
    cursor_mock = mocker.Mock()
    connection_mock.cursor.side_effect = [cursor_mock]
    cursor_mock.description = (1, 2, 3, 4, 5, 6, 7), (8, 9, 10, 11, 12, 13, 14)
    cursor_mock.fetchall.side_effect = [((1, 'abc'),)]
    field_1 = mocker.Mock()
    field_1.name = '1'
    field_1.org_name = '1'
    field_1.flags = 2
    field_1.get_column_length.return_value = 5
    field_1.scale = 6
    field_1.table_name = None
    field_2 = mocker.Mock()
    field_2.name = '8'
    field_2.org_name = '8'
    field_2.flags = 2
    field_2.get_column_length.return_value = 12
    field_2.scale = 13
    field_2.table_name = None
    cursor_mock._result.fields = [field_1, field_2]
    dummy = MySQL(connection_mock, transaction_id='123')
    assert (
        dummy.execute("select * from users", include_result_metadata=True).dict()
        == ExecuteStatementResponse(
            numberOfRecordsUpdated=0,
            records=[[Field.from_value(1), Field.from_value('abc')]],
            columnMetadata=[
                ColumnMetadata(
                    arrayBaseColumnType=0,
                    isAutoIncrement=False,
                    isCaseSensitive=False,
                    isCurrency=False,
                    isSigned=False,
                    label='1',
                    name='1',
                    nullable=1,
                    precision=5,
                    scale=6,
                    tableName=None,
                    type=None,
                    typeName=None,
                ),
                ColumnMetadata(
                    arrayBaseColumnType=0,
                    isAutoIncrement=False,
                    isCaseSensitive=False,
                    isCurrency=False,
                    isSigned=False,
                    label='8',
                    name='8',
                    nullable=1,
                    precision=12,
                    scale=13,
                    tableName=None,
                    type=None,
                    typeName=None,
                ),
            ],
        ).dict()
    )

    cursor_mock.execute.assert_called_once_with('select * from users')
    cursor_mock.close.assert_called_once_with()
示例#24
0
 def get_field_from_value(self, value: Any) -> Field:
     if type(value).__name__.endswith('BigInteger'):
         return Field(longValue=int(str(value)))
     else:
         return super().get_field_from_value(value)
示例#25
0
def test_from_value() -> None:
    assert Field.from_value('str') == Field(stringValue='str')
    assert Field.from_value(123) == Field(longValue=123)
    assert Field.from_value(1.23) == Field(doubleValue=1.23)
    assert Field.from_value(True) == Field(booleanValue=True)
    assert Field.from_value(False) == Field(booleanValue=False)
    assert Field.from_value(b'bytes') == Field(blobValue=b64encode(b'bytes'))
    assert Field.from_value(None) == Field(isNull=True)

    class Dummy:
        pass

    with pytest.raises(Exception):
        Field.from_value(Dummy())