Skip to content

Commit

Permalink
Merge PR #873 into 16.0
Browse files Browse the repository at this point in the history
Signed-off-by legalsylvain
  • Loading branch information
OCA-git-bot committed Nov 6, 2024
2 parents 3e0e4dd + 5811a07 commit b79d175
Show file tree
Hide file tree
Showing 22 changed files with 798 additions and 0 deletions.
1 change: 1 addition & 0 deletions setup/sql_export_delta/odoo/addons/sql_export_delta
6 changes: 6 additions & 0 deletions setup/sql_export_delta/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
4 changes: 4 additions & 0 deletions sql_export/models/sql_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ class SqlExport(models.Model):
default="utf-8",
)

keep_generated_file = fields.Boolean(
help="Check this to keep generated export files as attachments"
)

def _compute_use_properties(self):
for rec in self:
rec.use_properties = bool(rec.query_properties_definition)
Expand Down
13 changes: 13 additions & 0 deletions sql_export/tests/test_sql_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,16 @@ def test_sql_query_with_params(self):
wizard.export_sql()
export = base64.b64decode(wizard.binary_file)
self.assertTrue(export)

def test_keep_generated_file(self):
"""Test that we keep generated files"""
self.sql_report_demo.keep_generated_file = True
wizard = self.wizard_obj.create(
{
"sql_export_id": self.sql_report_demo.id,
}
)
wizard.export_sql()
attachment = wizard._get_field_attachment()
wizard.sudo().unlink()
self.assertTrue(attachment.exists())
5 changes: 5 additions & 0 deletions sql_export/views/sql_export_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@
name="file_format"
attrs="{'readonly': [('state', '!=', 'draft')]}"
/>
<field
name="keep_generated_file"
attrs="{'invisible': [('file_format', '!=', 'csv')], 'required': [('file_format', '=', 'csv')], 'readonly': [('state', '!=', 'draft')]}"
groups="base.group_no_one"
/>
<field
name="copy_options"
attrs="{'invisible': [('file_format', '!=', 'csv')], 'required': [('file_format', '=', 'csv')], 'readonly': [('state', '!=', 'draft')]}"
Expand Down
28 changes: 28 additions & 0 deletions sql_export/wizard/wizard_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from datetime import datetime
from mimetypes import guess_type

from odoo import _, fields, models
from odoo.exceptions import UserError
Expand Down Expand Up @@ -78,6 +79,12 @@ def export_sql(self):
sql_export.id,
),
)
self._get_field_attachment().write(
{
"name": self.file_name,
"mimetype": guess_type(self.file_name)[0],
}
)
action = {
"name": "SQL Export",
"type": "ir.actions.act_url",
Expand All @@ -87,3 +94,24 @@ def export_sql(self):
"target": "self",
}
return action

def _get_field_attachment(self):
"""Return the attachment of the binary_file field"""
return self.env["ir.attachment"].search(
[
("res_model", "=", self._name),
("res_id", "in", self.ids),
("res_field", "=", "binary_file"),
],
)

def unlink(self):
for this in self.filtered("sql_export_id.keep_generated_file"):
this._get_field_attachment().write(
{
"res_model": this.sql_export_id._name,
"res_id": this.sql_export_id.id,
"res_field": None,
}
)
return super().unlink()
99 changes: 99 additions & 0 deletions sql_export_delta/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
==========================
SQL Export (delta support)
==========================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:9494034b2f072b0d68ca3c3736ce6176299e3fede3f85b06ae004461e90f8431
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
:target: https://odoo-community.org/page/development-status
:alt: Alpha
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Freporting--engine-lightgray.png?logo=github
:target: https://github.com/OCA/reporting-engine/tree/16.0/sql_export_delta
:alt: OCA/reporting-engine
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/reporting-engine-16-0/reporting-engine-16-0-sql_export_delta
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/reporting-engine&target_branch=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module extends the functionality of ``sql_export`` to allow you to
only export changes between export runs.

.. IMPORTANT::
This is an alpha version, the data model and design can change at any time without warning.
Only for development or testing purpose, do not use in production.
`More details on development status <https://odoo-community.org/page/development-status>`_

**Table of contents**

.. contents::
:local:

Configuration
=============

To configure this module, you need to:

1. Go to an export in draft mode
2. Check the flag 'Delta'

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/reporting-engine/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/reporting-engine/issues/new?body=module:%20sql_export_delta%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Hunki Enterprises BV

Contributors
------------

