[IMP] web, base: shorten generated property names
Purpose ======= Shorten the property name to take less space in database (while keeping a very low probability of collision). E.G.: "aa34746a6851ee4ea1f8d95746e45788" -> "aa34746a6851ee4e" Automatically generate property name in python if they are missing. Task-2965523 X-original-commit: d597083ff5e0a4abde67a450a61e04e6bf119c26 Part-of: odoo/odoo#101487
This commit is contained in:
@@ -266,12 +266,12 @@ export function toStringExpression(str) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a unique identifier.
|
||||
* Generate a unique identifier (64 bits) in hexadecimal.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
export function uuid() {
|
||||
const array = new Uint8Array(16);
|
||||
const array = new Uint8Array(8);
|
||||
window.crypto.getRandomValues(array);
|
||||
// Uint8Array to hex
|
||||
return [...array].map((b) => b.toString(16).padStart(2, "0")).join("");
|
||||
|
||||
@@ -230,18 +230,20 @@ class PropertiesCase(TransactionCase):
|
||||
}])
|
||||
self.env.invalidate_all()
|
||||
|
||||
with self.assertQueryCount(7):
|
||||
with self.assertQueryCount(8):
|
||||
messages = self.env['test_new_api.message'].create([{
|
||||
'name': 'Test Message',
|
||||
'discussion': self.discussion_1.id,
|
||||
'author': self.user.id,
|
||||
'attributes': [{
|
||||
'name': 'discussion_color_code',
|
||||
'string': 'New Label',
|
||||
# no name, should be automatically generated
|
||||
'string': 'Discussion Color code',
|
||||
'type': 'char',
|
||||
'default': 'blue',
|
||||
'value': 'purple',
|
||||
'definition_changed': True,
|
||||
}, {
|
||||
# the name is already set and shouldn't be re-generated
|
||||
'name': 'moderator_partner_id',
|
||||
'string': 'Partner',
|
||||
'type': 'many2one',
|
||||
@@ -254,7 +256,6 @@ class PropertiesCase(TransactionCase):
|
||||
'discussion': self.discussion_2.id,
|
||||
'author': self.user.id,
|
||||
'attributes': [{
|
||||
'name': 'state',
|
||||
'type': 'selection',
|
||||
'string': 'Status',
|
||||
'selection': [
|
||||
@@ -269,12 +270,18 @@ class PropertiesCase(TransactionCase):
|
||||
self.env.invalidate_all()
|
||||
|
||||
sql_definition = self._get_sql_definition(self.discussion_1)
|
||||
self.assertEqual(len(sql_definition), 2)
|
||||
|
||||
# check the generated name
|
||||
property_color_name = sql_definition[0]['name']
|
||||
self.assertTrue(property_color_name, msg="Property name must have been generated")
|
||||
|
||||
self.assertEqual(sql_definition, [
|
||||
{
|
||||
'name': 'discussion_color_code',
|
||||
'type': 'char', 'string':
|
||||
'New Label', 'default':
|
||||
'blue'
|
||||
'name': property_color_name,
|
||||
'default': 'blue',
|
||||
'string': 'Discussion Color code',
|
||||
'type': 'char',
|
||||
}, {
|
||||
'name': 'moderator_partner_id',
|
||||
'type': 'many2one',
|
||||
@@ -284,7 +291,7 @@ class PropertiesCase(TransactionCase):
|
||||
])
|
||||
|
||||
self.assertEqual(
|
||||
self.discussion_1.attributes_definition[0]['string'], 'New Label',
|
||||
self.discussion_1.attributes_definition[0]['string'], 'Discussion Color code',
|
||||
msg='Should have updated the definition record')
|
||||
|
||||
self.assertEqual(len(messages), 2)
|
||||
@@ -293,11 +300,12 @@ class PropertiesCase(TransactionCase):
|
||||
self.assertEqual(
|
||||
sql_properties_1,
|
||||
{'moderator_partner_id': self.partner.id,
|
||||
'discussion_color_code': 'purple'})
|
||||
property_color_name: 'purple'})
|
||||
sql_properties_2 = self._get_sql_properties(messages[1])
|
||||
status_name = self.discussion_2.attributes_definition[0]['name']
|
||||
self.assertEqual(
|
||||
sql_properties_2,
|
||||
{'state': 'draft'})
|
||||
{status_name: 'draft'})
|
||||
|
||||
properties_values_1 = messages[0].attributes
|
||||
properties_values_2 = messages[1].attributes
|
||||
|
||||
+28
-12
@@ -16,6 +16,7 @@ import enum
|
||||
import itertools
|
||||
import json
|
||||
import logging
|
||||
import uuid
|
||||
import warnings
|
||||
|
||||
from markupsafe import Markup
|
||||
@@ -3198,8 +3199,8 @@ class Properties(Field):
|
||||
# names to their corresponding value, like
|
||||
#
|
||||
# {
|
||||
# '3adf37f3258cfe40f0907d9cbdd7d091': 'red',
|
||||
# 'aa34746a6851ee4ea1f8d95746e45788': 1337,
|
||||
# '3adf37f3258cfe40': 'red',
|
||||
# 'aa34746a6851ee4e': 1337,
|
||||
# }
|
||||
#
|
||||
def convert_to_column(self, value, record, values=None, validate=True):
|
||||
@@ -3254,13 +3255,13 @@ class Properties(Field):
|
||||
# corresponding value, like
|
||||
#
|
||||
# [{
|
||||
# 'name': '3adf37f3258cfe40f0907d9cbdd7d091',
|
||||
# 'name': '3adf37f3258cfe40',
|
||||
# 'string': 'Color Code',
|
||||
# 'type': 'char',
|
||||
# 'default': 'blue',
|
||||
# 'value': 'red',
|
||||
# }, {
|
||||
# 'name': 'aa34746a6851ee4ea1f8d95746e45788',
|
||||
# 'name': 'aa34746a6851ee4e',
|
||||
# 'string': 'Partner',
|
||||
# 'type': 'many2one',
|
||||
# 'comodel': 'test_new_api.partner',
|
||||
@@ -3283,13 +3284,13 @@ class Properties(Field):
|
||||
# field values have a display name.
|
||||
#
|
||||
# [{
|
||||
# 'name': '3adf37f3258cfe40f0907d9cbdd7d091',
|
||||
# 'name': '3adf37f3258cfe40',
|
||||
# 'string': 'Color Code',
|
||||
# 'type': 'char',
|
||||
# 'default': 'blue',
|
||||
# 'value': 'red',
|
||||
# }, {
|
||||
# 'name': 'aa34746a6851ee4ea1f8d95746e45788',
|
||||
# 'name': 'aa34746a6851ee4e',
|
||||
# 'string': 'Partner',
|
||||
# 'type': 'many2one',
|
||||
# 'comodel': 'test_new_api.partner',
|
||||
@@ -3493,6 +3494,19 @@ class Properties(Field):
|
||||
for many2many_value in property_value
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def _add_missing_names(cls, values_list):
|
||||
"""Generate new properties name if needed.
|
||||
|
||||
Modify in place "values_list".
|
||||
|
||||
:param values_list: List of properties definition with properties value
|
||||
"""
|
||||
for definition in values_list:
|
||||
if definition.get('definition_changed') and not definition.get('name'):
|
||||
# keep only the first 64 bits
|
||||
definition['name'] = str(uuid.uuid4()).replace('-', '')[:16]
|
||||
|
||||
@classmethod
|
||||
def _parse_json_types(cls, values_list, env, check_existence=True):
|
||||
"""Parse the value stored in the JSON.
|
||||
@@ -3563,13 +3577,13 @@ class Properties(Field):
|
||||
E.G.
|
||||
Input list:
|
||||
[{
|
||||
'name': '3adf37f3258cfe40f0907d9cbdd7d091',
|
||||
'name': '3adf37f3258cfe40',
|
||||
'string': 'Color Code',
|
||||
'type': 'char',
|
||||
'default': 'blue',
|
||||
'value': 'red',
|
||||
}, {
|
||||
'name': 'aa34746a6851ee4ea1f8d95746e45788',
|
||||
'name': 'aa34746a6851ee4e',
|
||||
'string': 'Partner',
|
||||
'type': 'many2one',
|
||||
'comodel': 'test_new_api.partner',
|
||||
@@ -3578,8 +3592,8 @@ class Properties(Field):
|
||||
|
||||
Output dict:
|
||||
{
|
||||
'3adf37f3258cfe40f0907d9cbdd7d091': 'red',
|
||||
'aa34746a6851ee4ea1f8d95746e45788': 1337,
|
||||
'3adf37f3258cfe40': 'red',
|
||||
'aa34746a6851ee4e': 1337,
|
||||
}
|
||||
|
||||
:param values_list: List of properties definition and value
|
||||
@@ -3588,6 +3602,8 @@ class Properties(Field):
|
||||
if not is_list_of(values_list, dict):
|
||||
raise ValueError(f'Wrong properties value {values_list!r}')
|
||||
|
||||
cls._add_missing_names(values_list)
|
||||
|
||||
dict_value = {}
|
||||
for property_definition in values_list:
|
||||
property_value = property_definition.get('value')
|
||||
@@ -3650,13 +3666,13 @@ class PropertiesDefinition(Field):
|
||||
might contain the name_get of those records (and will be removed).
|
||||
|
||||
[{
|
||||
'name': '3adf37f3258cfe40f0907d9cbdd7d091',
|
||||
'name': '3adf37f3258cfe40',
|
||||
'string': 'Color Code',
|
||||
'type': 'char',
|
||||
'default': 'blue',
|
||||
'default': 'red',
|
||||
}, {
|
||||
'name': 'aa34746a6851ee4ea1f8d95746e45788',
|
||||
'name': 'aa34746a6851ee4e',
|
||||
'string': 'Partner',
|
||||
'type': 'many2one',
|
||||
'comodel': 'test_new_api.partner',
|
||||
|
||||
Reference in New Issue
Block a user