Browse Source
[IMP] base_external_dbsource: Refactor & Split by source
[IMP] base_external_dbsource: Refactor & Split by source
* Heavily refactor code for reusability * Split all sources into independent modules * Add more test coverage * Add CRUD methods * Add iterator execute return to roadmappull/659/head
Dave Lasley
8 years ago
No known key found for this signature in database
GPG Key ID: 7DDBA4BA81B934CF
56 changed files with 1827 additions and 217 deletions
-
2.travis.yml
-
33base_external_dbsource/README.rst
-
1base_external_dbsource/__init__.py
-
6base_external_dbsource/__manifest__.py
-
13base_external_dbsource/exceptions.py
-
1base_external_dbsource/models/__init__.py
-
421base_external_dbsource/models/base_external_dbsource.py
-
2base_external_dbsource/tests/__init__.py
-
247base_external_dbsource/tests/test_base_external_dbsource.py
-
66base_external_dbsource/tests/test_create_dbsource.py
-
77base_external_dbsource_firebird/README.rst
-
2base_external_dbsource_firebird/__init__.py
-
28base_external_dbsource_firebird/__manifest__.py
-
9base_external_dbsource_firebird/demo/base_external_dbsource.xml
-
3base_external_dbsource_firebird/models/__init__.py
-
56base_external_dbsource_firebird/models/base_external_dbsource.py
-
3base_external_dbsource_firebird/tests/__init__.py
-
41base_external_dbsource_firebird/tests/test_base_external_dbsource.py
-
80base_external_dbsource_mssql/README.rst
-
2base_external_dbsource_mssql/__init__.py
-
29base_external_dbsource_mssql/__manifest__.py
-
9base_external_dbsource_mssql/demo/base_external_dbsource.xml
-
3base_external_dbsource_mssql/models/__init__.py
-
45base_external_dbsource_mssql/models/base_external_dbsource.py
-
3base_external_dbsource_mssql/tests/__init__.py
-
42base_external_dbsource_mssql/tests/test_base_external_dbsource.py
-
80base_external_dbsource_mysql/README.rst
-
2base_external_dbsource_mysql/__init__.py
-
29base_external_dbsource_mysql/__manifest__.py
-
9base_external_dbsource_mysql/demo/base_external_dbsource.xml
-
3base_external_dbsource_mysql/models/__init__.py
-
43base_external_dbsource_mysql/models/base_external_dbsource.py
-
3base_external_dbsource_mysql/tests/__init__.py
-
42base_external_dbsource_mysql/tests/test_base_external_dbsource.py
-
79base_external_dbsource_odbc/README.rst
-
2base_external_dbsource_odbc/__init__.py
-
29base_external_dbsource_odbc/__manifest__.py
-
9base_external_dbsource_odbc/demo/base_external_dbsource.xml
-
3base_external_dbsource_odbc/models/__init__.py
-
42base_external_dbsource_odbc/models/base_external_dbsource.py
-
3base_external_dbsource_odbc/tests/__init__.py
-
46base_external_dbsource_odbc/tests/test_base_external_dbsource.py
-
79base_external_dbsource_oracle/README.rst
-
2base_external_dbsource_oracle/__init__.py
-
25base_external_dbsource_oracle/__manifest__.py
-
3base_external_dbsource_oracle/models/__init__.py
-
47base_external_dbsource_oracle/models/base_external_dbsource.py
-
77base_external_dbsource_sqlite/README.rst
-
2base_external_dbsource_sqlite/__init__.py
-
28base_external_dbsource_sqlite/__manifest__.py
-
9base_external_dbsource_sqlite/demo/base_external_dbsource.xml
-
3base_external_dbsource_sqlite/models/__init__.py
-
59base_external_dbsource_sqlite/models/base_external_dbsource.py
-
3base_external_dbsource_sqlite/tests/__init__.py
-
42base_external_dbsource_sqlite/tests/test_base_external_dbsource.py
-
5requirements.txt
@ -1,2 +1,3 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
from . import models |
@ -0,0 +1,13 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2016 LasLabs Inc. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
|
|||
from odoo.exceptions import UserError |
|||
|
|||
|
|||
class ConnectionFailedError(UserError): |
|||
pass |
|||
|
|||
|
|||
class ConnectionSuccessError(UserError): |
|||
pass |
@ -1,2 +1,3 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
from . import base_external_dbsource |
@ -1,3 +1,3 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
|
|||
from . import test_create_dbsource |
|||
from . import test_base_external_dbsource |
@ -0,0 +1,247 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2016 LasLabs Inc. |
|||
|
|||
import mock |
|||
|
|||
from odoo.tests import common |
|||
|
|||
from ..exceptions import ConnectionFailedError, ConnectionSuccessError |
|||
|
|||
|
|||
class TestBaseExternalDbsource(common.TransactionCase): |
|||
|
|||
def setUp(self): |
|||
super(TestBaseExternalDbsource, self).setUp() |
|||
self.dbsource = self.env.ref('base_external_dbsource.demo_postgre') |
|||
|
|||
def _test_adapter_method( |
|||
self, method_name, side_effect=None, return_value=None, |
|||
create=False, args=None, kwargs=None, |
|||
): |
|||
if args is None: |
|||
args = [] |
|||
if kwargs is None: |
|||
kwargs = {} |
|||
adapter = '%s_postgresql' % method_name |
|||
with mock.patch.object(self.dbsource, |
|||
adapter, create=create) as adapter: |
|||
if side_effect is not None: |
|||
adapter.side_effect = side_effect |
|||
elif return_value is not None: |
|||
adapter.return_value = return_value |
|||
res = getattr(self.dbsource, method_name)(*args, **kwargs) |
|||
return res, adapter |
|||
|
|||
def test_conn_string_full(self): |
|||
""" It should add password if string interpolation not detected """ |
|||
self.dbsource.conn_string = 'User=Derp;' |
|||
self.dbsource.password = 'password' |
|||
expect = self.dbsource.conn_string + 'PWD=%s;' % self.dbsource.password |
|||
self.assertEqual( |
|||
self.dbsource.conn_string_full, expect, |
|||
) |
|||
|
|||
# Interface |
|||
|
|||
def test_connection_success(self): |
|||
""" It should raise for successful connection """ |
|||
with self.assertRaises(ConnectionSuccessError): |
|||
self.dbsource.connection_test() |
|||
|
|||
def test_connection_fail(self): |
|||
""" It should raise for failed/invalid connection """ |
|||
with mock.patch.object(self.dbsource, 'connection_open') as conn: |
|||
conn.side_effect = Exception |
|||
with self.assertRaises(ConnectionFailedError): |
|||
self.dbsource.connection_test() |
|||
|
|||
def test_connection_open_calls_close(self): |
|||
""" It should close connection after context ends """ |
|||
with mock.patch.object( |
|||
self.dbsource, 'connection_close', |
|||
) as close: |
|||
with self.dbsource.connection_open(): |
|||
pass |
|||
close.assert_called_once() |
|||
|
|||
def test_connection_close(self): |
|||
""" It should call adapter's close method """ |
|||
args = [mock.MagicMock()] |
|||
res, adapter = self._test_adapter_method( |
|||
'connection_close', args=args, |
|||
) |
|||
adapter.assert_called_once_with(args[0]) |
|||
|
|||
def test_execute_asserts_query_arg(self): |
|||
""" It should raise a TypeError if query and sqlquery not in args """ |
|||
with self.assertRaises(TypeError): |
|||
self.dbsource.execute() |
|||
|
|||
def test_execute_calls_adapter(self): |
|||
""" It should call the adapter methods with proper args """ |
|||
expect = ('query', 'execute', 'metadata') |
|||
return_value = 'rows', 'cols' |
|||
res, adapter = self._test_adapter_method( |
|||
'execute', args=expect, return_value=return_value, |
|||
) |
|||
adapter.assert_called_once_with(*expect) |
|||
|
|||
def test_execute_return(self): |
|||
""" It should return rows if not metadata """ |
|||
expect = (True, True, False) |
|||
return_value = 'rows', 'cols' |
|||
res, adapter = self._test_adapter_method( |
|||
'execute', args=expect, return_value=return_value, |
|||
) |
|||
self.assertEqual(res, return_value[0]) |
|||
|
|||
def test_execute_return_metadata(self): |
|||
""" It should return rows and cols if metadata """ |
|||
expect = (True, True, True) |
|||
return_value = 'rows', 'cols' |
|||
res, adapter = self._test_adapter_method( |
|||
'execute', args=expect, return_value=return_value, |
|||
) |
|||
self.assertEqual( |
|||
res, |
|||
{'rows': return_value[0], |
|||
'cols': return_value[1]}, |
|||
) |
|||
|
|||
def test_remote_browse(self): |
|||
""" It should call the adapter method with proper args """ |
|||
args = [1], 'args' |
|||
kwargs = {'kwargs': True} |
|||
self.dbsource.current_table = 'table' |
|||
res, adapter = self._test_adapter_method( |
|||
'remote_browse', create=True, args=args, kwargs=kwargs, |
|||
) |
|||
adapter.assert_called_once_with(*args, **kwargs) |
|||
self.assertEqual(res, adapter()) |
|||
|
|||
def test_remote_browse_asserts_current_table(self): |
|||
""" It should raise AssertionError if a table not selected """ |
|||
args = [1], 'args' |
|||
kwargs = {'kwargs': True} |
|||
with self.assertRaises(AssertionError): |
|||
res, adapter = self._test_adapter_method( |
|||
'remote_browse', create=True, args=args, kwargs=kwargs, |
|||
) |
|||
|
|||
def test_remote_create(self): |
|||
""" It should call the adapter method with proper args """ |
|||
args = {'val': 'Value'}, 'args' |
|||
kwargs = {'kwargs': True} |
|||
self.dbsource.current_table = 'table' |
|||
res, adapter = self._test_adapter_method( |
|||
'remote_create', create=True, args=args, kwargs=kwargs, |
|||
) |
|||
adapter.assert_called_once_with(*args, **kwargs) |
|||
self.assertEqual(res, adapter()) |
|||
|
|||
def test_remote_create_asserts_current_table(self): |
|||
""" It should raise AssertionError if a table not selected """ |
|||
args = [1], 'args' |
|||
kwargs = {'kwargs': True} |
|||
with self.assertRaises(AssertionError): |
|||
res, adapter = self._test_adapter_method( |
|||
'remote_create', create=True, args=args, kwargs=kwargs, |
|||
) |
|||
|
|||
def test_remote_delete(self): |
|||
""" It should call the adapter method with proper args """ |
|||
args = [1], 'args' |
|||
kwargs = {'kwargs': True} |
|||
self.dbsource.current_table = 'table' |
|||
res, adapter = self._test_adapter_method( |
|||
'remote_delete', create=True, args=args, kwargs=kwargs, |
|||
) |
|||
adapter.assert_called_once_with(*args, **kwargs) |
|||
self.assertEqual(res, adapter()) |
|||
|
|||
def test_remote_delete_asserts_current_table(self): |
|||
""" It should raise AssertionError if a table not selected """ |
|||
args = [1], 'args' |
|||
kwargs = {'kwargs': True} |
|||
with self.assertRaises(AssertionError): |
|||
res, adapter = self._test_adapter_method( |
|||
'remote_delete', create=True, args=args, kwargs=kwargs, |
|||
) |
|||
|
|||
def test_remote_search(self): |
|||
""" It should call the adapter method with proper args """ |
|||
args = {'search': 'query'}, 'args' |
|||
kwargs = {'kwargs': True} |
|||
self.dbsource.current_table = 'table' |
|||
res, adapter = self._test_adapter_method( |
|||
'remote_search', create=True, args=args, kwargs=kwargs, |
|||
) |
|||
adapter.assert_called_once_with(*args, **kwargs) |
|||
self.assertEqual(res, adapter()) |
|||
|
|||
def test_remote_search_asserts_current_table(self): |
|||
""" It should raise AssertionError if a table not selected """ |
|||
args = [1], 'args' |
|||
kwargs = {'kwargs': True} |
|||
with self.assertRaises(AssertionError): |
|||
res, adapter = self._test_adapter_method( |
|||
'remote_search', create=True, args=args, kwargs=kwargs, |
|||
) |
|||
|
|||
def test_remote_update(self): |
|||
""" It should call the adapter method with proper args """ |
|||
args = [1], {'vals': 'Value'}, 'args' |
|||
kwargs = {'kwargs': True} |
|||
self.dbsource.current_table = 'table' |
|||
res, adapter = self._test_adapter_method( |
|||
'remote_update', create=True, args=args, kwargs=kwargs, |
|||
) |
|||
adapter.assert_called_once_with(*args, **kwargs) |
|||
self.assertEqual(res, adapter()) |
|||
|
|||
def test_remote_update_asserts_current_table(self): |
|||
""" It should raise AssertionError if a table not selected """ |
|||
args = [1], 'args' |
|||
kwargs = {'kwargs': True} |
|||
with self.assertRaises(AssertionError): |
|||
res, adapter = self._test_adapter_method( |
|||
'remote_update', create=True, args=args, kwargs=kwargs, |
|||
) |
|||
|
|||
# Postgres |
|||
|
|||
def test_execute_postgresql(self): |
|||
""" It should call generic executor with proper args """ |
|||
expect = ('query', 'execute', 'metadata') |
|||
with mock.patch.object( |
|||
self.dbsource, '_execute_generic', autospec=True, |
|||
) as execute: |
|||
execute.return_value = 'rows', 'cols' |
|||
self.dbsource.execute(*expect) |
|||
execute.assert_called_once_with(*expect) |
|||
|
|||
# Old API Compat |
|||
|
|||
def test_execute_calls_adapter_old_api(self): |
|||
""" It should call the adapter correctly if old kwargs provided """ |
|||
expect = [None, None, 'metadata'] |
|||
with mock.patch.object( |
|||
self.dbsource, 'execute_postgresql', autospec=True, |
|||
) as psql: |
|||
psql.return_value = 'rows', 'cols' |
|||
self.dbsource.execute( |
|||
*expect, sqlparams='params', sqlquery='query' |
|||
) |
|||
expect[0], expect[1] = 'query', 'params' |
|||
psql.assert_called_once_with(*expect) |
|||
|
|||
def test_conn_open(self): |
|||
""" It should return open connection for use """ |
|||
with mock.patch.object( |
|||
self.dbsource, 'connection_open', autospec=True, |
|||
) as connection: |
|||
res = self.dbsource.conn_open() |
|||
self.assertEqual( |
|||
res, |
|||
connection().__enter__(), |
|||
) |
@ -1,66 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
from odoo.exceptions import Warning as UserError |
|||
from odoo.tests import common |
|||
import logging |
|||
|
|||
|
|||
class TestCreateDbsource(common.TransactionCase): |
|||
"""Test class for base_external_dbsource.""" |
|||
|
|||
def test_create_dbsource(self): |
|||
"""source creation should succeed.""" |
|||
dbsource = self.env.ref('base_external_dbsource.demo_postgre') |
|||
try: |
|||
dbsource.connection_test() |
|||
except UserError as e: |
|||
logging.warning("Log = " + str(e)) |
|||
self.assertTrue(u'Everything seems properly set up!' in str(e)) |
|||
|
|||
def test_create_dbsource_failed(self): |
|||
"""source creation without connection string should failed.""" |
|||
dbsource = self.env.ref('base_external_dbsource.demo_postgre') |
|||
|
|||
# Connection without connection_string |
|||
dbsource.conn_string = "" |
|||
try: |
|||
dbsource.connection_test() |
|||
except UserError as e: |
|||
logging.warning("Log = " + str(e)) |
|||
self.assertTrue(u'Here is what we got instead:' in str(e)) |
|||
|
|||
def test_create_dbsource_without_connector_failed(self): |
|||
"""source creation with other connector should failed.""" |
|||
dbsource = self.env.ref('base_external_dbsource.demo_postgre') |
|||
|
|||
# Connection to mysql |
|||
try: |
|||
dbsource.connector = "mysql" |
|||
dbsource.connection_test() |
|||
except ValueError as e: |
|||
logging.warning("Log = " + str(e)) |
|||
self.assertTrue(u'Wrong value for' in str(e)) |
|||
|
|||
# Connection to mysql |
|||
try: |
|||
dbsource.connector = "pyodbc" |
|||
dbsource.connection_test() |
|||
except ValueError as e: |
|||
logging.warning("Log = " + str(e)) |
|||
self.assertTrue(u'Wrong value for' in str(e)) |
|||
|
|||
# Connection to oracle |
|||
try: |
|||
dbsource.connector = "cx_Oracle" |
|||
dbsource.connection_test() |
|||
except ValueError as e: |
|||
logging.warning("Log = " + str(e)) |
|||
self.assertTrue(u'Wrong value for' in str(e)) |
|||
|
|||
# Connection to firebird |
|||
try: |
|||
dbsource.connector = "fdb" |
|||
dbsource.connection_test() |
|||
except Exception as e: |
|||
logging.warning("Log = " + str(e)) |
|||
self.assertTrue(u'Wrong value for' in str(e)) |
@ -0,0 +1,77 @@ |
|||
.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg |
|||
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html |
|||
:alt: License: LGPL-3 |
|||
|
|||
=================================== |
|||
External Database Source - Firebird |
|||
=================================== |
|||
|
|||
This module extends ``base_external_dbsource``, allowing you to connect to |
|||
foreign Firebird databases. |
|||
|
|||
Installation |
|||
============ |
|||
|
|||
* Install ``fdb`` python library |
|||
|
|||
Configuration |
|||
============= |
|||
|
|||
Database sources can be configured in Settings > Configuration -> Data sources. |
|||
|
|||
|
|||
Usage |
|||
===== |
|||
|
|||
To use this module: |
|||
|
|||
* Go to Settings > Database Structure > Database Sources |
|||
* Click on Create to enter the following information: |
|||
|
|||
* Datasource name |
|||
* Pasword |
|||
* Connector: Choose the database to which you want to connect |
|||
* Connection string : Specify how to connect to database |
|||
|
|||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
|||
:alt: Try me on Runbot |
|||
:target: https://runbot.odoo-community.org/runbot/149/10.0 for server-tools |
|||
|
|||
Known issues / Roadmap |
|||
====================== |
|||
|
|||
* Setting ``metadata`` to ``True`` in ``execute_fdb`` will do nothing. |
|||
* ``execute`` is susceptible to SQL injection. |
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-tools/issues>`_. |
|||
In case of trouble, please check there if your issue has already been reported. |
|||
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback. |
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Contributors |
|||
------------ |
|||
|
|||
* Daniel Reis <dreis.pt@hotmail.com> |
|||
* Maxime Chambreuil <maxime.chambreuil@savoirfairelinux.com> |
|||
* Gervais Naoussi <gervaisnaoussi@gmail.com> |
|||
* Dave Lasley <dave@laslabs.com> |
|||
|
|||
Maintainer |
|||
---------- |
|||
|
|||
.. image:: https://odoo-community.org/logo.png |
|||
:alt: Odoo Community Association |
|||
:target: https://odoo-community.org |
|||
|
|||
This module is maintained by the OCA. |
|||
|
|||
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. |
|||
|
|||
To contribute to this module, please visit http://odoo-community.org. |
@ -0,0 +1,2 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import models |
@ -0,0 +1,28 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright <2011> <Daniel Reis, Maxime Chambreuil, Savoir-faire Linux> |
|||
# Copyright 2016 LasLabs Inc. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
{ |
|||
'name': 'External Database Source - Firebird', |
|||
'version': '10.0.1.0.0', |
|||
'category': 'Tools', |
|||
'author': "Daniel Reis, " |
|||
"LasLabs, " |
|||
"Odoo Community Association (OCA)", |
|||
'website': 'https://github.com/OCA/server-tools', |
|||
'license': 'LGPL-3', |
|||
'depends': [ |
|||
'base_external_dbsource', |
|||
], |
|||
# Uncomment this for v11 |
|||
# 'external_dependencies': { |
|||
# 'python': [ |
|||
# 'fdb', |
|||
# ] |
|||
# }, |
|||
'demo': [ |
|||
'demo/base_external_dbsource.xml', |
|||
], |
|||
'installable': True, |
|||
'auto_install': True, # Remove this key for v11 |
|||
} |
@ -0,0 +1,9 @@ |
|||
<?xml version="1.0"?> |
|||
<odoo> |
|||
<record model="base.external.dbsource" id="demo_firebird"> |
|||
<field name="name">Firebird Demo</field> |
|||
<field name="conn_string">User=firebird;Database=SampleDatabase.fdb;DataSource=localhost;Port=3050;Dialect=3;Charset=NONE;Role=;Connection lifetime=15;Pooling=true;MinPoolSize=0;MaxPoolSize=50;Packet Size=8192;ServerType=0;</field> |
|||
<field name="password">password</field> |
|||
<field name="connector">fdb</field> |
|||
</record> |
|||
</odoo> |
@ -0,0 +1,3 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
from . import base_external_dbsource |
@ -0,0 +1,56 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2011 Daniel Reis |
|||
# Copyright 2016 LasLabs Inc. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
|||
|
|||
import logging |
|||
|
|||
from odoo import api |
|||
from odoo import models |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
try: |
|||
from odoo.addons.base_external_dbsource.models import ( |
|||
base_external_dbsource, |
|||
) |
|||
CONNECTORS = base_external_dbsource.BaseExternalDbsource.CONNECTORS |
|||
try: |
|||
import fdb |
|||
CONNECTORS.append(('fdb', 'Firebird')) |
|||
except: |
|||
_logger.info('Firebird library not available. Please install "fdb" ' |
|||
'python package.') |
|||
except ImportError: |
|||
_logger.info('base_external_dbsource Odoo module not found.') |
|||
|
|||
|
|||
class BaseExternalDbsource(models.Model): |
|||
""" It provides logic for connection to an Firebird data source. """ |
|||
|
|||
_inherit = "base.external.dbsource" |
|||
|
|||
PWD_STRING_FDB = 'Password=%s;' |
|||
|
|||
@api.multi |
|||
def connection_close_fdb(self, connection): |
|||
return connection.close() |
|||
|
|||
@api.multi |
|||
def connection_open_fdb(self): |
|||
kwargs = {} |
|||
for option in self.conn_string_full.split(';'): |
|||
try: |
|||
key, value = option.split('=') |
|||
except ValueError: |
|||
continue |
|||
kwargs[key.lower()] = value |
|||
return fdb.connect(**kwargs) |
|||
|
|||
@api.multi |
|||
def execute_fdb(self, sqlquery, sqlparams, metadata): |
|||
with self.connection_open_fdb() as conn: |
|||
cur = conn.cursor() |
|||
cur.execute(sqlquery % sqlparams) |
|||
rows = cur.fetchall() |
|||
return rows, [] |
@ -0,0 +1,3 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
|
|||
from . import test_base_external_dbsource |
@ -0,0 +1,41 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2016 LasLabs Inc. |
|||
|
|||
import mock |
|||
|
|||
from odoo.tests import common |
|||
|
|||
|
|||
ADAPTER = ('odoo.addons.base_external_dbsource_firebird.models' |
|||
'.base_external_dbsource.fdb') |
|||
|
|||
|
|||
class TestBaseExternalDbsource(common.TransactionCase): |
|||
|
|||
def setUp(self): |
|||
super(TestBaseExternalDbsource, self).setUp() |
|||
self.dbsource = self.env.ref( |
|||
'base_external_dbsource_firebird.demo_firebird', |
|||
) |
|||
|
|||
def test_connection_close_fdb(self): |
|||
""" It should close the connection """ |
|||
connection = mock.MagicMock() |
|||
res = self.dbsource.connection_close_fdb(connection) |
|||
self.assertEqual(res, connection.close()) |
|||
|
|||
@mock.patch(ADAPTER) |
|||
def test_connection_open_fdb(self, fdb): |
|||
""" It should open the connection with the split conn string """ |
|||
self.dbsource.conn_string = 'User=User;' |
|||
self.dbsource.connection_open_fdb() |
|||
fdb.connect.assert_called_once_with(**{ |
|||
'user': 'User', |
|||
'password': 'password', |
|||
}) |
|||
|
|||
@mock.patch(ADAPTER) |
|||
def test_connection_open_fdb_return(self, fdb): |
|||
""" It should return the newly opened connection """ |
|||
res = self.dbsource.connection_open_fdb() |
|||
self.assertEqual(res, fdb.connect()) |
@ -0,0 +1,80 @@ |
|||
.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg |
|||
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html |
|||
:alt: License: LGPL-3 |
|||
|
|||
================================ |
|||
External Database Source - MSSQL |
|||
================================ |
|||
|
|||
This module extends ``base_external_dbsource``, allowing you to connect to |
|||
foreign MSSQL databases using SQLAlchemy. |
|||
|
|||
|
|||
|
|||
Installation |
|||
============ |
|||
|
|||
* Install & configure FreeTDS driver (tdsodbc package) |
|||
* Install ``sqlalchemy`` and ``pymssql`` python libraries |
|||
* Install ``base_external_dbsource_sqlite`` Odoo module |
|||
|
|||
Configuration |
|||
============= |
|||
|
|||
Database sources can be configured in Settings > Configuration -> Data sources. |
|||
|
|||
|
|||
Usage |
|||
===== |
|||
|
|||
To use this module: |
|||
|
|||
* Go to Settings > Database Structure > Database Sources |
|||
* Click on Create to enter the following information: |
|||
|
|||
* Datasource name |
|||
* Pasword |
|||
* Connector: Choose the database to which you want to connect |
|||
* Connection string: Specify how to connect to database |
|||
|
|||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
|||
:alt: Try me on Runbot |
|||
:target: https://runbot.odoo-community.org/runbot/149/10.0 for server-tools |
|||
|
|||
Known issues / Roadmap |
|||
====================== |
|||
|
|||
* Add X.509 authentication |
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-tools/issues>`_. |
|||
In case of trouble, please check there if your issue has already been reported. |
|||
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback. |
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Contributors |
|||
------------ |
|||
|
|||
* Daniel Reis <dreis.pt@hotmail.com> |
|||
* Maxime Chambreuil <maxime.chambreuil@savoirfairelinux.com> |
|||
* Gervais Naoussi <gervaisnaoussi@gmail.com> |
|||
* Dave Lasley <dave@laslabs.com> |
|||
|
|||
Maintainer |
|||
---------- |
|||
|
|||
.. image:: https://odoo-community.org/logo.png |
|||
:alt: Odoo Community Association |
|||
:target: https://odoo-community.org |
|||
|
|||
This module is maintained by the OCA. |
|||
|
|||
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. |
|||
|
|||
To contribute to this module, please visit http://odoo-community.org. |
@ -0,0 +1,2 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import models |
@ -0,0 +1,29 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright <2011> <Daniel Reis, Maxime Chambreuil, Savoir-faire Linux> |
|||
# Copyright 2016 LasLabs Inc. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
{ |
|||
'name': 'External Database Source - MSSQL', |
|||
'version': '10.0.1.0.0', |
|||
'category': 'Tools', |
|||
'author': "Daniel Reis, " |
|||
"LasLabs, " |
|||
"Odoo Community Association (OCA)", |
|||
'website': 'https://github.com/OCA/server-tools', |
|||
'license': 'LGPL-3', |
|||
'depends': [ |
|||
'base_external_dbsource_sqlite', |
|||
], |
|||
# Uncomment this for v11 |
|||
# 'external_dependencies': [ |
|||
# 'python': [ |
|||
# 'sqlalchemy', |
|||
# 'pymssql', |
|||
# ] |
|||
# ], |
|||
'demo': [ |
|||
'demo/base_external_dbsource.xml', |
|||
], |
|||
'installable': True, |
|||
'auto_install': True, # Remove this key for v11 |
|||
} |
@ -0,0 +1,9 @@ |
|||
<?xml version="1.0"?> |
|||
<odoo> |
|||
<record model="base.external.dbsource" id="demo_mssql"> |
|||
<field name="name">MSSQL Demo</field> |
|||
<field name="conn_string">Server=myServerAddress;Database=myDataBase;User Id=myUsername;</field> |
|||
<field name="password">password</field> |
|||
<field name="connector">mssql</field> |
|||
</record> |
|||
</odoo> |
@ -0,0 +1,3 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
from . import base_external_dbsource |
@ -0,0 +1,45 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2011 Daniel Reis |
|||
# Copyright 2016 LasLabs Inc. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
|||
|
|||
import logging |
|||
|
|||
from odoo import api, models |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
try: |
|||
from odoo.addons.base_external_dbsource.models import ( |
|||
base_external_dbsource, |
|||
) |
|||
CONNECTORS = base_external_dbsource.BaseExternalDbsource.CONNECTORS |
|||
try: |
|||
import pymssql |
|||
CONNECTORS.append(('mssql', 'Microsoft SQL Server')) |
|||
assert pymssql |
|||
except (ImportError, AssertionError): |
|||
_logger.info('MS SQL Server not available. Please install "pymssql" ' |
|||
'python package.') |
|||
except ImportError: |
|||
_logger.info('base_external_dbsource Odoo module not found.') |
|||
|
|||
|
|||
class BaseExternalDbsource(models.Model): |
|||
""" It provides logic for connection to a MSSQL data source. """ |
|||
|
|||
_inherit = "base.external.dbsource" |
|||
|
|||
PWD_STRING_MSSQL = 'Password=%s;' |
|||
|
|||
@api.multi |
|||
def connection_close_mssql(self, connection): |
|||
return connection.close() |
|||
|
|||
@api.multi |
|||
def connection_open_mssql(self): |
|||
return self._connection_open_sqlalchemy() |
|||
|
|||
@api.multi |
|||
def execute_mssql(self, sqlquery, sqlparams, metadata): |
|||
return self._execute_sqlalchemy(sqlquery, sqlparams, metadata) |
@ -0,0 +1,3 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
|
|||
from . import test_base_external_dbsource |
@ -0,0 +1,42 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2016 LasLabs Inc. |
|||
|
|||
import mock |
|||
|
|||
from odoo.tests import common |
|||
|
|||
|
|||
ADAPTER = ('odoo.addons.base_external_dbsource_mssql.models' |
|||
'.base_external_dbsource.pymssql') |
|||
|
|||
|
|||
class TestBaseExternalDbsource(common.TransactionCase): |
|||
|
|||
def setUp(self): |
|||
super(TestBaseExternalDbsource, self).setUp() |
|||
self.dbsource = self.env.ref( |
|||
'base_external_dbsource_mssql.demo_mssql', |
|||
) |
|||
|
|||
def test_connection_close_mssql(self): |
|||
""" It should close the connection """ |
|||
connection = mock.MagicMock() |
|||
res = self.dbsource.connection_close_mssql(connection) |
|||
self.assertEqual(res, connection.close()) |
|||
|
|||
def test_connection_open_mssql(self): |
|||
""" It should call SQLAlchemy open """ |
|||
with mock.patch.object( |
|||
self.dbsource, '_connection_open_sqlalchemy' |
|||
) as parent_method: |
|||
self.dbsource.connection_open_mssql() |
|||
parent_method.assert_called_once_with() |
|||
|
|||
def test_excecute_mssql(self): |
|||
""" It should pass args to SQLAlchemy execute """ |
|||
expect = 'sqlquery', 'sqlparams', 'metadata' |
|||
with mock.patch.object( |
|||
self.dbsource, '_execute_sqlalchemy' |
|||
) as parent_method: |
|||
self.dbsource.execute_mssql(*expect) |
|||
parent_method.assert_called_once_with(*expect) |
@ -0,0 +1,80 @@ |
|||
.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg |
|||
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html |
|||
:alt: License: LGPL-3 |
|||
|
|||
================================ |
|||
External Database Source - MySQL |
|||
================================ |
|||
|
|||
This module extends ``base_external_dbsource``, allowing you to connect to |
|||
foreign MySQL databases using SQLAlchemy. |
|||
|
|||
|
|||
|
|||
Installation |
|||
============ |
|||
|
|||
* Install ``sqlalchemy`` and ``MySQLdb`` python libraries |
|||
* Install ``base_external_dbsource_sqlite`` Odoo module |
|||
|
|||
Configuration |
|||
============= |
|||
|
|||
Database sources can be configured in Settings > Configuration -> Data sources. |
|||
|
|||
|
|||
Usage |
|||
===== |
|||
|
|||
To use this module: |
|||
|
|||
* Go to Settings > Database Structure > Database Sources |
|||
* Click on Create to enter the following information: |
|||
|
|||
* Datasource name |
|||
* Pasword |
|||
* Connector: Choose the database to which you want to connect |
|||
* Connection string: Specify how to connect to database |
|||
|
|||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
|||
:alt: Try me on Runbot |
|||
:target: https://runbot.odoo-community.org/runbot/149/10.0 for server-tools |
|||
|
|||
Known issues / Roadmap |
|||
====================== |
|||
|
|||
|
|||
* Add X.509 authentication |
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-tools/issues>`_. |
|||
In case of trouble, please check there if your issue has already been reported. |
|||
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback. |
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Contributors |
|||
------------ |
|||
|
|||
* Daniel Reis <dreis.pt@hotmail.com> |
|||
* Maxime Chambreuil <maxime.chambreuil@savoirfairelinux.com> |
|||
* Gervais Naoussi <gervaisnaoussi@gmail.com> |
|||
* Dave Lasley <dave@laslabs.com> |
|||
|
|||
Maintainer |
|||
---------- |
|||
|
|||
.. image:: https://odoo-community.org/logo.png |
|||
:alt: Odoo Community Association |
|||
:target: https://odoo-community.org |
|||
|
|||
This module is maintained by the OCA. |
|||
|
|||
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. |
|||
|
|||
To contribute to this module, please visit http://odoo-community.org. |
@ -0,0 +1,2 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import models |
@ -0,0 +1,29 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright <2011> <Daniel Reis, Maxime Chambreuil, Savoir-faire Linux> |
|||
# Copyright 2016 LasLabs Inc. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
{ |
|||
'name': 'External Database Source - MySQL', |
|||
'version': '10.0.1.0.0', |
|||
'category': 'Tools', |
|||
'author': "Daniel Reis, " |
|||
"LasLabs, " |
|||
"Odoo Community Association (OCA)", |
|||
'website': 'https://github.com/OCA/server-tools', |
|||
'license': 'LGPL-3', |
|||
'depends': [ |
|||
'base_external_dbsource_sqlite', |
|||
], |
|||
# Uncomment this for v11 |
|||
# 'external_dependencies': [ |
|||
# 'python': [ |
|||
# 'sqlalchemy', |
|||
# 'MySQLdb', |
|||
# ] |
|||
# ], |
|||
'demo': [ |
|||
'demo/base_external_dbsource.xml', |
|||
], |
|||
'installable': True, |
|||
'auto_install': True, # Remove this key for v11 |
|||
} |
@ -0,0 +1,9 @@ |
|||
<?xml version="1.0"?> |
|||
<odoo> |
|||
<record model="base.external.dbsource" id="demo_mysql"> |
|||
<field name="name">MySQL Demo</field> |
|||
<field name="conn_string">Server=myServerAddress;Database=myDataBase;Uid=myUsername;</field> |
|||
<field name="password">password</field> |
|||
<field name="connector">mysql</field> |
|||
</record> |
|||
</odoo> |
@ -0,0 +1,3 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
from . import base_external_dbsource |
@ -0,0 +1,43 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2011 Daniel Reis |
|||
# Copyright 2016 LasLabs Inc. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
|||
|
|||
import logging |
|||
|
|||
from odoo import api, models |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
try: |
|||
from odoo.addons.base_external_dbsource.models import ( |
|||
base_external_dbsource, |
|||
) |
|||
CONNECTORS = base_external_dbsource.BaseExternalDbsource.CONNECTORS |
|||
try: |
|||
import MySQLdb |
|||
CONNECTORS.append(('mysql', 'MySQL')) |
|||
assert MySQLdb |
|||
except (ImportError, AssertionError): |
|||
_logger.info('MySQL not available. Please install "mysqldb" ' |
|||
'python package.') |
|||
except ImportError: |
|||
_logger.info('base_external_dbsource Odoo module not found.') |
|||
|
|||
|
|||
class BaseExternalDbsource(models.Model): |
|||
""" It provides logic for connection to a MySQL data source. """ |
|||
|
|||
_inherit = "base.external.dbsource" |
|||
|
|||
@api.multi |
|||
def connection_close_mysql(self, connection): |
|||
return connection.close() |
|||
|
|||
@api.multi |
|||
def connection_open_mysql(self): |
|||
return self._connection_open_sqlalchemy() |
|||
|
|||
@api.multi |
|||
def execute_mysql(self, sqlquery, sqlparams, metadata): |
|||
return self._execute_sqlalchemy(sqlquery, sqlparams, metadata) |
@ -0,0 +1,3 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
|
|||
from . import test_base_external_dbsource |
@ -0,0 +1,42 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2016 LasLabs Inc. |
|||
|
|||
import mock |
|||
|
|||
from odoo.tests import common |
|||
|
|||
|
|||
ADAPTER = ('odoo.addons.base_external_dbsource_mysql.models' |
|||
'.base_external_dbsource.MySQLdb') |
|||
|
|||
|
|||
class TestBaseExternalDbsource(common.TransactionCase): |
|||
|
|||
def setUp(self): |
|||
super(TestBaseExternalDbsource, self).setUp() |
|||
self.dbsource = self.env.ref( |
|||
'base_external_dbsource_mysql.demo_mysql', |
|||
) |
|||
|
|||
def test_connection_close_mysql(self): |
|||
""" It should close the connection """ |
|||
connection = mock.MagicMock() |
|||
res = self.dbsource.connection_close_mysql(connection) |
|||
self.assertEqual(res, connection.close()) |
|||
|
|||
def test_connection_open_mysql(self): |
|||
""" It should call SQLAlchemy open """ |
|||
with mock.patch.object( |
|||
self.dbsource, '_connection_open_sqlalchemy' |
|||
) as parent_method: |
|||
self.dbsource.connection_open_mysql() |
|||
parent_method.assert_called_once_with() |
|||
|
|||
def test_excecute_mysql(self): |
|||
""" It should pass args to SQLAlchemy execute """ |
|||
expect = 'sqlquery', 'sqlparams', 'metadata' |
|||
with mock.patch.object( |
|||
self.dbsource, '_execute_sqlalchemy' |
|||
) as parent_method: |
|||
self.dbsource.execute_mysql(*expect) |
|||
parent_method.assert_called_once_with(*expect) |
@ -0,0 +1,79 @@ |
|||
.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg |
|||
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html |
|||
:alt: License: LGPL-3 |
|||
|
|||
=============================== |
|||
External Database Source - ODBC |
|||
=============================== |
|||
|
|||
This module extends ``base_external_dbsource``, allowing you to connect to |
|||
foreign ODBC databases using PyODBC. |
|||
|
|||
|
|||
|
|||
Installation |
|||
============ |
|||
|
|||
* Install ``unixodbc`` and ``python-pyodbc`` packages |
|||
* Install ``base_external_dbsource_sqlite`` Odoo module |
|||
|
|||
Configuration |
|||
============= |
|||
|
|||
Database sources can be configured in Settings > Configuration -> Data sources. |
|||
|
|||
|
|||
Usage |
|||
===== |
|||
|
|||
To use this module: |
|||
|
|||
* Go to Settings > Database Structure > Database Sources |
|||
* Click on Create to enter the following information: |
|||
|
|||
* Datasource name |
|||
* Pasword |
|||
* Connector: Choose the database to which you want to connect |
|||
* Connection string: Specify how to connect to database |
|||
|
|||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
|||
:alt: Try me on Runbot |
|||
:target: https://runbot.odoo-community.org/runbot/149/10.0 for server-tools |
|||
|
|||
Known issues / Roadmap |
|||
====================== |
|||
|
|||
* Add X.509 authentication |
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-tools/issues>`_. |
|||
In case of trouble, please check there if your issue has already been reported. |
|||
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback. |
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Contributors |
|||
------------ |
|||
|
|||
* Daniel Reis <dreis.pt@hotmail.com> |
|||
* Maxime Chambreuil <maxime.chambreuil@savoirfairelinux.com> |
|||
* Gervais Naoussi <gervaisnaoussi@gmail.com> |
|||
* Dave Lasley <dave@laslabs.com> |
|||
|
|||
Maintainer |
|||
---------- |
|||
|
|||
.. image:: https://odoo-community.org/logo.png |
|||
:alt: Odoo Community Association |
|||
:target: https://odoo-community.org |
|||
|
|||
This module is maintained by the OCA. |
|||
|
|||
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. |
|||
|
|||
To contribute to this module, please visit http://odoo-community.org. |
@ -0,0 +1,2 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import models |
@ -0,0 +1,29 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright <2011> <Daniel Reis, Maxime Chambreuil, Savoir-faire Linux> |
|||
# Copyright 2016 LasLabs Inc. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
{ |
|||
'name': 'External Database Source - ODBC', |
|||
'version': '10.0.1.0.0', |
|||
'category': 'Tools', |
|||
'author': "Daniel Reis, " |
|||
"LasLabs, " |
|||
"Odoo Community Association (OCA)", |
|||
'website': 'https://github.com/OCA/server-tools', |
|||
'license': 'LGPL-3', |
|||
'depends': [ |
|||
'base_external_dbsource_sqlite', |
|||
], |
|||
# Uncomment this for v11 |
|||
# 'external_dependencies': [ |
|||
# 'python': [ |
|||
# 'sqlalchemy', |
|||
# 'pyodbc', |
|||
# ] |
|||
# ], |
|||
'demo': [ |
|||
'demo/base_external_dbsource.xml', |
|||
], |
|||
'installable': True, |
|||
'auto_install': True, # Remove this key for v11 |
|||
} |
@ -0,0 +1,9 @@ |
|||
<?xml version="1.0"?> |
|||
<odoo> |
|||
<record model="base.external.dbsource" id="demo_odbc"> |
|||
<field name="name">ODBC Demo</field> |
|||
<field name="conn_string">Driver='ODBC Driver 11 for SQL Server';Server=myServerAddress;Database=myDataBase;Uid=myUsername;</field> |
|||
<field name="password">password</field> |
|||
<field name="connector">pyodbc</field> |
|||
</record> |
|||
</odoo> |
@ -0,0 +1,3 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
from . import base_external_dbsource |
@ -0,0 +1,42 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2011 Daniel Reis |
|||
# Copyright 2016 LasLabs Inc. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
|||
|
|||
import logging |
|||
|
|||
from odoo import api, models |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
try: |
|||
from odoo.addons.base_external_dbsource.models import ( |
|||
base_external_dbsource, |
|||
) |
|||
CONNECTORS = base_external_dbsource.BaseExternalDbsource.CONNECTORS |
|||
try: |
|||
import pyodbc |
|||
CONNECTORS.append(('pyodbc', 'ODBC')) |
|||
except ImportError: |
|||
_logger.info('ODBC libraries not available. Please install ' |
|||
'"unixodbc" and "python-pyodbc" packages.') |
|||
except ImportError: |
|||
_logger.info('base_external_dbsource Odoo module not found.') |
|||
|
|||
|
|||
class BaseExternalDbsource(models.Model): |
|||
""" It provides logic for connection to a ODBC data source. """ |
|||
|
|||
_inherit = "base.external.dbsource" |
|||
|
|||
@api.multi |
|||
def connection_close_pyodbc(self, connection): |
|||
return connection.close() |
|||
|
|||
@api.multi |
|||
def connection_open_pyodbc(self): |
|||
return pyodbc.connect(self.conn_string_full) |
|||
|
|||
@api.multi |
|||
def execute_pyodbc(self, sqlquery, sqlparams, metadata): |
|||
return self._execute_generic(sqlquery, sqlparams, metadata) |
@ -0,0 +1,3 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
|
|||
from . import test_base_external_dbsource |
@ -0,0 +1,46 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2016 LasLabs Inc. |
|||
|
|||
import mock |
|||
|
|||
from odoo.tests import common |
|||
|
|||
|
|||
ADAPTER = ('odoo.addons.base_external_dbsource_odbc.models' |
|||
'.base_external_dbsource.pyodbc') |
|||
|
|||
|
|||
class TestBaseExternalDbsource(common.TransactionCase): |
|||
|
|||
def setUp(self): |
|||
super(TestBaseExternalDbsource, self).setUp() |
|||
self.dbsource = self.env.ref( |
|||
'base_external_dbsource_odbc.demo_odbc', |
|||
) |
|||
|
|||
def test_connection_close_pyodbc(self): |
|||
""" It should close the connection """ |
|||
connection = mock.MagicMock() |
|||
res = self.dbsource.connection_close_pyodbc(connection) |
|||
self.assertEqual(res, connection.close()) |
|||
|
|||
@mock.patch(ADAPTER) |
|||
def test_connection_open_pyodbc(self, pyodbc): |
|||
""" It should open the connection with the full conn string """ |
|||
self.dbsource.connection_open_pyodbc() |
|||
pyodbc.connect.assert_called_once_with( |
|||
self.dbsource.conn_string_full, |
|||
) |
|||
|
|||
@mock.patch(ADAPTER) |
|||
def test_connection_open_pyodbc_return(self, pyodbc): |
|||
""" It should return the newly opened connection """ |
|||
res = self.dbsource.connection_open_pyodbc() |
|||
self.assertEqual(res, pyodbc.connect()) |
|||
|
|||
def test_execute_pyodbc(self): |
|||
""" It should call the generic execute method w/ proper args """ |
|||
expect = 'sqlquery', 'sqlparams', 'metadata' |
|||
with mock.patch.object(self.dbsource, '_execute_generic') as execute: |
|||
self.dbsource.execute_pyodbc(*expect) |
|||
execute.assert_called_once_with(*expect) |
@ -0,0 +1,79 @@ |
|||
.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg |
|||
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html |
|||
:alt: License: LGPL-3 |
|||
|
|||
================================= |
|||
External Database Source - Oracle |
|||
================================= |
|||
|
|||
This module extends ``base_external_dbsource``, allowing you to connect to |
|||
foreign Oracle databases. |
|||
|
|||
Installation |
|||
============ |
|||
|
|||
* Install and configure Oracle Instant Client |
|||
* Install ``cx_Oracle`` python library |
|||
|
|||
Configuration |
|||
============= |
|||
|
|||
Database sources can be configured in Settings > Configuration -> Data sources. |
|||
|
|||
|
|||
Usage |
|||
===== |
|||
|
|||
To use this module: |
|||
|
|||
* Go to Settings > Database Structure > Database Sources |
|||
* Click on Create to enter the following information: |
|||
|
|||
* Datasource name |
|||
* Pasword |
|||
* Connector: Choose the database to which you want to connect |
|||
* Connection string: Specify how to connect to database |
|||
|
|||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
|||
:alt: Try me on Runbot |
|||
:target: https://runbot.odoo-community.org/runbot/149/10.0 for server-tools |
|||
|
|||
Known issues / Roadmap |
|||
====================== |
|||
|
|||
* Find a way to test (cx_Oracle requires InstantClient, which Travis doesn't have) |
|||
* Add X.509 authentication |
|||
|
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-tools/issues>`_. |
|||
In case of trouble, please check there if your issue has already been reported. |
|||
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback. |
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Contributors |
|||
------------ |
|||
|
|||
* Daniel Reis <dreis.pt@hotmail.com> |
|||
* Maxime Chambreuil <maxime.chambreuil@savoirfairelinux.com> |
|||
* Gervais Naoussi <gervaisnaoussi@gmail.com> |
|||
* Dave Lasley <dave@laslabs.com> |
|||
|
|||
Maintainer |
|||
---------- |
|||
|
|||
.. image:: https://odoo-community.org/logo.png |
|||
:alt: Odoo Community Association |
|||
:target: https://odoo-community.org |
|||
|
|||
This module is maintained by the OCA. |
|||
|
|||
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. |
|||
|
|||
To contribute to this module, please visit http://odoo-community.org. |
@ -0,0 +1,2 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import models |
@ -0,0 +1,25 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright <2011> <Daniel Reis, Maxime Chambreuil, Savoir-faire Linux> |
|||
# Copyright 2016 LasLabs Inc. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
{ |
|||
'name': 'External Database Source - Oracle', |
|||
'version': '10.0.1.0.0', |
|||
'category': 'Tools', |
|||
'author': "Daniel Reis, " |
|||
"LasLabs, " |
|||
"Odoo Community Association (OCA)", |
|||
'website': 'https://github.com/OCA/server-tools', |
|||
'license': 'LGPL-3', |
|||
'depends': [ |
|||
'base_external_dbsource', |
|||
], |
|||
# Uncomment this for v11 |
|||
# 'external_dependencies': [ |
|||
# 'python': [ |
|||
# 'cx_Oracle', |
|||
# ] |
|||
# ], |
|||
'installable': True, |
|||
'auto_install': True, # Remove this key for v11 |
|||
} |
@ -0,0 +1,3 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
from . import base_external_dbsource |
@ -0,0 +1,47 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2011 Daniel Reis |
|||
# Copyright 2016 LasLabs Inc. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
|||
|
|||
import logging |
|||
import os |
|||
|
|||
from odoo import api |
|||
from odoo import models |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
try: |
|||
from odoo.addons.base_external_dbsource.models import ( |
|||
base_external_dbsource, |
|||
) |
|||
CONNECTORS = base_external_dbsource.BaseExternalDbsource.CONNECTORS |
|||
try: |
|||
import cx_Oracle |
|||
CONNECTORS.append(('cx_Oracle', 'Oracle')) |
|||
except ImportError: |
|||
_logger.info('Oracle libraries not available. Please install ' |
|||
'"cx_Oracle" python package.') |
|||
except ImportError: |
|||
_logger.info('base_external_dbsource Odoo module not found.') |
|||
|
|||
|
|||
class BaseExternalDbsource(models.Model): |
|||
""" It provides logic for connection to an Oracle data source. """ |
|||
|
|||
_inherit = "base.external.dbsource" |
|||
|
|||
PWD_STRING_CX_ORACLE = 'Password=%s;' |
|||
|
|||
@api.multi |
|||
def connection_close_cx_Oracle(self, connection): |
|||
return connection.close() |
|||
|
|||
@api.multi |
|||
def connection_open_cx_Oracle(self): |
|||
os.environ['NLS_LANG'] = 'AMERICAN_AMERICA.UTF8' |
|||
return cx_Oracle.connect(self.conn_string_full) |
|||
|
|||
@api.multi |
|||
def execute_cx_Oracle(self, sqlquery, sqlparams, metadata): |
|||
return self._execute_generic(sqlquery, sqlparams, metadata) |
@ -0,0 +1,77 @@ |
|||
.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg |
|||
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html |
|||
:alt: License: LGPL-3 |
|||
|
|||
================================= |
|||
External Database Source - SQLite |
|||
================================= |
|||
|
|||
This module extends ``base_external_dbsource``, allowing you to connect to |
|||
foreign SQLite databases using SQLAlchemy. |
|||
|
|||
|
|||
Installation |
|||
============ |
|||
|
|||
* Install ``sqlalchemy`` python library |
|||
|
|||
Configuration |
|||
============= |
|||
|
|||
Database sources can be configured in Settings > Configuration -> Data sources. |
|||
|
|||
|
|||
Usage |
|||
===== |
|||
|
|||
To use this module: |
|||
|
|||
* Go to Settings > Database Structure > Database Sources |
|||
* Click on Create to enter the following information: |
|||
|
|||
* Datasource name |
|||
* Pasword |
|||
* Connector: Choose the database to which you want to connect |
|||
* Connection string: Specify how to connect to database |
|||
|
|||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
|||
:alt: Try me on Runbot |
|||
:target: https://runbot.odoo-community.org/runbot/149/10.0 for server-tools |
|||
|
|||
Known issues / Roadmap |
|||
====================== |
|||
|
|||
* Add X.509 authentication |
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-tools/issues>`_. |
|||
In case of trouble, please check there if your issue has already been reported. |
|||
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback. |
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Contributors |
|||
------------ |
|||
|
|||
* Daniel Reis <dreis.pt@hotmail.com> |
|||
* Maxime Chambreuil <maxime.chambreuil@savoirfairelinux.com> |
|||
* Gervais Naoussi <gervaisnaoussi@gmail.com> |
|||
* Dave Lasley <dave@laslabs.com> |
|||
|
|||
Maintainer |
|||
---------- |
|||
|
|||
.. image:: https://odoo-community.org/logo.png |
|||
:alt: Odoo Community Association |
|||
:target: https://odoo-community.org |
|||
|
|||
This module is maintained by the OCA. |
|||
|
|||
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. |
|||
|
|||
To contribute to this module, please visit http://odoo-community.org. |
@ -0,0 +1,2 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import models |
@ -0,0 +1,28 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright <2011> <Daniel Reis, Maxime Chambreuil, Savoir-faire Linux> |
|||
# Copyright 2016 LasLabs Inc. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
{ |
|||
'name': 'External Database Source - SQLite', |
|||
'version': '10.0.1.0.0', |
|||
'category': 'Tools', |
|||
'author': "Daniel Reis, " |
|||
"LasLabs, " |
|||
"Odoo Community Association (OCA)", |
|||
'website': 'https://github.com/OCA/server-tools', |
|||
'license': 'LGPL-3', |
|||
'depends': [ |
|||
'base_external_dbsource', |
|||
], |
|||
# Uncomment this for v11 |
|||
# 'external_dependencies': [ |
|||
# 'python': [ |
|||
# 'sqlalchemy', |
|||
# ] |
|||
# ], |
|||
'demo': [ |
|||
'demo/base_external_dbsource.xml', |
|||
], |
|||
'installable': True, |
|||
'auto_install': True, # Remove this key for v11 |
|||
} |
@ -0,0 +1,9 @@ |
|||
<?xml version="1.0"?> |
|||
<odoo> |
|||
<record model="base.external.dbsource" id="demo_sqlite"> |
|||
<field name="name">SQLite Demo</field> |
|||
<field name="conn_string">Data Source=:memory:;Version=3;New=True;</field> |
|||
<field name="password">password</field> |
|||
<field name="connector">sqlite</field> |
|||
</record> |
|||
</odoo> |
@ -0,0 +1,3 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
from . import base_external_dbsource |
@ -0,0 +1,59 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2011 Daniel Reis |
|||
# Copyright 2016 LasLabs Inc. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
|||
|
|||
import logging |
|||
|
|||
from odoo import api, models |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
try: |
|||
from odoo.addons.base_external_dbsource.models import ( |
|||
base_external_dbsource, |
|||
) |
|||
CONNECTORS = base_external_dbsource.BaseExternalDbsource.CONNECTORS |
|||
try: |
|||
import sqlalchemy |
|||
CONNECTORS.append(('sqlite', 'SQLite')) |
|||
except ImportError: |
|||
_logger.info('SQLAlchemy library not available. Please ' |
|||
'install "sqlalchemy" python package.') |
|||
except ImportError: |
|||
_logger.info('base_external_dbsource Odoo module not found.') |
|||
|
|||
|
|||
class BaseExternalDbsource(models.Model): |
|||
""" It provides logic for connection to a SQLite data source. """ |
|||
|
|||
_inherit = "base.external.dbsource" |
|||
|
|||
PWD_STRING_SQLITE = 'Password=%s;' |
|||
|
|||
@api.multi |
|||
def connection_close_sqlite(self, connection): |
|||
return connection.close() |
|||
|
|||
@api.multi |
|||
def connection_open_sqlite(self): |
|||
return self._connection_open_sqlalchemy() |
|||
|
|||
@api.multi |
|||
def execute_sqlite(self, sqlquery, sqlparams, metadata): |
|||
return self._execute_sqlalchemy(sqlquery, sqlparams, metadata) |
|||
|
|||
@api.multi |
|||
def _connection_open_sqlalchemy(self): |
|||
return sqlalchemy.create_engine(self.conn_string_full).connect() |
|||
|
|||
@api.multi |
|||
def _execute_sqlalchemy(self, sqlquery, sqlparams, metadata): |
|||
rows, cols = list(), list() |
|||
for record in self: |
|||
with record.connection_open() as connection: |
|||
cur = connection.execute(sqlquery, sqlparams) |
|||
if metadata: |
|||
cols = cur.keys() |
|||
rows = [r for r in cur] |
|||
return rows, cols |
@ -0,0 +1,3 @@ |
|||
# -*- encoding: utf-8 -*- |
|||
|
|||
from . import test_base_external_dbsource |
@ -0,0 +1,42 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Copyright 2016 LasLabs Inc. |
|||
|
|||
import mock |
|||
|
|||
from odoo.tests import common |
|||
|
|||
|
|||
ADAPTER = ('odoo.addons.base_external_dbsource_sqlite.models' |
|||
'.base_external_dbsource.sqlalchemy') |
|||
|
|||
|
|||
class TestBaseExternalDbsource(common.TransactionCase): |
|||
|
|||
def setUp(self): |
|||
super(TestBaseExternalDbsource, self).setUp() |
|||
self.dbsource = self.env.ref( |
|||
'base_external_dbsource_sqlite.demo_sqlite', |
|||
) |
|||
|
|||
def test_connection_close_sqlite(self): |
|||
""" It should close the connection """ |
|||
connection = mock.MagicMock() |
|||
res = self.dbsource.connection_close_sqlite(connection) |
|||
self.assertEqual(res, connection.close()) |
|||
|
|||
def test_connection_open_sqlite(self): |
|||
""" It should call SQLAlchemy open """ |
|||
with mock.patch.object( |
|||
self.dbsource, '_connection_open_sqlalchemy' |
|||
) as parent_method: |
|||
self.dbsource.connection_open_sqlite() |
|||
parent_method.assert_called_once_with() |
|||
|
|||
def test_excecute_sqlite(self): |
|||
""" It should pass args to SQLAlchemy execute """ |
|||
expect = 'sqlquery', 'sqlparams', 'metadata' |
|||
with mock.patch.object( |
|||
self.dbsource, '_execute_sqlalchemy' |
|||
) as parent_method: |
|||
self.dbsource.execute_sqlite(*expect) |
|||
parent_method.assert_called_once_with(*expect) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue