I wrote a simple text parser and a converter using Python 3.12.1.
The purpose is to read a text file that contains 20000 words one per line, and create an output file that contains all the queries.
Here is a snippet of the input file with fake values:
aaaaaaaa
bbbbbbbb
cccccccc
dddddddd
I got this file from an external source and I need to save those words in a database. For that reason, I need to read the input file and create the SQL queries. I can directly run the queries on the DB, but for simplicity, here I published a version with a text file for output.
I tried to implement the separation of concerns and the single responsability concept.
Here's my code:
#!/usr/bin/env python3
from abc import ABC, abstractmethod
class ParserInterface(ABC):
@abstractmethod
def parse(self) -> None:
pass
class ConverterInterface(ABC):
@abstractmethod
def convert(self, tablename: str = '', columnname: str = '') -> None:
pass
@abstractmethod
def writeOnFile(self, filename: str = '') -> None:
pass
class Parser(ParserInterface):
def __init__(self, filename: str = '') -> None:
if not filename:
raise Exception('Filename cannot be empty!')
self.filename = filename
self.tokens = set()
def parse(self) -> None:
with open(self.filename, 'r') as file:
while line := file.readline():
self.tokens.add(line.rstrip())
class TextToMySQLConverter(ConverterInterface):
def __init__(self) -> None:
self.tokens = set()
self.queries = set()
def setTokens(self, tokens: set = set()) -> None:
self.tokens = tokens
def convert(self, tablename: str = '', columnname: str = '') -> None:
if not tablename:
raise Exception('Tablename cannot be empty!')
if not columnname:
raise Exception('Columnname cannot be empty!')
for token in self.tokens:
query = 'INSERT INTO {0} ({1}) VALUES ("{2}");'.format(tablename, columnname, token)
self.queries.add(query)
def writeOnFile(self, filename: str = '') -> None:
if not filename:
raise Exception('Filename cannot be empty!')
with open(filename,'w') as file:
for query in self.queries:
file.write('{0}\n'.format(query))
class Manager:
def __init__(self, parser: ParserInterface = None, converter: ConverterInterface = None) -> None:
if not parser:
raise Exception('Parser cannot be None!')
if not converter:
raise Exception('Converter cannot be None!')
self.parser = parser
self.converter = converter
self.outputFilename = ''
self.tableName = ''
self.columnName = ''
def setOutputFilename(self, filename: str = '') -> None:
if not filename:
raise Exception('Filename cannot be empty!')
self.outputFilename = filename
def setTableName(self, tableName: str = '') -> None:
if not tableName:
raise Exception('Filename cannot be empty!')
self.tableName = tableName
def setColumnName(self, columnName: str = '') -> None:
if not columnName:
raise Exception('Filename cannot be empty!')
self.columnName = columnName
def process(self):
self.parser.parse()
tokens = self.parser.tokens
converter.setTokens(tokens)
converter.convert(self.tableName, self.columnName)
converter.writeOnFile(self.outputFilename)
if __name__ == "__main__":
parser = Parser('original.txt')
converter = TextToMySQLConverter() # We can implement a strategy here
manager = Manager(parser, converter)
manager.setOutputFilename('queries.txt')
manager.setTableName("tablename")
manager.setColumnName("columname")
manager.process()