diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index 8d47a075ba..c8d1bb18b4 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -166,7 +166,6 @@ class CustomizeForm(Document): self.flags.update_db = False self.flags.rebuild_doctype_for_global_search = False - self.set_property_setters() self.update_custom_fields() self.set_name_translation() @@ -362,13 +361,45 @@ class CustomizeForm(Document): def validate_fieldtype_change(self, df, old_value, new_value): allowed = False + self.check_length_for_fieldtypes = [] for allowed_changes in allowed_fieldtype_change: if (old_value in allowed_changes and new_value in allowed_changes): allowed = True + if frappe.db.type_map.get(old_value)[1] > frappe.db.type_map.get(new_value)[1]: + self.check_length_for_fieldtypes.append({'df': df, 'old_value': old_value}) + self.validate_fieldtype_length() + else: + self.flags.update_db = True break if not allowed: frappe.throw(_("Fieldtype cannot be changed from {0} to {1} in row {2}").format(old_value, new_value, df.idx)) + def validate_fieldtype_length(self): + for field in self.check_length_for_fieldtypes: + df = field.get('df') + max_length = frappe.db.type_map.get(df.fieldtype)[1] + fieldname = df.fieldname + docs = frappe.db.sql(''' + SELECT name, {fieldname}, LENGTH({fieldname}) AS len + FROM `tab{doctype}` + WHERE LENGTH({fieldname}) > {max_length} + '''.format( + fieldname = fieldname, + doctype = self.doc_type, + max_length = max_length + ), as_dict = True) + links = [] + label = df.label + for doc in docs: + links.append(frappe.utils.get_link_to_form(self.doc_type, doc.name)) + links_str = ', '.join(links) + + if docs: + frappe.throw(_('Value for field {0} is too long in {1}. Length should be lesser than {2} characters') + .format(frappe.bold(label), links_str, frappe.bold(max_length)), title=_('Data Too Long'), is_minimizable=len(docs) > 1) + + self.flags.update_db = True + def reset_to_defaults(self): if not self.doc_type: return diff --git a/frappe/database/mariadb/database.py b/frappe/database/mariadb/database.py index cd053569f0..926425f857 100644 --- a/frappe/database/mariadb/database.py +++ b/frappe/database/mariadb/database.py @@ -33,7 +33,7 @@ class MariaDBDatabase(Database): 'Float': ('decimal', '18,6'), 'Percent': ('decimal', '18,6'), 'Check': ('int', '1'), - 'Small Text': ('text', ''), + 'Small Text': ('text', 65535), 'Long Text': ('longtext', ''), 'Code': ('longtext', ''), 'Text Editor': ('longtext', ''), @@ -42,7 +42,7 @@ class MariaDBDatabase(Database): 'Date': ('date', ''), 'Datetime': ('datetime', '6'), 'Time': ('time', '6'), - 'Text': ('text', ''), + 'Text': ('text', 65535), 'Data': ('varchar', self.VARCHAR_LEN), 'Link': ('varchar', self.VARCHAR_LEN), 'Dynamic Link': ('varchar', self.VARCHAR_LEN), diff --git a/frappe/database/schema.py b/frappe/database/schema.py index 88cda9340b..73bdf32761 100644 --- a/frappe/database/schema.py +++ b/frappe/database/schema.py @@ -69,6 +69,7 @@ class DBTable: lengths = {} precisions = {} uniques = {} + fieldtype = '' # optional fields like _comments if not self.meta.istable: @@ -100,7 +101,7 @@ class DBTable: filters={ "doc_type": self.doctype, "doctype_or_field": "DocField", - "property": ["in", ["precision", "length", "unique"]] + "property": ["in", ["precision", "length", "unique", "fieldtype"]] }): if ps.property=="length": @@ -112,10 +113,13 @@ class DBTable: elif ps.property=="unique": uniques[ps.field_name] = cint(ps.value) + if ps.property=="fieldtype": + fieldtype = ps.value + for f in fl: self.columns[f['fieldname']] = DbColumn(self, f['fieldname'], - f['fieldtype'], + fieldtype or f['fieldtype'], lengths.get(f["fieldname"]) or f.get('length'), f.get('default'), f.get('search_index'),