コード例 #1
0
ファイル: __init__.py プロジェクト: Py-AMS/pyams-alchemy
class AlchemyManagerEnginesView(TableAdminView):
    """SQLAlchemy manager engines view"""

    title = _("SQL engines")
    table_class = AlchemyManagerEnginesTable
    table_label = _("List of SQL engines")

    @property
    def back_url(self):
        """Form back URL getter"""
        return absolute_url(self.request.root, self.request,
                            'admin#utilities.html')  # pylint: disable=no-member

    back_url_target = None
コード例 #2
0
ファイル: engine.py プロジェクト: Py-AMS/pyams-alchemy
def handle_new_engine_data_extraction(event):
    """Handle new engine data"""
    name = event.data['name'] or ''
    engine = query_utility(IAlchemyEngineUtility, name=name)
    if engine is not None:
        event.form.widgets.errors += (Invalid(_("An SQLAlchemy engine is already "
                                                "registered with this name!")),)
コード例 #3
0
class IAlchemyTaskInfo(Interface):
    """SQLAlchemy scheduler task interface"""

    session_name = Choice(
        title=_("SQL session name"),
        description=_("Name of the SQLAlchemy engine used to access database"),
        vocabulary=ALCHEMY_ENGINES_VOCABULARY,
        required=True)

    query = Text(title=_("SQL query text"), required=True)

    output_format = Choice(
        title=_("Output format"),
        description=_("Format into which query output should be returned"),
        vocabulary=ALCHEMY_CONVERTERS_VOCABULARY,
        required=True,
        default='json')
コード例 #4
0
ファイル: engine.py プロジェクト: Py-AMS/pyams-alchemy
class AlchemyEngineCloneColumn(ActionColumn):
    """SQLAlchemy engine clone column"""

    hint = _("Clone SQL engine")
    icon_class = 'far fa-clone'

    href = 'clone-sql-engine.html'

    weight = 100
コード例 #5
0
ファイル: engine.py プロジェクト: Py-AMS/pyams-alchemy
class AlchemyEngineAddForm(AlchemyEngineBaseAddFormMixin, AdminModalAddForm):  # pylint: disable=abstract-method
    """SQLAlchemy engine add form"""

    legend = _("New engine properties")

    fields = Fields(IAlchemyEngineUtility)
    content_factory = IAlchemyEngineUtility

    def add(self, obj):
        oid = IUniqueID(obj).oid
        self.context[oid] = obj
コード例 #6
0
ファイル: engine.py プロジェクト: Py-AMS/pyams-alchemy
class AlchemyEngineCloneForm(AlchemyEngineBaseAddFormMixin, AdminModalAddForm):
    """SQLAlchemy engine clone form"""

    legend = _("Clone SQL connection")

    fields = Fields(IAlchemyEngineUtility).select('name')

    def create(self, data):
        return copy(self.context)

    def add(self, obj):
        oid = IUniqueID(obj).oid
        self.context.__parent__[oid] = obj
コード例 #7
0
ファイル: __init__.py プロジェクト: Py-AMS/pyams-alchemy
 def update_widgets(self, prefix=None):
     """Widgets update"""
     super().update_widgets(prefix)  # pylint: disable=no-member
     session = self.widgets.get('session_name')  # pylint: disable=no-member
     if session is not None:
         translate = self.request.localizer.translate  # pylint: disable=no-member
         session.placeholder = translate(_("Select connection name..."))
     query = self.widgets.get('query')  # pylint: disable=no-member
     if query is not None:
         query.add_class('height-100')
         query.widget_css_class = "editor height-400px"
         query.object_data = {
             'ams-filename': 'query.sql'
         }
         alsoProvides(query, IObjectData)
