Validate on max length of string field type
This blueprint aims to add a max_length validation to the `nova.objects.fields.String` class. Change-Id: I1ed8f0804996af86c7eadc83914d81df1ab4a88d Blueprint: string-field-max-length
This commit is contained in:
174
specs/juno/string-field-max-length.rst
Normal file
174
specs/juno/string-field-max-length.rst
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
..
|
||||||
|
This work is licensed under a Creative Commons Attribution 3.0 Unported
|
||||||
|
License.
|
||||||
|
|
||||||
|
http://creativecommons.org/licenses/by/3.0/legalcode
|
||||||
|
|
||||||
|
=======================================
|
||||||
|
Allow StringField to enforce max length
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
https://blueprints.launchpad.net/nova/+spec/string-field-max-length
|
||||||
|
|
||||||
|
This blueprint aims to add a max length constraint to the
|
||||||
|
`nova.objects.fields.StringField` class.
|
||||||
|
|
||||||
|
Problem description
|
||||||
|
===================
|
||||||
|
|
||||||
|
Currently, the nova object framework revolves around the use of field type
|
||||||
|
classes that describe the schema of an object. Each object model is simply
|
||||||
|
a collection of fields, each of which have a particular type, such as
|
||||||
|
IntegerField or StringField.
|
||||||
|
|
||||||
|
In much the same way that a SQL database schema describes the constraints
|
||||||
|
that a given column in a table must adhere to -- e.g. the length of characters
|
||||||
|
possible in a CHAR field, or a valid DATETIME string -- the nova objects
|
||||||
|
should be self-validating.
|
||||||
|
|
||||||
|
Proposed change
|
||||||
|
===============
|
||||||
|
|
||||||
|
This specification proposes to change the `coerce` method of the
|
||||||
|
`String` class to validate on the number of characters in the
|
||||||
|
field's string value.
|
||||||
|
|
||||||
|
The `StringField` concrete field class shall have a new `max_length` kwarg
|
||||||
|
added to its constructor that will control the validation. The default
|
||||||
|
value will be None, and no `StringField` objects defined in the schemas of
|
||||||
|
any of the nova object models shall be changed in this spec.
|
||||||
|
|
||||||
|
Alternatives
|
||||||
|
------------
|
||||||
|
|
||||||
|
None (keep things the way they are now)
|
||||||
|
|
||||||
|
Data model impact
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
None (the existing models themselves won't be changed in this specification
|
||||||
|
at all)
|
||||||
|
|
||||||
|
REST API impact
|
||||||
|
---------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Security impact
|
||||||
|
---------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Notifications impact
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Other end user impact
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Performance Impact
|
||||||
|
------------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Other deployer impact
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Developer impact
|
||||||
|
----------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Implementation
|
||||||
|
==============
|
||||||
|
|
||||||
|
Roughly, the code the `String` field type class would change from this:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
class String(FieldType):
|
||||||
|
@staticmethod
|
||||||
|
def coerce(obj, attr, value):
|
||||||
|
# FIXME(danms): We should really try to avoid the need to do this
|
||||||
|
if isinstance(value, (six.string_types, int, long, float,
|
||||||
|
datetime.datetime)):
|
||||||
|
return unicode(value)
|
||||||
|
else:
|
||||||
|
raise ValueError(_('A string is required here, not %s') %
|
||||||
|
value.__class__.__name__)
|
||||||
|
|
||||||
|
to this:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
class String(FieldType):
|
||||||
|
|
||||||
|
def __init__(self, max_length=None):
|
||||||
|
"""
|
||||||
|
:param max_length: Optional constraint on the number of Unicode
|
||||||
|
characters the string value can be.
|
||||||
|
"""
|
||||||
|
self._max_length = max_length
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def coerce(self, obj, attr, value):
|
||||||
|
# FIXME(danms): We should really try to avoid the need to do this
|
||||||
|
if isinstance(value, (six.string_types, int, long, float,
|
||||||
|
datetime.datetime)):
|
||||||
|
result = unicode(value)
|
||||||
|
else:
|
||||||
|
raise ValueError(_('A string is required here, not %s') %
|
||||||
|
value.__class__.__name__)
|
||||||
|
if self._max_length is not None:
|
||||||
|
if len(value) > self._max_length):
|
||||||
|
msg = _("String %(result)s is longer than maximum allowed "
|
||||||
|
"length of %(max_length)d.")
|
||||||
|
msg = msg % dict(result=result,
|
||||||
|
max_length=self._max_length)
|
||||||
|
raise ValueError(msg)
|
||||||
|
return result
|
||||||
|
|
||||||
|
The StringField class would then need to be modified to allow passing the
|
||||||
|
max_length parameter along to its type class.
|
||||||
|
|
||||||
|
Work Items
|
||||||
|
----------
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
Assignee(s)
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Primary assignee:
|
||||||
|
jaypipes
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
============
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Testing
|
||||||
|
=======
|
||||||
|
|
||||||
|
Would need new unit tests. No need for any integration test changes.
|
||||||
|
|
||||||
|
Documentation Impact
|
||||||
|
====================
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
References
|
||||||
|
==========
|
||||||
|
|
||||||
|
The server-instance-tagging work will likely be the first work to use
|
||||||
|
this functionality, as the tag string has a max length associated with
|
||||||
|
it and we need to be very careful about changing existing model fields' string
|
||||||
|
length validation code, so a new field like the tag field is an ideal place to
|
||||||
|
begin with this implementation.
|
||||||
|
|
||||||
|
http://git.openstack.org/cgit/openstack/nova-specs/tree/specs/juno/tag-instances.rst
|
||||||
Reference in New Issue
Block a user