Skip to content

Commit

Permalink
MySQL DB extension
Browse files Browse the repository at this point in the history
  • Loading branch information
gs-ssh16 authored and gs-ssh16 committed Nov 6, 2023
1 parent e28f60b commit 21cefd6
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 1 deletion.
2 changes: 2 additions & 0 deletions pylegend/core/tds/tds_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

postgres_ext = 'pylegend.extensions.database.vendors.postgres.postgres_sql_to_string'
importlib.import_module(postgres_ext)
mysql_ext = 'pylegend.extensions.database.vendors.mysql.mysql_sql_to_string'
importlib.import_module(mysql_ext)

__all__: PyLegendSequence[str] = [
"PyLegendTdsFrame",
Expand Down
13 changes: 13 additions & 0 deletions pylegend/extensions/database/vendors/mysql/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2023 Goldman Sachs
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
46 changes: 46 additions & 0 deletions pylegend/extensions/database/vendors/mysql/mysql_sql_to_string.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright 2023 Goldman Sachs
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from pylegend.core.databse.sql_to_string import (
SqlToStringGenerator,
SqlToStringDbExtension,
)
from pylegend._typing import PyLegendSequence


__all__: PyLegendSequence[str] = [
"MySQLSqlToStringGenerator"
]


class MySQLSqlToStringDbExtension(SqlToStringDbExtension):

@classmethod
def quote_character(cls) -> str:
return "`"


class MySQLSqlToStringGenerator(SqlToStringGenerator):
__sql_to_string_db_extension: SqlToStringDbExtension = MySQLSqlToStringDbExtension()

@classmethod
def database_type(cls) -> str:
return "MySQL"

@classmethod
def create_sql_generator(cls) -> SqlToStringGenerator:
return MySQLSqlToStringGenerator()

def get_db_extension(self) -> SqlToStringDbExtension:
return self.__sql_to_string_db_extension
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ mockito = ">=1.0.0"
testcontainers = ">=3.0.0"
sqlalchemy = ">=2.0.0"
pg8000 = ">=1.0.0"
pymysql = ">=1.0.0"
cryptography = ">=40.0.0"

[build-system]
requires = ["poetry-core"]
Expand Down
2 changes: 1 addition & 1 deletion tests/core/database/test_sql_gen_e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def test_literal(self, db_test):
def wrap_and_execute_expression(self, db_test, expr):
wrapped = QuerySpecification(
select=Select(
selectItems=[SingleColumn(alias="res", expression=expr)],
selectItems=[SingleColumn(alias=self.db_extension().quote_identifier("res"), expression=expr)],
distinct=False
),
from_=[],
Expand Down
13 changes: 13 additions & 0 deletions tests/extensions/database/vendors/mysql/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2023 Goldman Sachs
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
42 changes: 42 additions & 0 deletions tests/extensions/database/vendors/mysql/test_mysql_sql_gen_e2e.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright 2023 Goldman Sachs
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


# type: ignore
import pytest
import platform
import sqlalchemy
from testcontainers.mysql import MySqlContainer
from tests.core.database.test_sql_gen_e2e import E2EDbSpecificSqlGenerationTest
from pylegend.extensions.database.vendors.mysql.mysql_sql_to_string import MySQLSqlToStringGenerator


@pytest.mark.skipif(platform.system() in ("Windows", "Darwin"), reason="Skip on windows and macos")
class TestMySQLE2ESqlGeneration(E2EDbSpecificSqlGenerationTest):
extension = MySQLSqlToStringGenerator.create_sql_generator().get_db_extension()

@pytest.fixture(scope='module')
def db_test(self):
with MySqlContainer() as c:
engine = sqlalchemy.create_engine(c.get_connection_url())
yield {
"engine": engine
}

def execute_sql(self, db_test, sql):
with db_test["engine"].connect() as c:
return c.execute(sqlalchemy.text(sql))

def db_extension(self):
return self.extension
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright 2023 Goldman Sachs
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import importlib
from pylegend.core.databse.sql_to_string import (
SqlToStringGenerator,
SqlToStringConfig,
SqlToStringFormat,
)

mysql_ext = 'pylegend.extensions.database.vendors.mysql.mysql_sql_to_string'
importlib.import_module(mysql_ext)


class TestMySQLSqlToString:
generator = SqlToStringGenerator.find_sql_to_string_generator_for_db_type("MySQL")
db_ext = generator.get_db_extension()

def test_find_mysql_sql_generator(self) -> None:
assert self.generator is not None
assert (str(type(self.generator)) ==
"<class 'pylegend.extensions.database.vendors.mysql.mysql_sql_to_string.MySQLSqlToStringGenerator'>")

def test_process_identifier(self) -> None:
config = SqlToStringConfig(SqlToStringFormat(pretty=False))
assert self.db_ext.process_identifier("A", config, True) == "`A`"
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Copyright 2023 Goldman Sachs
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import importlib
from pylegend.core.databse.sql_to_string import (
SqlToStringGenerator,
)

postgres_ext = 'pylegend.extensions.database.vendors.postgres.postgres_sql_to_string'
importlib.import_module(postgres_ext)


class TestPostgresSqlToString:
generator = SqlToStringGenerator.find_sql_to_string_generator_for_db_type("Postgres")
db_ext = generator.get_db_extension()

def test_find_postgres_sql_generator(self) -> None:
assert self.generator is not None
assert (str(type(self.generator)) ==
("<class 'pylegend.extensions.database.vendors."
"postgres.postgres_sql_to_string.PostgresSqlToStringGenerator'>"))

0 comments on commit 21cefd6

Please sign in to comment.