Handler table dependencies.

This commit is contained in:
Albert Cervera i Areny 2023-05-19 19:58:52 +02:00
parent 0e8e10ffe6
commit c5e0c7c310
9 changed files with 382 additions and 43 deletions

View File

@ -45,6 +45,7 @@ def register():
test_model.TestBabiModel,
table.Table,
table.Field,
table.TableDependency,
module='babi', type_='model')
Pool.register(
babi.OpenChart,

View File

@ -1,6 +1,17 @@
#
# Albert Cervera i Areny <albert@nan-tic.com>, 2023.
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Last-Translator: Albert Cervera i Areny <albert@nan-tic.com>\n"
"PO-Revision-Date: 2023-05-19 19:58+0200\n"
"Project-Id-Version: \n"
"Language-Team: Catalan <kde-i18n-ca@kde.org>\n"
"Language: ca_ES\n"
"Content-Transfer-Encoding: 8bit\n"
"MIME-Version: 1.0\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Lokalize 20.12.0\n"
msgctxt "field:babi.action.dashboard,action:"
msgid "Action"
@ -74,6 +85,10 @@ msgctxt "field:babi.dashboard.item,dashboard:"
msgid "Dashboard"
msgstr "Tauler de control"
msgctxt "field:babi.dashboard.item,height:"
msgid "Height"
msgstr "Alçada"
msgctxt "field:babi.dashboard.item,parent:"
msgid "Parent"
msgstr "Pare"
@ -554,6 +569,10 @@ msgctxt "field:babi.table,babi_raise_user_error:"
msgid "Raise User Error"
msgstr "Mostrar l'error al usuari"
msgctxt "field:babi.table,compute_error:"
msgid "Compute Error"
msgstr "Error de càlcul"
msgctxt "field:babi.table,crons:"
msgid "Schedulers"
msgstr "Tasques planificades"
@ -578,10 +597,30 @@ msgctxt "field:babi.table,name:"
msgid "Name"
msgstr "Nom"
msgctxt "field:babi.table,preview:"
msgid "Preview"
msgstr "Vista prèvia"
msgctxt "field:babi.table,preview_filename:"
msgid "Preview Filename"
msgstr "Vista prèvia del nom del fitxer"
msgctxt "field:babi.table,preview_limit:"
msgid "Preview Limit"
msgstr "Límit de previsualització"
msgctxt "field:babi.table,query:"
msgid "Query"
msgstr "Consulta"
msgctxt "field:babi.table,required_by:"
msgid "Required By"
msgstr "Requerit per"
msgctxt "field:babi.table,requires:"
msgid "Requires"
msgstr "Requereix"
msgctxt "field:babi.table,timeout:"
msgid "Timeout"
msgstr "Timeout"
@ -590,6 +629,18 @@ msgctxt "field:babi.table,type:"
msgid "Type"
msgstr "Tipus"
msgctxt "field:babi.table.dependency,name:"
msgid "Name"
msgstr "Nom"
msgctxt "field:babi.table.dependency,required_by:"
msgid "Required By"
msgstr "Requerit per"
msgctxt "field:babi.table.dependency,table:"
msgid "Requires"
msgstr "Requereix"
msgctxt "field:babi.test,amount:"
msgid "Amount"
msgstr "Import"
@ -734,6 +785,10 @@ msgctxt "help:babi.configuration,report_cell_level:"
msgid "Start cell level that not has indentation"
msgstr "Nivell d'inici de cel·la no té sagnat."
msgctxt "help:babi.dashboard.item,height:"
msgid "The default is 450px"
msgstr "El valor predeterminat és de 450 píxels"
msgctxt "help:babi.dimension,width:"
msgid "Width report columns (%)"
msgstr "Amplada de les columnes de l'informe (%)"
@ -747,7 +802,8 @@ msgid ""
"Python expression that will return the value to be used.\n"
"The expression can include the following variables:\n"
"\n"
"- \"o\": A reference to the current record being processed. For example: \"o.party.name\"\n"
"- \"o\": A reference to the current record being processed. For example:"
" \"o.party.name\"\n"
"\n"
"And the following functions apply to dates and timestamps:\n"
"\n"
@ -761,7 +817,8 @@ msgstr ""
"Expressió Python que returnarà el valor utilitzar.\n"
"L'expressió pot incloure les següent variables:\n"
"\n"
"- \"o\": Referència al registre que s'està tractant actualment. Per exemple: \"o.party.name\"\n"
"- \"o\": Referència al registre que s'està tractant actualment. Per exemple:"
" \"o.party.name\"\n"
"\n"
"I les següents funcions apliquen a camps de data: \n"
"\n"
@ -946,6 +1003,10 @@ msgctxt "model:babi.table,name:"
msgid "BABI Table"
msgstr "Taula BABI"
msgctxt "model:babi.table.dependency,name:"
msgid "BABI Table Dependency"
msgstr "Taula BABI Dependència"
msgctxt "model:babi.test,name:"
msgid "Test BABI Model"
msgstr "Model de proves BABI"
@ -1076,18 +1137,22 @@ msgstr "S'ha produït una excepció: %(error)s"
msgctxt "model:ir.message,text:create_data_exception_dimension"
msgid ""
"An Exception Occurred: On dimensions, with expression %(expression)s on record %(record)s.\n"
"An Exception Occurred: On dimensions, with expression %(expression)s on"
" record %(record)s.\n"
"Exception: %(error)s"
msgstr ""
"S'ha produït una excepció: a les dimensions, amb l'expressió %(expression)s al registre %(record)s.\n"
"S'ha produït una excepció: a les dimensions, amb l'expressió %(expression)s"
" al registre %(record)s.\n"
"Excepció: %(error)s"
msgctxt "model:ir.message,text:create_data_exception_measures"
msgid ""
"An Exception Occurred: On measures, with expression %(expression)s on record %(record)s.\n"
"An Exception Occurred: On measures, with expression %(expression)s on record "
"%(record)s.\n"
"Exception: %(error)s"
msgstr ""
"S'ha produït una excepció: a les mesures, amb l'expressió %(expression)s al registre %(record)s.\n"
"S'ha produït una excepció: a les mesures, amb l'expressió %(expression)s al"
" registre %(record)s.\n"
"Excepció: %(error)s"
msgctxt "model:ir.message,text:false"
@ -1119,9 +1184,18 @@ msgstr ""
"El nombre de registres \"%(count)s\" supera el límit \"%(limit)s\" per al "
"gràfic \"%(widget)s\". Heu de restringir la consulta o augmentar el límit."
msgctxt "model:ir.message,text:msg_circular_dependency"
msgid ""
"Circular dependency with the following table sequence:\n"
"\n"
"\"%(sequence)s\""
msgstr ""
"Dependència circular amb la següent seqüència de taules: \"%(sequence)s\""
msgctxt "model:ir.message,text:msg_compute_table_exception"
msgid ""
"An exception occurred while computing the value for field \"%(field)s\" in table \"%(table)s\", record \"%(record)s\". The error was:\n"
"An exception occurred while computing the value for field \"%(field)s\" in"
" table \"%(table)s\", record \"%(record)s\". The error was:\n"
"\n"
"%(error)s"
msgstr ""
@ -1144,8 +1218,7 @@ msgctxt "model:ir.message,text:msg_invalid_field_internal_name"
msgid "Invalid internal name \"%(internal_name)s\" in field \"%(field)s\"."
msgstr "El nom intern \"%(internal_name)s\" no és vàlid al camp \"%(field)s\"."
msgctxt ""
"model:ir.message,text:msg_invalid_field_internal_name_first_character"
msgctxt "model:ir.message,text:msg_invalid_field_internal_name_first_character"
msgid ""
"Invalid first character in internal name \"%(internal_name)s\" in field "
"\"%(field)s\"."
@ -1163,10 +1236,10 @@ msgstr ""
msgctxt "model:ir.message,text:msg_invalid_table_internal_name"
msgid "Invalid internal name \"%(internal_name)s\" in table \"%(table)s\"."
msgstr "El nom intern \"%(internal_name)s\" no és vàlid a la taula \"%(table)s\"."
msgstr ""
"El nom intern \"%(internal_name)s\" no és vàlid a la taula \"%(table)s\"."
msgctxt ""
"model:ir.message,text:msg_invalid_table_internal_name_first_character"
msgctxt "model:ir.message,text:msg_invalid_table_internal_name_first_character"
msgid ""
"Invalid first character in internal name \"%(internal_name)s\" in table "
"\"%(table)s\"."
@ -1205,10 +1278,18 @@ msgstr ""
"El càlcul de l'informe \"%(report)s\" s'ha avortat perquè ha trigat més de "
"%(segons)s a calcular-se."
msgctxt "model:ir.message,text:msg_table_failed"
msgid "Computation of \"%(table)s\" failed."
msgstr "El càlcul de \"%(table)s\" ha fallat."
msgctxt "model:ir.message,text:msg_table_no_fields"
msgid "Table \"%(table)s\" cannot be computed because it has no fields."
msgstr "La taula \"%(table)s\" no es pot calcular perquè no té camps."
msgctxt "model:ir.message,text:msg_table_successful"
msgid "Computation of \"%(table)s\" finished successfully."
msgstr "El càlcul de \"%(table)s\" ha finalitzat correctament."
msgctxt "model:ir.message,text:msg_too_many_parameters"
msgid ""
"There can not be more than \"%(max)s\" parameters of type \"%(type)s\" in "
@ -1219,11 +1300,13 @@ msgstr ""
msgctxt "model:ir.message,text:msg_widget_help"
msgid ""
"The following is the list of valid parameter types wth the number of minimum and maximum occurrences allowed:\n"
"The following is the list of valid parameter types wth the number of minimum"
" and maximum occurrences allowed:\n"
"\n"
"%(list)s"
msgstr ""
"La següent és la llista de tipus de paràmetres vàlids amb el nombre d'ocurrències mínim i màxim permesos:\n"
"La següent és la llista de tipus de paràmetres vàlids amb el nombre"
" d'ocurrències mínim i màxim permesos:\n"
"\n"
"%(list)s"
@ -1283,7 +1366,8 @@ msgctxt "model:ir.message,text:report_not_exists"
msgid ""
"Report \"%(report)s\" no longer exists or you do not have the rights to "
"access it."
msgstr "Linforme \"%(report)s\" ja no existeix o no teniu els permissos d'accés."
msgstr ""
"Linforme \"%(report)s\" ja no existeix o no teniu els permissos d'accés."
msgctxt "model:ir.message,text:timeout_exception"
msgid ""
@ -1809,6 +1893,10 @@ msgctxt "selection:babi.widget.parameter,aggregate:"
msgid "Maximum"
msgstr "Màxim"
msgctxt "selection:babi.widget.parameter,aggregate:"
msgid "Median"
msgstr "Mitjana"
msgctxt "selection:babi.widget.parameter,aggregate:"
msgid "Minimum"
msgstr "Mínim"
@ -1997,6 +2085,10 @@ msgctxt "view:babi.table:"
msgid "Configuration"
msgstr "Configuració"
msgctxt "view:babi.table:"
msgid "Dependencies"
msgstr "Dependències"
msgctxt "view:babi.update_data.wizard.done:"
msgid "The data for the report has been calculated"
msgstr "S'ha calculat la informació de l'informe."

View File

@ -1,6 +1,17 @@
#
# Albert Cervera i Areny <albert@nan-tic.com>, 2023.
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Last-Translator: Albert Cervera i Areny <albert@nan-tic.com>\n"
"PO-Revision-Date: 2023-05-19 19:57+0200\n"
"Project-Id-Version: \n"
"Language-Team: Catalan <kde-i18n-ca@kde.org>\n"
"Language: ca_ES\n"
"Content-Transfer-Encoding: 8bit\n"
"MIME-Version: 1.0\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Lokalize 20.12.0\n"
msgctxt "field:babi.action.dashboard,action:"
msgid "Action"
@ -74,6 +85,10 @@ msgctxt "field:babi.dashboard.item,dashboard:"
msgid "Dashboard"
msgstr "Tablero"
msgctxt "field:babi.dashboard.item,height:"
msgid "Height"
msgstr "Altura"
msgctxt "field:babi.dashboard.item,parent:"
msgid "Parent"
msgstr "Padre"
@ -554,6 +569,10 @@ msgctxt "field:babi.table,babi_raise_user_error:"
msgid "Raise User Error"
msgstr "Mostrar el error al usuario"
msgctxt "field:babi.table,compute_error:"
msgid "Compute Error"
msgstr "Error en cálculo"
msgctxt "field:babi.table,crons:"
msgid "Schedulers"
msgstr "Tareas planificadas"
@ -578,10 +597,30 @@ msgctxt "field:babi.table,name:"
msgid "Name"
msgstr "Nombre"
msgctxt "field:babi.table,preview:"
msgid "Preview"
msgstr "Vista previa"
msgctxt "field:babi.table,preview_filename:"
msgid "Preview Filename"
msgstr "Nombre de archivo de la vista previa"
msgctxt "field:babi.table,preview_limit:"
msgid "Preview Limit"
msgstr "Límite de vista previa"
msgctxt "field:babi.table,query:"
msgid "Query"
msgstr "Consulta"
msgctxt "field:babi.table,required_by:"
msgid "Required By"
msgstr "Requerido por"
msgctxt "field:babi.table,requires:"
msgid "Requires"
msgstr "Requiere"
msgctxt "field:babi.table,timeout:"
msgid "Timeout"
msgstr "Timeout"
@ -590,6 +629,18 @@ msgctxt "field:babi.table,type:"
msgid "Type"
msgstr "Tipo"
msgctxt "field:babi.table.dependency,name:"
msgid "Name"
msgstr "Nombre"
msgctxt "field:babi.table.dependency,required_by:"
msgid "Required By"
msgstr "Requerido por"
msgctxt "field:babi.table.dependency,table:"
msgid "Requires"
msgstr "Requiere"
msgctxt "field:babi.test,amount:"
msgid "Amount"
msgstr "Importe"
@ -734,6 +785,10 @@ msgctxt "help:babi.configuration,report_cell_level:"
msgid "Start cell level that not has indentation"
msgstr "Nivel de inicio de celda no tiene sangría."
msgctxt "help:babi.dashboard.item,height:"
msgid "The default is 450px"
msgstr "El valor predeterminado es 450px"
msgctxt "help:babi.dimension,width:"
msgid "Width report columns (%)"
msgstr "Ancho de las columnas del informe (%)"
@ -747,7 +802,8 @@ msgid ""
"Python expression that will return the value to be used.\n"
"The expression can include the following variables:\n"
"\n"
"- \"o\": A reference to the current record being processed. For example: \"o.party.name\"\n"
"- \"o\": A reference to the current record being processed. For example:"
" \"o.party.name\"\n"
"\n"
"And the following functions apply to dates and timestamps:\n"
"\n"
@ -762,7 +818,8 @@ msgstr ""
"La expresión puede incluir las siguientes variables:\n"
"Python expression that will return the value to be used.\n"
"\n"
"- \"o\": Una referencia al registro al que se tiene acceso actualmente. Por ejemplo: \"o.party.name\"\n"
"- \"o\": Una referencia al registro al que se tiene acceso actualmente. Por"
" ejemplo: \"o.party.name\"\n"
"\n"
"Y las siguientes funciones a aplicar a fechas y marcas de tiempo:\n"
"\n"
@ -946,6 +1003,10 @@ msgctxt "model:babi.table,name:"
msgid "BABI Table"
msgstr "Tabla BABI"
msgctxt "model:babi.table.dependency,name:"
msgid "BABI Table Dependency"
msgstr "Dependencia de la tabla BABI"
msgctxt "model:babi.test,name:"
msgid "Test BABI Model"
msgstr "Modelo de pruebas babi"
@ -1076,18 +1137,22 @@ msgstr "Se ha producido una excepción: %(error)s"
msgctxt "model:ir.message,text:create_data_exception_dimension"
msgid ""
"An Exception Occurred: On dimensions, with expression %(expression)s on record %(record)s.\n"
"An Exception Occurred: On dimensions, with expression %(expression)s on"
" record %(record)s.\n"
"Exception: %(error)s"
msgstr ""
"Se ha producido una excepción: en las dimensiones, con la expresión %(expression)s en el registro %(record)s.\n"
"Se ha producido una excepción: en las dimensiones, con la expresión "
"%(expression)s en el registro %(record)s.\n"
"Excepción: %(error)s"
msgctxt "model:ir.message,text:create_data_exception_measures"
msgid ""
"An Exception Occurred: On measures, with expression %(expression)s on record %(record)s.\n"
"An Exception Occurred: On measures, with expression %(expression)s on record "
"%(record)s.\n"
"Exception: %(error)s"
msgstr ""
"Se ha producido una excepción: en las medidas, con la expresión %(expression)s en el registro %(record)s.\n"
"Se ha producido una excepción: en las medidas, con la expresión "
"%(expression)s en el registro %(record)s.\n"
"Excepción: %(error)s"
msgctxt "model:ir.message,text:false"
@ -1119,9 +1184,18 @@ msgstr ""
"El número de registros \"%(count)s\" supera el límite \"%(limit)s\" para el "
"gráfico \"%(widget)s\". Debe limitar la consulta o aumentar el límite."
msgctxt "model:ir.message,text:msg_circular_dependency"
msgid ""
"Circular dependency with the following table sequence:\n"
"\n"
"\"%(sequence)s\""
msgstr ""
"Dependencia circular en la siguiente secuencia de tablas: \"%(secuencia)s\""
msgctxt "model:ir.message,text:msg_compute_table_exception"
msgid ""
"An exception occurred while computing the value for field \"%(field)s\" in table \"%(table)s\", record \"%(record)s\". The error was:\n"
"An exception occurred while computing the value for field \"%(field)s\" in"
" table \"%(table)s\", record \"%(record)s\". The error was:\n"
"\n"
"%(error)s"
msgstr ""
@ -1142,10 +1216,10 @@ msgstr ""
msgctxt "model:ir.message,text:msg_invalid_field_internal_name"
msgid "Invalid internal name \"%(internal_name)s\" in field \"%(field)s\"."
msgstr "Nombre interno no válido \"%(internal_name)s\" en el campo \"%(field)s\"."
msgstr ""
"Nombre interno no válido \"%(internal_name)s\" en el campo \"%(field)s\"."
msgctxt ""
"model:ir.message,text:msg_invalid_field_internal_name_first_character"
msgctxt "model:ir.message,text:msg_invalid_field_internal_name_first_character"
msgid ""
"Invalid first character in internal name \"%(internal_name)s\" in field "
"\"%(field)s\"."
@ -1163,10 +1237,10 @@ msgstr ""
msgctxt "model:ir.message,text:msg_invalid_table_internal_name"
msgid "Invalid internal name \"%(internal_name)s\" in table \"%(table)s\"."
msgstr "Nombre interno no válido \"%(internal_name)s\" en la tabla \"%(table)s\"."
msgstr ""
"Nombre interno no válido \"%(internal_name)s\" en la tabla \"%(table)s\"."
msgctxt ""
"model:ir.message,text:msg_invalid_table_internal_name_first_character"
msgctxt "model:ir.message,text:msg_invalid_table_internal_name_first_character"
msgid ""
"Invalid first character in internal name \"%(internal_name)s\" in table "
"\"%(table)s\"."
@ -1205,10 +1279,18 @@ msgstr ""
"Se anuló el cálculo del informe \"%(report)s\" porque tardó más de "
"%(segundos)s en calcularse."
msgctxt "model:ir.message,text:msg_table_failed"
msgid "Computation of \"%(table)s\" failed."
msgstr "El cálculo de \"%(table)s\" falló."
msgctxt "model:ir.message,text:msg_table_no_fields"
msgid "Table \"%(table)s\" cannot be computed because it has no fields."
msgstr "La tabla \"%(table)s\" no puede ser calculada porque no tiene campos."
msgctxt "model:ir.message,text:msg_table_successful"
msgid "Computation of \"%(table)s\" finished successfully."
msgstr "El cálculo de \"%(table)s\" finalizó correctamente."
msgctxt "model:ir.message,text:msg_too_many_parameters"
msgid ""
"There can not be more than \"%(max)s\" parameters of type \"%(type)s\" in "
@ -1219,11 +1301,13 @@ msgstr ""
msgctxt "model:ir.message,text:msg_widget_help"
msgid ""
"The following is the list of valid parameter types wth the number of minimum and maximum occurrences allowed:\n"
"The following is the list of valid parameter types wth the number of minimum"
" and maximum occurrences allowed:\n"
"\n"
"%(list)s"
msgstr ""
"La siguiente es la lista de tipos de parámetros válidos con el número de ocurrencias mínimas y máximas permitidas:\n"
"La siguiente es la lista de tipos de parámetros válidos con el número de"
" ocurrencias mínimas y máximas permitidas:\n"
"\n"
"%(list)s"
@ -1283,7 +1367,8 @@ msgctxt "model:ir.message,text:report_not_exists"
msgid ""
"Report \"%(report)s\" no longer exists or you do not have the rights to "
"access it."
msgstr "El informe \"%(report)s\" ya no existe o no tiene los permisos de acceso."
msgstr ""
"El informe \"%(report)s\" ya no existe o no tiene los permisos de acceso."
msgctxt "model:ir.message,text:timeout_exception"
msgid ""
@ -1809,6 +1894,10 @@ msgctxt "selection:babi.widget.parameter,aggregate:"
msgid "Maximum"
msgstr "Máximo"
msgctxt "selection:babi.widget.parameter,aggregate:"
msgid "Median"
msgstr "Mediana"
msgctxt "selection:babi.widget.parameter,aggregate:"
msgid "Minimum"
msgstr "Mínimo"
@ -1997,6 +2086,10 @@ msgctxt "view:babi.table:"
msgid "Configuration"
msgstr "Configuración"
msgctxt "view:babi.table:"
msgid "Dependencies"
msgstr "Dependencias"
msgctxt "view:babi.update_data.wizard.done:"
msgid "The data for the report has been calculated"
msgstr "Se ha calculado la información para este informe."

View File

@ -125,5 +125,10 @@ Exception: %(error)s</field>
<record model="ir.message" id="msg_table_failed">
<field name="text">Computation of "%(table)s" failed.</field>
</record>
<record model="ir.message" id="msg_circular_dependency">
<field name="text">Circular dependency with the following table sequence:
"%(sequence)s"</field>
</record>
</data>
</tryton>

129
table.py
View File

@ -116,6 +116,10 @@ class Table(DeactivableMixin, ModelSQL, ModelView):
crons = fields.One2Many('ir.cron', 'babi_table', 'Schedulers', context={
'babi_table': Eval('id'),
}, depends=['id'])
requires = fields.One2Many('babi.table.dependency', 'required_by',
'Requires', readonly=True)
required_by = fields.One2Many('babi.table.dependency', 'table',
'Required By', readonly=True)
@staticmethod
def default_timeout():
@ -132,6 +136,83 @@ class Table(DeactivableMixin, ModelSQL, ModelView):
super().__setup__()
cls._order.insert(0, ('name', 'ASC'))
@classmethod
def create(cls, vlist):
tables = super().create(vlist)
for table in tables:
table.update_table_dependencies()
return tables
@classmethod
def write(cls, *args):
actions = iter(args)
for tables, values in zip(actions, actions):
if 'internal_name' not in values:
continue
for table in tables:
table._drop()
super().write(*args)
actions = iter(args)
for tables, values in zip(actions, actions):
for table in tables:
table.update_table_dependencies()
if 'internal_name' in values:
table._drop()
def delete(cls, tables):
for table in tables:
table._drop()
super().delete(tables)
def update_table_dependencies(self):
pool = Pool()
Dependency = pool.get('babi.table.dependency')
Dependency.delete(self.requires)
Dependency.delete(self.required_by)
import pdb; pdb.set_trace()
tables = {x.table_name: x for x in self.search([])}
to_save = []
required_tables = self.get_required_table_names()
for name in required_tables:
dependency = Dependency()
dependency.required_by = self
dependency.name = name
dependency.table = tables.get(name)
to_save.append(dependency)
requiredby_tables = self.get_required_by_table_names() - required_tables
for name in requiredby_tables:
dependency = Dependency()
dependency.required_by = tables.get(name)
dependency.name = self.table_name
dependency.table = self
to_save.append(dependency)
Dependency.save(to_save)
def get_required_table_names(self):
if self.type and self.type == 'model':
return set()
query = self.query or ''
tables = {x for x in query.split() if x.startswith('__')}
return tables
def get_required_by_table_names(self):
tables = self.search([
('type', 'in', ['table', 'query']),
('query', 'ilike', '%' + self.table_name + '%'),
])
res = set()
for table in tables:
if self.table_name in table.get_required_table_names():
res.add(table.table_name)
return res
def get_preview(self, name):
start = time.time()
content = None
@ -290,7 +371,14 @@ class Table(DeactivableMixin, ModelSQL, ModelView):
def timeout_exception(self):
raise TimeoutException
def _compute(self):
def _compute(self, processed=None):
if processed is None:
processed = []
if self in processed:
seq = ' > '.join([x.rec_name for x in processed] + [self.rec_name])
raise UserError(gettext('babi.msg_circular_dependency',
sequence=seq))
print('Computing %s.... ' % self.rec_name)
try:
if self.type == 'model':
if not self.fields_:
@ -307,6 +395,9 @@ class Table(DeactivableMixin, ModelSQL, ModelView):
self._compute_table()
elif self.type == 'query':
self._compute_query()
for dependency in self.required_by:
dependency.required_by._compute(processed + [self])
except Exception as e:
notify(gettext('babi.msg_table_failed', table=self.rec_name))
self.compute_error = str(e)
@ -350,6 +441,21 @@ class Table(DeactivableMixin, ModelSQL, ModelView):
else:
return ''
def _drop(self):
if backend.name == 'postgresql':
cascade = 'CASCADE'
else:
cascade = ''
cursor = Transaction().connection.cursor()
cursor.execute('SELECT * FROM information_schema.tables '
'WHERE table_name=%s', (self.table_name,))
if cursor.fetchone():
cursor.execute('DROP TABLE %s %s' % (self.table_name, cascade))
cursor.execute('SELECT * FROM information_schema.views '
'WHERE table_name=%s', (self.table_name,))
if cursor.fetchone():
cursor.execute('DROP VIEW IF EXISTS "%s" %s;' % (self.table_name, cascade))
def _compute_query(self):
with Transaction().new_transaction() as transaction:
cursor = transaction.connection.cursor()
@ -362,11 +468,7 @@ class Table(DeactivableMixin, ModelSQL, ModelView):
self.update_fields(field_names)
cursor = Transaction().connection.cursor()
if backend.name == 'postgresql':
cascade = 'CASCADE'
else:
cascade = ''
cursor.execute('DROP VIEW IF EXISTS "%s" %s;' % (self.table_name, cascade))
self._drop()
cursor.execute('CREATE VIEW "%s" AS %s' % (self.table_name, self._stripped_query))
def _compute_table(self):
@ -377,6 +479,7 @@ class Table(DeactivableMixin, ModelSQL, ModelView):
else:
cascade = ''
cursor.execute('DROP TABLE IF EXISTS "%s" %s;' % (self.table_name, cascade))
self._drop()
cursor.execute('CREATE TABLE "%s" AS %s' % (self.table_name,
self._stripped_query))
cursor.execute('SELECT * FROM "%s" LIMIT 1' % self.table_name)
@ -562,3 +665,17 @@ class Field(sequence_ordered(), ModelSQL, ModelView):
def on_change_with_model(self, name=None):
if self.table and self.table.model:
return self.table.model.id
class TableDependency(ModelSQL, ModelView):
'BABI Table Dependency'
__name__ = 'babi.table.dependency'
required_by = fields.Many2One('babi.table', 'Required By', required=True,
ondelete='CASCADE')
name = fields.Char('Name')
table = fields.Many2One('babi.table', 'Requires', ondelete='SET NULL')
@classmethod
def __setup__(cls):
super().__setup__()
cls.__access__.add('table')

View File

@ -83,5 +83,17 @@
</record>
<menuitem id="menu_babi_field" parent="menu_babi_table" action="act_babi_field" sequence="10"/>
<!-- babi.table.dependency -->
<record model="ir.ui.view" id="babi_table_dependency_form_view">
<field name="model">babi.table.dependency</field>
<field name="type">form</field>
<field name="name">table_dependency_form</field>
</record>
<record model="ir.ui.view" id="babi_table_dependency_tree_view">
<field name="model">babi.table.dependency</field>
<field name="type">tree</field>
<field name="name">table_dependency_list</field>
</record>
</data>
</tryton>

View File

@ -0,0 +1,9 @@
<form>
<label name="required_by"/>
<field name="required_by"/>
<newline/>
<label name="name"/>
<field name="name"/>
<label name="table"/>
<field name="table"/>
</form>

View File

@ -0,0 +1,5 @@
<tree>
<field name="required_by"/>
<field name="name"/>
<field name="table"/>
</tree>

View File

@ -11,14 +11,15 @@
<field name="filter"/>
<button name="compute" colspan="2"/>
<newline/>
<separator name="query" colspan="6"/>
<field name="query" colspan="6"/>
<notebook colspan="6">
<page name="query">
<field name="query" colspan="4" height="550"/>
</page>
<page name="fields_">
<field name="fields_" colspan="4"/>
<field name="fields_" colspan="4" height="550"/>
</page>
<page name="preview">
<field name="preview" colspan="4" widget="document"/>
<field name="preview" colspan="4" widget="document" height="550"/>
</page>
<page name="crons">
<field name="crons" colspan="4"/>
@ -33,6 +34,10 @@
<field name="babi_raise_user_error"/>
<label name="timeout"/>
<field name="timeout"/>
</page>
<page id="dependencies" string="Dependencies">
<field name="requires" colspan="2" height="550"/>
<field name="required_by" colspan="2" height="550"/>
</page>
</notebook>
</form>