コード例 #8
0
ファイル: engine.py プロジェクト: Py-AMS/pyams-alchemy
class AlchemyEngineEditForm(AdminModalEditForm):
    """SQLAlchemy engine properties edit form"""

    @property
    def title(self):
        translate = self.request.localizer.translate
        manager = query_utility(IAlchemyManager)
        return '<small>{}</small><br />{}'.format(
            get_object_label(manager, self.request, self),
            translate(_("SQL engine: {}")).format(self.context.name))

    legend = _("SQL engine properties")

    fields = Fields(IAlchemyEngineUtility)

    def update_widgets(self, prefix=None):
        super().update_widgets(prefix)
        name = self.widgets.get('name')
        if name is not None:
            name.mode = DISPLAY_MODE
コード例 #9
0
ファイル: __init__.py プロジェクト: Py-AMS/pyams-alchemy
class AlchemyTaskFormInfo(GroupManager):
    """SQLAlchemy task form info"""

    title = _("SQL task settings")
    fields = Fields(IAlchemyTaskInfo)

    def update_widgets(self, prefix=None):
        """Widgets update"""
        super().update_widgets(prefix)  # pylint: disable=no-member
        session = self.widgets.get('session_name')  # pylint: disable=no-member
        if session is not None:
            translate = self.request.localizer.translate  # pylint: disable=no-member
            session.placeholder = translate(_("Select connection name..."))
        query = self.widgets.get('query')  # pylint: disable=no-member
        if query is not None:
            query.add_class('height-100')
            query.widget_css_class = "editor height-400px"
            query.object_data = {
                'ams-filename': 'query.sql'
            }
            alsoProvides(query, IObjectData)
コード例 #10
0
ファイル: __init__.py プロジェクト: Py-AMS/pyams-alchemy
class AlchemyTask(Task):
    """SQLAlchemy task"""

    label = _("SQL query")
    icon_class = 'fas fa-database'

    session_name = FieldProperty(IAlchemyTask['session_name'])
    query = FieldProperty(IAlchemyTask['query'])
    output_format = FieldProperty(IAlchemyTask['output_format'])

    def run(self, report, **kwargs):  # pylint: disable=unused-argument
        """Run SQL query task"""
        try:
            session = get_user_session(self.session_name, join=False, twophase=False,
                                       use_zope_extension=False)
            try:
                report.write('SQL query output\n'
                             '================\n')
                report.write('SQL query: \n    {}\n\n'.format(
                    self.query.replace('\r', '').replace('\n', '\n    ')))
                results = session.execute(self.query)
                session.commit()
                converter = get_utility(IAlchemyConverter, name=self.output_format)
                result = converter.convert(results)
                report.write('SQL output ({} records):\n\n'.format(results.rowcount))
                report.write(result)
                return TASK_STATUS_OK, result
            except ResourceClosedError:
                report.write('SQL query returned no result.\n')
                return TASK_STATUS_EMPTY, None
        except SQLAlchemyError:
            session.rollback()
            etype, value, tb = sys.exc_info()  # pylint: disable=invalid-name
            report.write('\n\n'
                         'An SQL error occurred\n'
                         '=====================\n')
            report.write(''.join(traceback.format_exception(etype, value, tb)))
            return TASK_STATUS_ERROR, None
コード例 #11
0
ファイル: __init__.py プロジェクト: Py-AMS/pyams-alchemy
class AlchemyTaskAddMenu(MenuItem):
    """SQLAlchemy task add menu"""

    label = _("Add SQL query...")
    href = 'add-sql-task.html'
    modal_target = True
コード例 #12
0
ファイル: __init__.py プロジェクト: Py-AMS/pyams-alchemy
class AlchemyManagerEnginesListMenu(NavigationMenuItem):
    """SQLAlchemy manager engines list menu"""

    label = _("SQL engines")
    icon_class = 'fas fa-table'
    href = '#engines-list.html'
