diff --git a/pyreportjasper/config.py b/pyreportjasper/config.py index 0a8e98e..9d21909 100644 --- a/pyreportjasper/config.py +++ b/pyreportjasper/config.py @@ -16,6 +16,7 @@ class Config: dbType = None dbUrl = None dbUser = None + dbOracleMultitenant = False verbose = None input = None jdbcDir = None @@ -46,7 +47,7 @@ class Config: subreports = {} jvm_opts = () - jvm_maxmem = '512M' + jvm_maxmem = '1G' jvm_classpath = None def has_output(self): diff --git a/pyreportjasper/db.py b/pyreportjasper/db.py index 67bb5a1..90dfd8f 100644 --- a/pyreportjasper/db.py +++ b/pyreportjasper/db.py @@ -19,6 +19,7 @@ class Db: JRXmlDataSource = None JsonDataSource = None JsonQLDataSource = None + HikariDataSource = None def __init__(self): self.Connection = jpype.JPackage('java').sql.Connection @@ -33,6 +34,55 @@ def __init__(self): self.File = jpype.JPackage('java').io.File self.URL = jpype.JPackage('java').net.URL self.ByteArrayInputStream = jpype.JPackage('java').io.ByteArrayInputStream + self.HikariDataSource = jpype.JPackage('com.zaxxer.hikari').HikariDataSource + self.HikariConfig = jpype.JPackage('com.zaxxer.hikari').HikariConfig + self.config_pool = None + + def initialize_pool(self, config: Config): + dbtype = config.dbType + host = config.dbHost + user = config.dbUser + passwd = config.dbPasswd + driver = None + dbname = None + port = None + sid = None + connect_string = None + multitenant = None + + if dbtype == "mysql": + driver = config.dbDriver + port = config.dbPort or 3306 + dbname = config.dbName + connect_string = f"jdbc:mysql://{host}:{port}/{dbname}?useSSL=false" + elif dbtype == "postgres": + driver = config.dbDriver + port = config.dbPort or 5434 + dbname = config.dbName + connect_string = f"jdbc:postgresql://{host}:{port}/{dbname}" + elif dbtype == "oracle": + driver = config.dbDriver + port = config.dbPort or 1521 + sid = config.dbSid + multitenant = config.dbOracleMultitenant + connect_string = ( + f"jdbc:oracle:thin:@{host}:{port}/{sid}" if multitenant else f"jdbc:oracle:thin:@{host}:{port}:{sid}" + ) + elif dbtype == "generic": + driver = config.dbDriver + connect_string = config.dbUrl + + self.Class.forName(driver) + hikari_config = self.HikariConfig() + hikari_config.setJdbcUrl(connect_string) + hikari_config.setUsername(user) + hikari_config.setPassword(passwd) + hikari_config.setMaximumPoolSize(10) # Máximo de conexiones en el pool + hikari_config.setMinimumIdle(2) # Mínimo de conexiones en el pool + hikari_config.setIdleTimeout(30000) # Tiempo de espera para conexiones inactivas (ms) + hikari_config.setConnectionTimeout(10000) # Tiempo de espera para obtener una conexión (ms) + + self.config_pool = self.HikariDataSource(hikari_config) def get_csv_datasource(self, config: Config): ds = self.JRCsvDataSource(self.get_data_file_input_stream(config), config.csvCharset) @@ -51,7 +101,7 @@ def get_json_datasource(self, config: Config): if config.dataURL: ds = self.JsonDataSource(self.get_data_url_input_stream(config), config.jsonQuery) else: - ds = self.JsonDataSource(self.get_data_file_input_stream(config), config.jsonQuery) + ds = self.JsonDataSource(self.get_data_file_input_stream(config), config.jsonQuery) return jpype.JObject(ds, self.JsonDataSource) def get_jsonql_datasource(self, config: Config): @@ -63,48 +113,19 @@ def get_data_file_input_stream(self, config: Config): bytes_data_file = None if isinstance(data_file, str) or isinstance(data_file, pathlib.PurePath): if not os.path.isfile(data_file): - raise NameError('dataFile is not file') - with open(data_file, 'rb') as file: - bytes_data_file = file.read() + raise NameError("dataFile is not file") + with open(data_file, "rb") as file: + bytes_data_file = file.read() elif isinstance(data_file, bytes): bytes_data_file = data_file else: - raise NameError('dataFile does not have a valid type. Please enter the file path or its bytes') + raise NameError("dataFile does not have a valid type. Please enter the file path or its bytes") return self.ByteArrayInputStream(bytes_data_file) - - def get_data_url_input_stream(self, config: Config): - return self.JRLoader.getInputStream(self.URL(config.dataURL)) - - def get_connection(self, config: Config): - dbtype = config.dbType - host = config.dbHost - user = config.dbUser - passwd = config.dbPasswd - driver = None - dbname = None - port = None - sid = None - connect_string = None - if dbtype == "mysql": - driver = config.dbDriver - port = config.dbPort or 3306 - dbname = config.dbName - connect_string = "jdbc:mysql://{}:{}/{}?useSSL=false".format(host, port, dbname) - elif dbtype == "postgres": - driver = config.dbDriver - port = config.dbPort or 5434 - dbname = config.dbName - connect_string = "jdbc:postgresql://{}:{}/{}".format(host, port, dbname) - elif dbtype == "oracle": - driver = config.dbDriver - port = config.dbPort or 1521 - sid = config.dbSid - connect_string = "jdbc:oracle:thin:@{}:{}:{}".format(host, port, sid) - elif dbtype == "generic": - driver = config.dbDriver - connect_string = config.dbUrl + def get_data_url_input_stream(self, config: Config): + return self.JRLoader.getInputStream(self.URL(config.dataURL)) - self.Class.forName(driver) - conn = self.DriverManager.getConnection(connect_string, user, passwd) - return conn + def get_connection(self): + if self.config_pool is None: + raise NameError("El pool de conexiones no está inicializado.") + return self.config_pool.getConnection() diff --git a/pyreportjasper/libs/HikariCP-6.2.1.jar b/pyreportjasper/libs/HikariCP-6.2.1.jar new file mode 100644 index 0000000..c149579 Binary files /dev/null and b/pyreportjasper/libs/HikariCP-6.2.1.jar differ diff --git a/pyreportjasper/libs/jdbc/ojdbc8.jar b/pyreportjasper/libs/jdbc/ojdbc8.jar new file mode 100644 index 0000000..4c92806 Binary files /dev/null and b/pyreportjasper/libs/jdbc/ojdbc8.jar differ diff --git a/pyreportjasper/pyreportjasper.py b/pyreportjasper/pyreportjasper.py index 7966e31..52c2b7f 100644 --- a/pyreportjasper/pyreportjasper.py +++ b/pyreportjasper/pyreportjasper.py @@ -37,7 +37,8 @@ class PyReportJasper: 'csv_meta', 'ods', 'pptx', - 'jrprint' + 'jrprint', + 'stream_pdf' ) METHODS = ('GET', 'POST', 'PUT') @@ -76,6 +77,7 @@ def config(self, input_file, output_file=False, output_formats=['pdf'], paramete 'jdbc_url': 'dbUrl', 'jdbc_dir': 'jdbcDir', 'db_sid': 'dbSid', + 'db_multitenant': 'dbOracleMultitenant', 'xml_xpath': 'xmlXpath', 'data_file': 'dataFile', 'data_url': 'data_url', @@ -175,15 +177,20 @@ def process_report(self): 'csv_meta': report.export_csv_meta, 'ods': report.export_ods, 'pptx': report.export_pptx, - 'jrprint': report.export_jrprint + 'jrprint': report.export_jrprint, + 'stream_pdf': report.fetch_pdf_report } for f in self.config.outputFormats: export_function = formats_functions.get(f) if export_function: - export_function() + if f == 'stream_pdf': + pdf_bytes =export_function() + else: + export_function() else: raise NameError("Error output format {} not implemented!".format(f)) + return pdf_bytes except Exception as ex: error = NameError("Error export format: {}".format(ex)) except Exception as ex: diff --git a/pyreportjasper/report.py b/pyreportjasper/report.py index 86114c9..36d4904 100644 --- a/pyreportjasper/report.py +++ b/pyreportjasper/report.py @@ -365,9 +365,9 @@ def get_output_stream_pdf(self): def fetch_pdf_report(self): output_stream_pdf = self.get_output_stream_pdf() - res = self.String(output_stream_pdf.toByteArray(), 'UTF-8') - return bytes(str(res), 'UTF-8') + return output_stream_pdf.toByteArray() + def export_pdf(self): output_stream = self.get_output_stream('.pdf') output_stream_pdf = self.get_output_stream_pdf()