Ticket #2417: patch_8020.2.txt

File patch_8020.2.txt, 8.3 KB (added by alex@…, 16 years ago)

latest version of the patch (with tests), fixed up to 8020 with some improvements

Line 
1Index: django/db/models/fields/__init__.py
2===================================================================
3--- django/db/models/fields/__init__.py (revision 8020)
4+++ django/db/models/fields/__init__.py (working copy)
5@@ -518,6 +518,25 @@
6 defaults.update(kwargs)
7 return super(CharField, self).formfield(**defaults)
8
9+class BinaryField(Field):
10+ """Sometimes we have fields that need to store a small amount of binary
11+ data. This is different then a varchar on postgresql at least because it
12+ will not allow fields that are just nul bytes.
13+ """
14+
15+ def get_internal_type(self):
16+ return "BinaryField"
17+
18+
19+class BlobField(Field):
20+ """Sometimes we have fields that need to store a large amounts of binary
21+ data.
22+ """
23+
24+ def get_internal_type(self):
25+ return "BlobField"
26+
27+
28 # TODO: Maybe move this into contrib, because it's specialized.
29 class CommaSeparatedIntegerField(CharField):
30 def get_manipulator_field_objs(self):
31Index: django/db/backends/postgresql/introspection.py
32===================================================================
33--- django/db/backends/postgresql/introspection.py (revision 8020)
34+++ django/db/backends/postgresql/introspection.py (working copy)
35@@ -71,6 +71,7 @@
36 # Maps type codes to Django Field types.
37 DATA_TYPES_REVERSE = {
38 16: 'BooleanField',
39+ 17: 'BlobField',
40 21: 'SmallIntegerField',
41 23: 'IntegerField',
42 25: 'TextField',
43Index: django/db/backends/postgresql/creation.py
44===================================================================
45--- django/db/backends/postgresql/creation.py (revision 8020)
46+++ django/db/backends/postgresql/creation.py (working copy)
47@@ -4,6 +4,8 @@
48 # If a column type is set to None, it won't be included in the output.
49 DATA_TYPES = {
50 'AutoField': 'serial',
51+ 'BinaryField': 'bytea',
52+ 'BlobField': 'bytea',
53 'BooleanField': 'boolean',
54 'CharField': 'varchar(%(max_length)s)',
55 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
56Index: django/db/backends/sqlite3/creation.py
57===================================================================
58--- django/db/backends/sqlite3/creation.py (revision 8020)
59+++ django/db/backends/sqlite3/creation.py (working copy)
60@@ -3,6 +3,8 @@
61 # schema inspection is more useful.
62 DATA_TYPES = {
63 'AutoField': 'integer',
64+ 'BinaryField': 'BLOB',
65+ 'BlobField': 'BLOB',
66 'BooleanField': 'bool',
67 'CharField': 'varchar(%(max_length)s)',
68 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
69Index: django/db/backends/mysql/base.py
70===================================================================
71--- django/db/backends/mysql/base.py (revision 8020)
72+++ django/db/backends/mysql/base.py (working copy)
73@@ -44,6 +44,10 @@
74 FIELD_TYPE.TIME: util.typecast_time,
75 FIELD_TYPE.DECIMAL: util.typecast_decimal,
76 FIELD_TYPE.NEWDECIMAL: util.typecast_decimal,
77+ FIELD_TYPE.TINY_BLOB: buffer,
78+ FIELD_TYPE.MEDIUM_BLOB: buffer,
79+ FIELD_TYPE.LONG_BLOB: buffer,
80+ FIELD_TYPE.BLOB: buffer,
81 })
82
83 # This should match the numerical portion of the version numbers (we can treat
84Index: django/db/backends/mysql/introspection.py
85===================================================================
86--- django/db/backends/mysql/introspection.py (revision 8020)
87+++ django/db/backends/mysql/introspection.py (working copy)
88@@ -75,7 +75,10 @@
89 return indexes
90
91 DATA_TYPES_REVERSE = {
92- FIELD_TYPE.BLOB: 'TextField',
93+ FIELD_TYPE.BLOB: 'BlobField',
94+ FIELD_TYPE.LONG_BLOB: 'BlobField',
95+ FIELD_TYPE.TINY_BLOB: 'BlobField',
96+ FIELD_TYPE.MEDIUM_BLOB: 'BlobField',
97 FIELD_TYPE.CHAR: 'CharField',
98 FIELD_TYPE.DECIMAL: 'DecimalField',
99 FIELD_TYPE.DATE: 'DateField',
100Index: django/db/backends/mysql/creation.py
101===================================================================
102--- django/db/backends/mysql/creation.py (revision 8020)
103+++ django/db/backends/mysql/creation.py (working copy)
104@@ -4,6 +4,8 @@
105 # If a column type is set to None, it won't be included in the output.
106 DATA_TYPES = {
107 'AutoField': 'integer AUTO_INCREMENT',
108+ 'BinaryField': 'varbinary(%(max_length)s)',
109+ 'BlobField': 'blob',
110 'BooleanField': 'bool',
111 'CharField': 'varchar(%(max_length)s)',
112 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
113Index: django/db/backends/__init__.py
114===================================================================
115--- django/db/backends/__init__.py (revision 8020)
116+++ django/db/backends/__init__.py (working copy)
117@@ -143,8 +143,11 @@
118 """
119 from django.utils.encoding import smart_unicode, force_unicode
120
121- # Convert params to contain Unicode values.
122- to_unicode = lambda s: force_unicode(s, strings_only=True)
123+ def to_unicode(s):
124+ if isinstance(s,buffer):
125+ return u'<binary data buffer size %d>' % len(s)
126+ return force_unicode(s, strings_only=True)
127+
128 if isinstance(params, (list, tuple)):
129 u_params = tuple([to_unicode(val) for val in params])
130 else:
131Index: django/db/backends/postgresql_psycopg2/introspection.py
132===================================================================
133--- django/db/backends/postgresql_psycopg2/introspection.py (revision 8020)
134+++ django/db/backends/postgresql_psycopg2/introspection.py (working copy)
135@@ -68,6 +68,7 @@
136 # Maps type codes to Django Field types.
137 DATA_TYPES_REVERSE = {
138 16: 'BooleanField',
139+ 17: 'BlobField',
140 21: 'SmallIntegerField',
141 23: 'IntegerField',
142 25: 'TextField',
143Index: tests/modeltests/binary/__init__.py
144===================================================================
145Index: tests/modeltests/binary/tests.py
146===================================================================
147--- tests/modeltests/binary/tests.py (revision 0)
148+++ tests/modeltests/binary/tests.py (revision 0)
149@@ -0,0 +1,67 @@
150+#!/usr/bin/python
151+# encoding: utf-8
152+
153+from models import Document, BinaryFieldTest
154+
155+import unittest
156+
157+
158+class BlobFieldTests( unittest.TestCase ):
159+
160+ def test_blob(self):
161+ test_title = u'Hi there! привет!'
162+ test_descr = u'описание документа'
163+
164+ s = ''
165+ for i in range(0,256):
166+ s += chr(i)
167+ s+= '\xff\xff'
168+
169+
170+ test_data = buffer(s)
171+
172+ doc = Document(title = test_title,
173+ description = test_descr,
174+ document = test_data)
175+ doc.save()
176+ doc_id = doc.id
177+ doc = None
178+ doc = Document.objects.get(id=doc_id)
179+ assert doc.title == test_title, type(doc.title)
180+ assert doc.description == test_descr, type(doc.description)
181+ assert doc.document == test_data, type(doc.document)
182+
183+class BinaryFieldTests( unittest.TestCase ):
184+
185+ def test_binary(self):
186+ test_title = u'Hi there! привет!'
187+
188+ s = ''
189+ for i in range(0,10):
190+ s += chr(i)
191+
192+ s+= '\xff\xff'
193+
194+ test_data = buffer(s)
195+
196+
197+ tst = BinaryFieldTest(title = test_title,
198+ binfield = test_data)
199+ tst.save()
200+ tst_id = tst.id
201+ tst = None
202+ tst = BinaryFieldTest.objects.get(id=tst_id)
203+ assert tst.title == test_title, type(tst.title)
204+ assert tst.binfield == test_data, type(tst.binfield)
205+
206+
207+def test_suite():
208+ return unittest.TestSuite((
209+ unittest.makeSuite(BlobFieldTests),
210+ unittest.makeSuite(BinaryFieldTests)
211+ ))
212+
213+
214+
215+if __name__ == '__main__':
216+ unittest.main(defaultTest='test_suite')
217Index: tests/modeltests/binary/models.py
218===================================================================
219--- tests/modeltests/binary/models.py (revision 0)
220+++ tests/modeltests/binary/models.py (revision 0)
221@@ -0,0 +1,18 @@
222+"""
223+BlobField and BinaryField tests
224+
225+"""
226+
227+from django.db import models
228+
229+# Create your models here.
230+class Document(models.Model):
231+ title = models.CharField(max_length=50)
232+ description = models.TextField()
233+ document = models.BlobField()
234+
235+class BinaryFieldTest(models.Model):
236+ title = models.CharField(max_length=20)
237+ binfield = models.BinaryField(max_length=20)
238+
239+
Back to Top