コード例 #13
0
class IAlchemyEngineUtility(IAttributeAnnotatable):
    """SQLAlchemy engine definition interface"""

    name = TextLine(
        title=_("Engine name"),
        description=_("Keep empty if this engine is the default engine..."),
        required=False,
        default='')

    dsn = TextLine(
        title=_('DSN'),
        description=_('RFC-1738 compliant URL for the database connection'),
        required=True,
        default=u'sqlite://')

    echo = Bool(title=_('Echo SQL?'),
                description=_("Log all SQL statements to system logger"),
                required=True,
                default=False)

    use_pool = Bool(
        title=_("Use connections pool?"),
        description=_("If 'no', collections pooling will be disabled"),
        required=True,
        default=True)

    pool_size = Int(title=_("Pool size"),
                    description=_("SQLAlchemy connections pool size"),
                    required=False,
                    default=25)

    pool_recycle = Int(
        title=_("Pool recycle time"),
        description=_("SQLAlchemy connection recycle time (-1 for none)"),
        required=False,
        default=-1)

    echo_pool = Bool(
        title=_("Echo pool?"),
        description=_("Log all pool checkouts/checkins to system logger?"),
        required=True,
        default=False)

    encoding = Choice(title=_('Encoding'),
                      required=True,
                      vocabulary=ENCODINGS_VOCABULARY_NAME,
                      default='utf-8')

    convert_unicode = Bool(title=_('Convert Unicode'),
                           required=True,
                           default=False)

    twophase = Bool(title=_("Two-phases commit?"),
                    description=_(
                        "Disable this option if two-phases commits should be "
                        "disabled (for SQLite for example)"),
                    required=True,
                    default=True)

    def get_engine(self, use_pool=True):
        """Get SQLAlchemy engine"""

    def clear_engine(self):
        """Remove inner volatile attributes when utility properties are modified"""
コード例 #14
0
class IAlchemyManagerRoles(IContentRoles):
    """SQLAlchemy manager roles"""

    sql_managers = PrincipalsSetField(title=_("SQL managers"),
                                      role_id=SQL_MANAGER_ROLE,
                                      required=False)
コード例 #15
0
ファイル: engine.py プロジェクト: Py-AMS/pyams-alchemy
class AlchemyEngineAddAction(ContextAddAction):
    """Alchemy engine add action"""

    label = _("Add SQL engine")
    href = 'add-sql-engine.html'
コード例 #16
0
ファイル: engine.py プロジェクト: Py-AMS/pyams-alchemy
 def title(self):
     translate = self.request.localizer.translate
     manager = query_utility(IAlchemyManager)
     return '<small>{}</small><br />{}'.format(
         get_object_label(manager, self.request, self),
         translate(_("SQL engine: {}")).format(self.context.name))
コード例 #17
0
ファイル: __init__.py プロジェクト: Py-AMS/pyams-alchemy
from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
from pyams_utils.url import absolute_url
from pyams_viewlet.manager import viewletmanager_config
from pyams_zmi.helper.container import delete_container_element
from pyams_zmi.interfaces import IAdminLayer, IObjectLabel
from pyams_zmi.interfaces.table import ITableElementEditor
from pyams_zmi.interfaces.viewlet import IMenuHeader, IPropertiesMenu, ISiteManagementMenu
from pyams_zmi.table import NameColumn, Table, TableAdminView, \
    TableElementEditor, TrashColumn
from pyams_zmi.zmi.viewlet.menu import NavigationMenuItem

__docformat__ = 'restructuredtext'

from pyams_alchemy import _  # pylint: disable=ungrouped-imports

ALCHEMY_MANAGER_LABEL = _("SQL connections")


@adapter_config(required=(IAlchemyManager, IPyAMSLayer, Interface),
                provides=IObjectLabel)
def alchemy_manager_label(context, request, view):
    """Alchemy manager label"""
    return request.localizer.translate(ALCHEMY_MANAGER_LABEL)


@adapter_config(required=(IAlchemyManager, IAdminLayer, Interface,
                          ISiteManagementMenu),
                provides=IMenuHeader)
def alchemy_manager_menu_header(context, request, view, manager):  # pylint: disable=unused-argument
    """SQLAlchemy manager menu header"""
    return ALCHEMY_MANAGER_LABEL
コード例 #18
0
ファイル: engine.py プロジェクト: Py-AMS/pyams-alchemy
 def title(self):
     translate = self.request.localizer.translate
     return '<small>{}</small><br />{}'.format(
         get_object_label(self.context, self.request, self),
         translate(_("New SQL engine")))