| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | # |
|---|
| 3 | # Copyright (C) 2010-2015 Roberto Longobardi |
|---|
| 4 | # Copyright (C) 2021 Cinc |
|---|
| 5 | # |
|---|
| 6 | # This file is part of the Test Manager plugin for Trac. |
|---|
| 7 | # |
|---|
| 8 | # This software is licensed as described in the file COPYING, which |
|---|
| 9 | # you should have received as part of this distribution. The terms |
|---|
| 10 | # are also available at: |
|---|
| 11 | # https://trac-hacks.org/wiki/TestManagerForTracPluginLicense |
|---|
| 12 | # |
|---|
| 13 | # Author: Roberto Longobardi <otrebor.dev@gmail.com> |
|---|
| 14 | # |
|---|
| 15 | |
|---|
| 16 | from trac.core import Component, implements |
|---|
| 17 | from trac.db import Table, Column |
|---|
| 18 | from trac.env import IEnvironmentSetupParticipant |
|---|
| 19 | from trac.util.translation import N_ |
|---|
| 20 | |
|---|
| 21 | from codereview.tracgenericclass.model import IConcreteClassProvider, AbstractVariableFieldsObject, \ |
|---|
| 22 | need_db_create_for_realm, create_db_for_realm, need_db_upgrade_for_realm, upgrade_db_for_realm |
|---|
| 23 | |
|---|
| 24 | |
|---|
| 25 | class ResourceWorkflowState(AbstractVariableFieldsObject): |
|---|
| 26 | """ |
|---|
| 27 | This object represents the current workflow state of the associated |
|---|
| 28 | resource. |
|---|
| 29 | """ |
|---|
| 30 | |
|---|
| 31 | # Fields that must not be modified directly by the user |
|---|
| 32 | protected_fields = ('id', 'res_realm', 'state') |
|---|
| 33 | |
|---|
| 34 | def __init__(self, env, id_=None, res_realm=None, state='new', db=None): |
|---|
| 35 | """ |
|---|
| 36 | The resource workflow state is related to a resource, the 'id' |
|---|
| 37 | and 'res_realm' arguments. |
|---|
| 38 | The state can be any string. |
|---|
| 39 | """ |
|---|
| 40 | self.values = {} |
|---|
| 41 | |
|---|
| 42 | self.values['id'] = id_ |
|---|
| 43 | self.values['res_realm'] = res_realm |
|---|
| 44 | self.values['state'] = state |
|---|
| 45 | |
|---|
| 46 | key = self.build_key_object() |
|---|
| 47 | |
|---|
| 48 | AbstractVariableFieldsObject.__init__(self, env, 'resourceworkflowstate', key, db) |
|---|
| 49 | |
|---|
| 50 | def get_key_prop_names(self): |
|---|
| 51 | return ['id', 'res_realm'] |
|---|
| 52 | |
|---|
| 53 | def create_instance(self, key): |
|---|
| 54 | return ResourceWorkflowState(self.env, key['id'], key['res_realm']) |
|---|
| 55 | |
|---|
| 56 | |
|---|
| 57 | class GenericWorkflowModelProvider(Component): |
|---|
| 58 | """ |
|---|
| 59 | This class provides the data model for the generic workflow plugin. |
|---|
| 60 | |
|---|
| 61 | The actual data model on the db is created starting from the |
|---|
| 62 | SCHEMA declaration below. |
|---|
| 63 | For each table, we specify whether to create also a '_custom' and |
|---|
| 64 | a '_change' table. |
|---|
| 65 | |
|---|
| 66 | This class also provides the specification of the available fields |
|---|
| 67 | for each class, being them standard fields and the custom fields |
|---|
| 68 | specified in the trac.ini file. |
|---|
| 69 | The custom field specification follows the same syntax as for |
|---|
| 70 | Tickets. |
|---|
| 71 | Currently, only 'text' type of custom fields are supported. |
|---|
| 72 | """ |
|---|
| 73 | |
|---|
| 74 | implements(IConcreteClassProvider, IEnvironmentSetupParticipant) |
|---|
| 75 | |
|---|
| 76 | SCHEMA = { |
|---|
| 77 | 'resourceworkflowstate': |
|---|
| 78 | {'table': |
|---|
| 79 | Table('resourceworkflowstate', key = ('id', 'res_realm'))[ |
|---|
| 80 | Column('id'), |
|---|
| 81 | Column('res_realm'), |
|---|
| 82 | Column('state')], |
|---|
| 83 | 'has_custom': True, |
|---|
| 84 | 'has_change': True, |
|---|
| 85 | 'version': 1} |
|---|
| 86 | } |
|---|
| 87 | |
|---|
| 88 | FIELDS = { |
|---|
| 89 | 'resourceworkflowstate': [ |
|---|
| 90 | {'name': 'id', 'type': 'text', 'label': N_('ID')}, |
|---|
| 91 | {'name': 'res_realm', 'type': 'text', 'label': N_('Resource realm')}, |
|---|
| 92 | {'name': 'state', 'type': 'text', 'label': N_('Workflow state')} |
|---|
| 93 | ] |
|---|
| 94 | } |
|---|
| 95 | |
|---|
| 96 | METADATA = { |
|---|
| 97 | 'resourceworkflowstate': { |
|---|
| 98 | 'label': "Workflow State", |
|---|
| 99 | 'searchable': False, |
|---|
| 100 | 'has_custom': True, |
|---|
| 101 | 'has_change': True |
|---|
| 102 | }, |
|---|
| 103 | } |
|---|
| 104 | |
|---|
| 105 | |
|---|
| 106 | # IConcreteClassProvider methods |
|---|
| 107 | def get_realms(self): |
|---|
| 108 | yield 'resourceworkflowstate' |
|---|
| 109 | |
|---|
| 110 | def get_data_models(self): |
|---|
| 111 | return self.SCHEMA |
|---|
| 112 | |
|---|
| 113 | def get_fields(self): |
|---|
| 114 | return self.FIELDS |
|---|
| 115 | |
|---|
| 116 | def get_metadata(self): |
|---|
| 117 | return self.METADATA |
|---|
| 118 | |
|---|
| 119 | def create_instance(self, realm, key=None): |
|---|
| 120 | obj = None |
|---|
| 121 | |
|---|
| 122 | if realm == 'resourceworkflowstate': |
|---|
| 123 | if key is not None: |
|---|
| 124 | obj = ResourceWorkflowState(self.env, key['id'], key['res_realm']) |
|---|
| 125 | else: |
|---|
| 126 | obj = ResourceWorkflowState(self.env) |
|---|
| 127 | |
|---|
| 128 | return obj |
|---|
| 129 | |
|---|
| 130 | def check_permission(self, req, realm, key_str=None, operation='set', name=None, value=None): |
|---|
| 131 | pass |
|---|
| 132 | |
|---|
| 133 | # IEnvironmentSetupParticipant methods |
|---|
| 134 | def environment_created(self): |
|---|
| 135 | self.upgrade_environment() |
|---|
| 136 | |
|---|
| 137 | def environment_needs_upgrade(self, db=None): |
|---|
| 138 | for realm in self.SCHEMA: |
|---|
| 139 | realm_metadata = self.SCHEMA[realm] |
|---|
| 140 | |
|---|
| 141 | if need_db_create_for_realm(self.env, realm, realm_metadata, db) or \ |
|---|
| 142 | need_db_upgrade_for_realm(self.env, realm, realm_metadata, db): |
|---|
| 143 | |
|---|
| 144 | return True |
|---|
| 145 | return False |
|---|
| 146 | |
|---|
| 147 | def upgrade_environment(self, db=None): |
|---|
| 148 | # Create or update db |
|---|
| 149 | with self.env.db_transaction as db: |
|---|
| 150 | for realm in self.SCHEMA: |
|---|
| 151 | realm_metadata = self.SCHEMA[realm] |
|---|
| 152 | |
|---|
| 153 | if need_db_create_for_realm(self.env, realm, realm_metadata, db): |
|---|
| 154 | create_db_for_realm(self.env, realm, realm_metadata, db) |
|---|
| 155 | |
|---|
| 156 | elif need_db_upgrade_for_realm(self.env, realm, realm_metadata, db): |
|---|
| 157 | upgrade_db_for_realm(self.env, 'tracgenericworkflow.upgrades', realm, realm_metadata, db) |
|---|