From c775f7c1fe5eee513de15760059908091622bc13 Mon Sep 17 00:00:00 2001 From: Hamatoma Date: Thu, 29 Oct 2020 19:25:29 +0100 Subject: [PATCH] daily work: role+user+config work --- data/ddl/configuration.sql | 2 +- data/rest/configuration.yaml | 9 ++-- data/rest/role.yaml | 4 +- data/rest/user.yaml | 7 ++-- lib/app.dart | 4 +- lib/src/model/column_model.dart | 42 ++++++++++++------- lib/src/model/db_reference_model.dart | 28 ++++++------- lib/src/model/field_model.dart | 6 ++- lib/src/model/model_base.dart | 12 +++++- lib/src/model/module_model.dart | 21 +++++++++- .../model/standard/configuration_model.dart | 2 +- lib/src/model/standard/user_model.dart | 2 +- .../configuration_change_page.dart | 12 +++--- lib/src/widget/filter_set.dart | 24 +++++++---- lib/src/widget/view.dart | 3 +- 15 files changed, 114 insertions(+), 64 deletions(-) diff --git a/data/ddl/configuration.sql b/data/ddl/configuration.sql index dd4958d..25b196a 100644 --- a/data/ddl/configuration.sql +++ b/data/ddl/configuration.sql @@ -1,7 +1,7 @@ DROP TABLE IF EXISTS configuration; CREATE TABLE configuration ( configuration_id INT(10) UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT, - configuration_scope VARCHAR(64) UNIQUE NOT NULL, + configuration_scope VARCHAR(64) NOT NULL, configuration_property VARCHAR(64), configuration_order INT(10), configuration_type VARCHAR(16), diff --git a/data/rest/configuration.yaml b/data/rest/configuration.yaml index 33b419a..98f5ae0 100644 --- a/data/rest/configuration.yaml +++ b/data/rest/configuration.yaml @@ -1,6 +1,6 @@ --- # configuration of the bones backend for configuration: -created: 2020.10.20 23:16:54 +created: 2020.10.29 22:35:03 author: flutter_bones.module_model.exportSqlBackend() version: 1.0.0 modules: @@ -21,10 +21,7 @@ modules: - name: record type: record sql: "SELECT * from configuration WHERE configuration_id=:configuration_id;" - - name: by_configuration_scope - type: record - sql: "SELECT * from configuration WHERE configuration_scope=:configuration_scope&&configuration_id!=:excluded;" - name: list type: list - sql: "SELECT * from configuration - WHERE configuration_property like :configuration_property AND configuration_scope like :configuration_scope;" + sql: "SELECT t0.* from configuration t0 + WHERE configuration_scope like :configuration_scope AND configuration_property like :configuration_property;" diff --git a/data/rest/role.yaml b/data/rest/role.yaml index 25b3215..c621943 100644 --- a/data/rest/role.yaml +++ b/data/rest/role.yaml @@ -1,6 +1,6 @@ --- # configuration of the bones backend for role: -created: 2020.10.20 23:16:54 +created: 2020.10.29 22:35:03 author: flutter_bones.module_model.exportSqlBackend() version: 1.0.0 modules: @@ -26,5 +26,5 @@ modules: sql: "SELECT * from role WHERE role_name=:role_name&&role_id!=:excluded;" - name: list type: list - sql: "SELECT * from role + sql: "SELECT t0.* from role t0 WHERE role_name like :role_name;" diff --git a/data/rest/user.yaml b/data/rest/user.yaml index ab0ff4a..c85fad9 100644 --- a/data/rest/user.yaml +++ b/data/rest/user.yaml @@ -1,6 +1,6 @@ --- # configuration of the bones backend for user: -created: 2020.10.20 23:16:54 +created: 2020.10.29 22:35:03 author: flutter_bones.module_model.exportSqlBackend() version: 1.0.0 modules: @@ -32,5 +32,6 @@ modules: sql: "SELECT * from user WHERE user_email=:user_email&&user_id!=:excluded;" - name: list type: list - sql: "SELECT * from user - WHERE user_name like :user_name AND (:user_role is null or user_role=:user_role);" + sql: "SELECT t0.*,t1.role_name as user_role from user t0 + left join role t1 on t1.role_id=t0.user_role + WHERE user_name like :user_name AND (:user_role IS NULL OR t0.user_role=:user_role);" diff --git a/lib/app.dart b/lib/app.dart index 1fe35e1..ba74153 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -8,6 +8,8 @@ import 'src/page/role/role_create_page.dart'; import 'src/page/role/role_list_page.dart'; import 'src/page/user/user_create_page.dart'; import 'src/page/user/user_list_page.dart'; +import 'src/page/configuration/configuration_create_page.dart'; +import 'src/page/configuration/configuration_list_page.dart'; import 'src/private/bsettings.dart'; class BoneApp extends StatefulWidget { @@ -60,14 +62,12 @@ Route _getRoute(RouteSettings settings) { case '/user/create': page = UserCreatePage(BSettings.lastInstance.pageData); break; - /* case '/configuration/list': page = ConfigurationListPage(BSettings.lastInstance.pageData); break; case '/configuration/create': page = ConfigurationCreatePage(BSettings.lastInstance.pageData); break; - */ default: page = LoginPage(BSettings.lastInstance.pageData); break; diff --git a/lib/src/model/column_model.dart b/lib/src/model/column_model.dart index 0a119fb..7ab3ba8 100644 --- a/lib/src/model/column_model.dart +++ b/lib/src/model/column_model.dart @@ -13,14 +13,14 @@ class ColumnModel extends ComboBaseModel { r'^(undef|readonly|disabled|doStore|hidden|null|notnull|password|primary|required|unique)$'); static final regExprListDbOption = RegExp(r'^\w+\.\w+;\w+ \w+(?:;(:? ?:\w+=[^ ]*?)+)?$'); + static final regExprForeignKey = RegExp(r'^\w+\.\w+ \w+$'); int size; int rows; final TableModel table; - final Map map; String foreignKey; /// A constructor used in the parser. - ColumnModel(this.table, this.map, BaseLogger logger) + ColumnModel(this.table, Map map, BaseLogger logger) : super(null, null, map, WidgetModelType.column, logger); /// A constructor for columns created by the program. @@ -30,19 +30,28 @@ class ColumnModel extends ComboBaseModel { @required String label, @required DataType dataType, @required List options, - String toolTip, - String listOption, - ComboboxListType listType, + String toolTip, + String listOption, + ComboboxListType listType, this.size, - this.map, - List texts, - List values, + List texts, + List values, BaseLogger logger}) - : super.direct(section: null, page: null, - map: null, - name: name, label: label, toolTip: toolTip, texts: texts, values: values, - listOption: listOption, listType: listType, options: options, - widgetType: WidgetModelType.column, logger: logger); + : super.direct( + section: null, + page: null, + map: null, + name: name, + label: label, + toolTip: toolTip, + texts: texts, + dataType: dataType, + values: values, + listOption: listOption, + listType: listType, + options: options, + widgetType: WidgetModelType.column, + logger: logger); /// Dumps the instance into a [StringBuffer] StringBuffer dump(StringBuffer stringBuffer) { @@ -73,7 +82,12 @@ class ColumnModel extends ComboBaseModel { parseEnum('dataType', map, DataType.values, required: true); size = parseInt('size', map, required: dataType == DataType.string); rows = parseInt('rows', map); - + foreignKey = parseString('foreignKey', map); + if (foreignKey != null && + regExprForeignKey.firstMatch(foreignKey) == null) { + logger.error( + 'invalid foreign key: $foreignKey expected: ". " e.g. "role.role_id role_name"'); + } checkOptionsByRegExpr(options, regExprOptions); if (options.contains('primary')) { if (!options.contains('notnull')) { diff --git a/lib/src/model/db_reference_model.dart b/lib/src/model/db_reference_model.dart index bfa3a36..d138346 100644 --- a/lib/src/model/db_reference_model.dart +++ b/lib/src/model/db_reference_model.dart @@ -24,20 +24,20 @@ class DbReferenceModel extends ComboBaseModel { DbReferenceModel.fromColumn(SectionModel section, PageModel page, ColumnModel column, BaseLogger logger) : super.direct( - section: section, - page: page, - map: null, - widgetType: WidgetModelType.dbReference, - name: column.name, - label: column.label, - toolTip: column.toolTip, - dataType: column.dataType, - options: column.options = [], - texts: column.texts, - values: column.values, - listOption: column.listOption, - listType: column.listType, - logger: logger) { + section: section, + page: page, + map: null, + widgetType: WidgetModelType.dbReference, + name: column.name, + label: column.label, + toolTip: column.toolTip, + dataType: column.dataType, + options: column.options ?? [], + texts: column.texts, + values: column.values, + listOption: column.listOption, + listType: column.listType, + logger: logger) { this.column = column; maxSize = column.size; rows = column.rows; diff --git a/lib/src/model/field_model.dart b/lib/src/model/field_model.dart index 36ff059..66a7bb2 100644 --- a/lib/src/model/field_model.dart +++ b/lib/src/model/field_model.dart @@ -61,7 +61,7 @@ abstract class FieldModel extends WidgetModel { /// Tests whether a given [option] is part of [options]. bool hasOption(String option) { - if (options == null){ + if (options == null) { return false; } bool rc = options.contains(option); @@ -70,7 +70,9 @@ abstract class FieldModel extends WidgetModel { /// Parses the map and stores the data in the instance. void parse() { - name = parseString(widgetModelType == WidgetModelType.column ? 'column' : 'name', map, required: true); + name = parseString( + widgetModelType == WidgetModelType.column ? 'column' : 'name', map, + required: true); label = parseString('label', map, required: false); toolTip = parseString('toolTip', map, required: false); filterType = parseEnum('filterType', map, FilterType.values); diff --git a/lib/src/model/model_base.dart b/lib/src/model/model_base.dart index d70cc28..7756b60 100644 --- a/lib/src/model/model_base.dart +++ b/lib/src/model/model_base.dart @@ -1,6 +1,6 @@ import 'package:dart_bones/dart_bones.dart'; import 'package:meta/meta.dart'; - +import '../helper/string_helper.dart'; import 'model_types.dart'; /// Base class of all models. @@ -172,6 +172,16 @@ abstract class ModelBase { case DataType.reference: rc2 = StringUtils.asInt(item); break; + case DataType.bool: + case DataType.currency: + case DataType.date: + case DataType.dateTime: + case DataType.float: + rc2 = StringHelper.fromString(item, dataType); + break; + case DataType.string: + rc2 = item; + break; default: logger.error('unknown dataType in parseValueList()'); rc2 = item; diff --git a/lib/src/model/module_model.dart b/lib/src/model/module_model.dart index b8dde9c..3bfd13e 100644 --- a/lib/src/model/module_model.dart +++ b/lib/src/model/module_model.dart @@ -96,9 +96,25 @@ class ModuleModel extends ModelBase { (element) => element.pageModelType == PageModelType.list, orElse: () => null); if (page != null) { + final buffer2 = StringBuffer(); + var select = 't0.*'; + var no = 0; + table.columns.forEach((column) { + if (column.foreignKey != null && column.foreignKey.isNotEmpty) { + no++; + final foreignName = column.foreignKey.split(' '); + final colName = foreignName[1]; + final tableColumn = foreignName[0].split('.'); + final table2 = tableColumn[0]; + final col2 = tableColumn[1]; + select += ',t$no.$colName as ${column.name}'; + buffer2.write( + ' left join $table2 t$no on t$no.$col2=t0.${column.name}\n'); + } + }); buffer.write(''' - name: list type: list - sql: "SELECT * from ${table.name}\n'''); + sql: "SELECT $select from ${table.name} t0\n$buffer2'''); // @ToDo: joins final fields = page.fields .where((item) => item is FieldModel && item.filterType != null); @@ -121,7 +137,8 @@ class ModuleModel extends ModelBase { buffer.write('${field.name}<=:${field.name}'); break; case FilterType.equals: - buffer.write('${field.name} like :${field.name}'); + buffer.write( + '(:${field.name} IS NULL OR ${field.name}=:${field.name})'); break; case FilterType.pattern: buffer.write('${field.name} like :${field.name}'); diff --git a/lib/src/model/standard/configuration_model.dart b/lib/src/model/standard/configuration_model.dart index 16abd36..4958f09 100644 --- a/lib/src/model/standard/configuration_model.dart +++ b/lib/src/model/standard/configuration_model.dart @@ -24,7 +24,7 @@ class ConfigurationModel extends ModuleModel { 'dataType': 'string', 'label': 'Bereich', 'size': 64, - 'options': 'unique notnull', + 'options': 'notnull', }, { 'column': 'configuration_property', diff --git a/lib/src/model/standard/user_model.dart b/lib/src/model/standard/user_model.dart index 4809366..097e2a0 100644 --- a/lib/src/model/standard/user_model.dart +++ b/lib/src/model/standard/user_model.dart @@ -47,7 +47,7 @@ class UserModel extends ModuleModel { 'column': 'user_role', 'dataType': 'reference', 'label': 'Role', - 'foreignKey': 'role.role_id', + 'foreignKey': 'role.role_id role_name', 'listType': 'explicite', 'texts': ';-;Administrator;Benutzer;Gast;Verwalter', 'values': ';;1;2;3;4', diff --git a/lib/src/page/configuration/configuration_change_page.dart b/lib/src/page/configuration/configuration_change_page.dart index 2b35b87..a711d8c 100644 --- a/lib/src/page/configuration/configuration_change_page.dart +++ b/lib/src/page/configuration/configuration_change_page.dart @@ -32,21 +32,21 @@ class ConfigurationChangePageState extends State { final int primaryId; final Map initialRow; final GlobalKey _formKey = - GlobalKey(debugLabel: 'configuration_change'); + GlobalKey(debugLabel: 'configuration_change'); ConfigurationController controller; - ConfigurationChangePageState(this.primaryId, this.applicationData, - this.initialRow); + ConfigurationChangePageState( + this.primaryId, this.applicationData, this.initialRow); @override Widget build(BuildContext context) { if (controller == null) { controller = ConfigurationController( _formKey, this, 'change', context, applicationData, redrawCallback: - (RedrawReason reason, - {String customString, - RedrawCallbackFunctionSimple callback}) { + (RedrawReason reason, + {String customString, + RedrawCallbackFunctionSimple callback}) { switch (reason) { case RedrawReason.callback: callback(RedrawReason.custom, customString); diff --git a/lib/src/widget/filter_set.dart b/lib/src/widget/filter_set.dart index 34a70f9..55851f4 100644 --- a/lib/src/widget/filter_set.dart +++ b/lib/src/widget/filter_set.dart @@ -1,6 +1,8 @@ import 'package:dart_bones/dart_bones.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bones/flutter_bones.dart'; +import 'package:flutter_bones/src/model/combo_base_model.dart'; +import 'package:flutter_bones/src/widget/dropdown_button_form_bone.dart'; import 'package:flutter_bones/src/widget/page_controller_bones.dart'; import 'text_form_field_bone.dart'; @@ -79,15 +81,21 @@ class FilterSet { /// Returns a list of widgets for the filter fields. List getWidgets() { final rc = filters.map((filter) { - Widget rc = TextFormFieldBone( - filter.name, - pageController, - decoration: InputDecoration(labelText: filter.label), - ); - if (filter.toolTip != null) { - rc = Tooltip(message: filter.toolTip, child: rc); + final model = pageController.page.fieldByName(filter.name); + if (model is ComboBaseModel) { + Widget rc3 = View().combobox(model, pageController, null); + return rc3; + } else { + Widget rc2 = TextFormFieldBone( + filter.name, + pageController, + decoration: InputDecoration(labelText: filter.label), + ); + if (filter.toolTip != null) { + rc2 = Tooltip(message: filter.toolTip, child: rc2); + } + return rc2; } - return rc; }).toList(); return rc; } diff --git a/lib/src/widget/view.dart b/lib/src/widget/view.dart index 688fe5e..aad66b2 100644 --- a/lib/src/widget/view.dart +++ b/lib/src/widget/view.dart @@ -99,7 +99,8 @@ class View { dynamic initialValue) { var rc; if (model.dataType == DataType.bool) { - rc = checkbox(model, controller, StringHelper.fromString(initialValue, DataType.bool)); + rc = checkbox(model, controller, + StringHelper.fromString(initialValue, DataType.bool)); } else if (model.listType != null) { rc = combobox(model, controller, initialValue); } else { -- 2.39.5