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:
parent
88c4f0be4a
commit
e3ef937f93
|
@ -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
|
Loading…
Reference in New Issue