- Holger Brunn <[email protected]>
(https://hunki-enterprises.com)

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-hbrunn| image:: https://github.com/hbrunn.png?size=40px
:target: https://github.com/hbrunn
:alt: hbrunn

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-hbrunn|

This module is part of the `OCA/reporting-engine <https://github.com/OCA/reporting-engine/tree/16.0/sql_export_delta>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
3 changes: 3 additions & 0 deletions sql_export_delta/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import models
from . import wizards
from .hooks import uninstall_hook
26 changes: 26 additions & 0 deletions sql_export_delta/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright 2024 Hunki Enterprises BV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0)

{
"name": "SQL Export (delta support)",
"summary": "Support exporting only the changes from last export",
"version": "16.0.1.0.0",
"development_status": "Alpha",
"category": "Extra Tools",
"website": "https://github.com/OCA/reporting-engine",
"author": "Hunki Enterprises BV, Odoo Community Association (OCA)",
"maintainers": ["hbrunn"],
"license": "AGPL-3",
"uninstall_hook": "uninstall_hook",
"external_dependencies": {
"python": [],
"bin": [],
},
"depends": [
"sql_export",
],
"data": [
"views/sql_export.xml",
],
"demo": [],
}
9 changes: 9 additions & 0 deletions sql_export_delta/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright 2024 Hunki Enterprises BV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0)
from odoo import SUPERUSER_ID, api


def uninstall_hook(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {})
for export in env["sql.export"].search([]):
export._export_delta_cleanup(keep_last=False)
1 change: 1 addition & 0 deletions sql_export_delta/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import sql_export
98 changes: 98 additions & 0 deletions sql_export_delta/models/sql_export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Copyright 2024 Hunki Enterprises BV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl-3.0)

from psycopg2.sql import SQL, Identifier

from odoo import fields, models


class SqlExport(models.Model):
_inherit = "sql.export"

export_delta = fields.Boolean(
string="Delta",
help="With this checked, the full result of the query "
"will be stored as table in the database, but the file generated will "
"only contain rows not existing in the n-1st export",
)

def write(self, vals):
"""Delete previous results when we change the query"""
if "query" in vals:
for this in self:
this._export_delta_cleanup(keep_last=False)
return super().write(vals)

def _execute_sql_request(
self,
params=None,
mode="fetchall",
rollback=True,
view_name=False,
copy_options="CSV HEADER DELIMITER ';'",
header=False,
):
delta_id = self.env.context.get("export_delta_id")

if delta_id:
original_query = self.env.cr.mogrify(self.query, params).decode("utf-8")
result_table = self._export_delta_table_name(delta_id)
table_query = SQL(
"WITH result as ({0}) SELECT * INTO TABLE {1} FROM result"
).format(SQL(original_query), Identifier(result_table))
previous_result_table = self._export_delta_existing_tables()[-1:]
if previous_result_table:
result_query = SQL("SELECT * FROM {0} EXCEPT SELECT * FROM {1}").format(
Identifier(result_table),
Identifier(previous_result_table[0]),
)
else:
result_query = SQL("SELECT * FROM {0}").format(Identifier(result_table))
self.env.cr.execute(table_query)
# inject new query in cache for super to use
self._cache["query"] = result_query
result = super()._execute_sql_request(
params=None,
mode=mode,
rollback=rollback,
view_name=view_name,
copy_options=copy_options,
header=header,
)
self.invalidate_recordset(["query"])
self._export_delta_cleanup(keep_last=True)
else:
result = super()._execute_sql_request(
params=params,
mode=mode,
rollback=rollback,
view_name=view_name,
copy_options=copy_options,
header=header,
)

return result

def _export_delta_table_name(self, identifier):
"""
Return the name of a table to store data for delta export, must end with
{identifier}
"""
return f"sql_export_delta_{self.id}_{identifier}"

def _export_delta_existing_tables(self):
"""Return all table names used for storing data for delta export"""
self.env.cr.execute(
"SELECT table_name FROM information_schema.tables WHERE table_name LIKE %s",
(self._export_delta_table_name("%"),),
)
return sorted(
[name for name, in self.env.cr.fetchall()],
key=lambda name: int(name[len(self._export_delta_table_name("")) :]),
)

def _export_delta_cleanup(self, keep_last=True):
"""Delete tables storing data for delta export"""
table_names = self._export_delta_existing_tables()[: -1 if keep_last else None]
for table_name in table_names:
self.env.cr.execute(SQL("DROP TABLE {0}").format(Identifier(table_name)))
4 changes: 4 additions & 0 deletions sql_export_delta/readme/CONFIGURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
To configure this module, you need to:

1. Go to an export in draft mode
2. Check the flag 'Delta'
1 change: 1 addition & 0 deletions sql_export_delta/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Holger Brunn \<[email protected]> (https://hunki-enterprises.com)
1 change: 1 addition & 0 deletions sql_export_delta/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This module extends the functionality of ``sql_export`` to allow you to only export changes between export runs.
Binary file added sql_export_delta/static/description/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit b79d175

Please sign in to comment.