sqlobject 3.13.1__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. sqlobject/__init__.py +15 -0
  2. sqlobject/__version__.py +8 -0
  3. sqlobject/boundattributes.py +124 -0
  4. sqlobject/cache.py +376 -0
  5. sqlobject/classregistry.py +138 -0
  6. sqlobject/col.py +2187 -0
  7. sqlobject/compat.py +59 -0
  8. sqlobject/conftest.py +64 -0
  9. sqlobject/constraints.py +77 -0
  10. sqlobject/converters.py +278 -0
  11. sqlobject/dbconnection.py +1137 -0
  12. sqlobject/dberrors.py +54 -0
  13. sqlobject/declarative.py +211 -0
  14. sqlobject/events.py +365 -0
  15. sqlobject/firebird/__init__.py +8 -0
  16. sqlobject/firebird/firebirdconnection.py +463 -0
  17. sqlobject/include/__init__.py +1 -0
  18. sqlobject/include/hashcol.py +109 -0
  19. sqlobject/include/tests/__init__.py +1 -0
  20. sqlobject/include/tests/test_hashcol.py +84 -0
  21. sqlobject/index.py +189 -0
  22. sqlobject/inheritance/__init__.py +551 -0
  23. sqlobject/inheritance/iteration.py +106 -0
  24. sqlobject/inheritance/tests/__init__.py +1 -0
  25. sqlobject/inheritance/tests/test_aggregates.py +23 -0
  26. sqlobject/inheritance/tests/test_asdict.py +48 -0
  27. sqlobject/inheritance/tests/test_deep_inheritance.py +114 -0
  28. sqlobject/inheritance/tests/test_destroy_cascade.py +23 -0
  29. sqlobject/inheritance/tests/test_foreignKey.py +94 -0
  30. sqlobject/inheritance/tests/test_indexes.py +42 -0
  31. sqlobject/inheritance/tests/test_inheritance.py +164 -0
  32. sqlobject/inheritance/tests/test_inheritance_tree.py +50 -0
  33. sqlobject/joins.py +656 -0
  34. sqlobject/main.py +1880 -0
  35. sqlobject/manager/__init__.py +1 -0
  36. sqlobject/manager/command.py +1309 -0
  37. sqlobject/maxdb/__init__.py +8 -0
  38. sqlobject/maxdb/maxdbconnection.py +320 -0
  39. sqlobject/maxdb/readme.txt +27 -0
  40. sqlobject/mssql/__init__.py +8 -0
  41. sqlobject/mssql/mssqlconnection.py +417 -0
  42. sqlobject/mysql/__init__.py +8 -0
  43. sqlobject/mysql/mysqlconnection.py +562 -0
  44. sqlobject/postgres/__init__.py +8 -0
  45. sqlobject/postgres/pgconnection.py +619 -0
  46. sqlobject/sqlbuilder.py +1655 -0
  47. sqlobject/sqlite/__init__.py +8 -0
  48. sqlobject/sqlite/sqliteconnection.py +418 -0
  49. sqlobject/sresults.py +377 -0
  50. sqlobject/styles.py +174 -0
  51. sqlobject/sybase/__init__.py +8 -0
  52. sqlobject/sybase/sybaseconnection.py +183 -0
  53. sqlobject/tests/__init__.py +1 -0
  54. sqlobject/tests/dbtest.py +363 -0
  55. sqlobject/tests/test_ForeignKey.py +133 -0
  56. sqlobject/tests/test_ForeignKey_cascade.py +150 -0
  57. sqlobject/tests/test_NoneValuedResultItem.py +33 -0
  58. sqlobject/tests/test_SQLMultipleJoin.py +65 -0
  59. sqlobject/tests/test_SQLRelatedJoin.py +114 -0
  60. sqlobject/tests/test_SingleJoin.py +30 -0
  61. sqlobject/tests/test_aggregates.py +75 -0
  62. sqlobject/tests/test_aliases.py +49 -0
  63. sqlobject/tests/test_asdict.py +18 -0
  64. sqlobject/tests/test_auto.py +218 -0
  65. sqlobject/tests/test_basic.py +359 -0
  66. sqlobject/tests/test_blob.py +34 -0
  67. sqlobject/tests/test_boundattributes.py +67 -0
  68. sqlobject/tests/test_cache.py +57 -0
  69. sqlobject/tests/test_class_hash.py +22 -0
  70. sqlobject/tests/test_columns_order.py +18 -0
  71. sqlobject/tests/test_combining_joins.py +47 -0
  72. sqlobject/tests/test_comparison.py +24 -0
  73. sqlobject/tests/test_compat.py +10 -0
  74. sqlobject/tests/test_complex_sorting.py +77 -0
  75. sqlobject/tests/test_constraints.py +43 -0
  76. sqlobject/tests/test_converters.py +276 -0
  77. sqlobject/tests/test_create_drop.py +29 -0
  78. sqlobject/tests/test_csvexport.py +101 -0
  79. sqlobject/tests/test_csvimport.py +21 -0
  80. sqlobject/tests/test_cyclic_reference.py +55 -0
  81. sqlobject/tests/test_datetime.py +171 -0
  82. sqlobject/tests/test_dbconnection.py +17 -0
  83. sqlobject/tests/test_decimal.py +63 -0
  84. sqlobject/tests/test_declarative.py +83 -0
  85. sqlobject/tests/test_default_style.py +65 -0
  86. sqlobject/tests/test_delete.py +74 -0
  87. sqlobject/tests/test_distinct.py +36 -0
  88. sqlobject/tests/test_empty.py +22 -0
  89. sqlobject/tests/test_enum.py +75 -0
  90. sqlobject/tests/test_events.py +142 -0
  91. sqlobject/tests/test_exceptions.py +40 -0
  92. sqlobject/tests/test_expire.py +29 -0
  93. sqlobject/tests/test_groupBy.py +45 -0
  94. sqlobject/tests/test_identity.py +29 -0
  95. sqlobject/tests/test_indexes.py +100 -0
  96. sqlobject/tests/test_inheritance.py +35 -0
  97. sqlobject/tests/test_joins.py +160 -0
  98. sqlobject/tests/test_joins_conditional.py +143 -0
  99. sqlobject/tests/test_jsonbcol.py +53 -0
  100. sqlobject/tests/test_jsoncol.py +56 -0
  101. sqlobject/tests/test_lazy.py +165 -0
  102. sqlobject/tests/test_md5.py +13 -0
  103. sqlobject/tests/test_mysql.py +50 -0
  104. sqlobject/tests/test_new_joins.py +165 -0
  105. sqlobject/tests/test_parse_uri.py +147 -0
  106. sqlobject/tests/test_paste.py +92 -0
  107. sqlobject/tests/test_perConnection.py +20 -0
  108. sqlobject/tests/test_pickle.py +42 -0
  109. sqlobject/tests/test_picklecol.py +44 -0
  110. sqlobject/tests/test_postgres.py +82 -0
  111. sqlobject/tests/test_reparent_sqlmeta.py +33 -0
  112. sqlobject/tests/test_schema.py +30 -0
  113. sqlobject/tests/test_select.py +218 -0
  114. sqlobject/tests/test_select_through.py +63 -0
  115. sqlobject/tests/test_setters.py +23 -0
  116. sqlobject/tests/test_slice.py +59 -0
  117. sqlobject/tests/test_sorting.py +80 -0
  118. sqlobject/tests/test_sqlbuilder.py +134 -0
  119. sqlobject/tests/test_sqlbuilder_dbspecific.py +66 -0
  120. sqlobject/tests/test_sqlbuilder_importproxy.py +55 -0
  121. sqlobject/tests/test_sqlbuilder_joins_instances.py +90 -0
  122. sqlobject/tests/test_sqlite.py +160 -0
  123. sqlobject/tests/test_sqlmeta_idName.py +52 -0
  124. sqlobject/tests/test_sqlobject_admin.py +38 -0
  125. sqlobject/tests/test_string_id.py +79 -0
  126. sqlobject/tests/test_style.py +36 -0
  127. sqlobject/tests/test_subqueries.py +142 -0
  128. sqlobject/tests/test_transactions.py +122 -0
  129. sqlobject/tests/test_unicode.py +84 -0
  130. sqlobject/tests/test_uuidcol.py +40 -0
  131. sqlobject/tests/test_validation.py +125 -0
  132. sqlobject/tests/test_views.py +159 -0
  133. sqlobject/util/__init__.py +1 -0
  134. sqlobject/util/csvexport.py +210 -0
  135. sqlobject/util/csvimport.py +366 -0
  136. sqlobject/util/moduleloader.py +35 -0
  137. sqlobject/util/threadinglocal.py +6 -0
  138. sqlobject/versioning/__init__.py +120 -0
  139. sqlobject/versioning/test/__init__.py +0 -0
  140. sqlobject/versioning/test/test_version.py +183 -0
  141. sqlobject/views.py +151 -0
  142. sqlobject/wsgi_middleware.py +109 -0
  143. sqlobject-3.13.1.data/scripts/sqlobject-admin +36 -0
  144. sqlobject-3.13.1.data/scripts/sqlobject-convertOldURI +19 -0
  145. sqlobject-3.13.1.dist-info/METADATA +177 -0
  146. sqlobject-3.13.1.dist-info/RECORD +149 -0
  147. sqlobject-3.13.1.dist-info/WHEEL +6 -0
  148. sqlobject-3.13.1.dist-info/entry_points.txt +4 -0
  149. sqlobject-3.13.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,218 @@
1
+ from datetime import datetime
2
+ from pytest import raises
3
+
4
+ from sqlobject import KeyCol, MultipleJoin, SQLObject, StringCol, \
5
+ classregistry, sqlmeta
6
+ from sqlobject.col import use_microseconds
7
+ from sqlobject.tests.dbtest import getConnection, setupClass
8
+
9
+
10
+ ########################################
11
+ # Dynamic column tests
12
+ ########################################
13
+
14
+
15
+ now = datetime.now
16
+
17
+
18
+ class Person(SQLObject):
19
+
20
+ class sqlmeta:
21
+ defaultOrder = 'name'
22
+ name = StringCol(length=100, dbName='name_col')
23
+
24
+
25
+ class Phone(SQLObject):
26
+
27
+ class sqlmeta:
28
+ defaultOrder = 'phone'
29
+ phone = StringCol(length=12)
30
+
31
+
32
+ class TestPeople:
33
+
34
+ def setup_method(self, meth):
35
+ setupClass(Person)
36
+ setupClass(Phone)
37
+ for n in ['jane', 'tim', 'bob', 'jake']:
38
+ Person(name=n)
39
+ for p in ['555-555-5555', '555-394-2930',
40
+ '444-382-4854']:
41
+ Phone(phone=p)
42
+
43
+ def test_defaultOrder(self):
44
+ assert list(Person.select('all')) == list(
45
+ Person.select('all', orderBy=Person.sqlmeta.defaultOrder))
46
+
47
+ def test_dynamicColumn(self):
48
+ nickname = StringCol('nickname', length=10)
49
+ Person.sqlmeta.addColumn(nickname, changeSchema=True)
50
+ Person(name='robert', nickname='bob')
51
+ assert ([p.name for p in Person.select('all')]
52
+ == ['bob', 'jake', 'jane', 'robert', 'tim'])
53
+ Person.sqlmeta.delColumn(nickname, changeSchema=True)
54
+
55
+ def test_dynamicJoin(self):
56
+ col = KeyCol('person', foreignKey='Person')
57
+ Phone.sqlmeta.addColumn(col, changeSchema=True)
58
+ join = MultipleJoin('Phone')
59
+ Person.sqlmeta.addJoin(join)
60
+ for phone in Phone.select('all'):
61
+ if phone.phone.startswith('555'):
62
+ phone.person = Person.selectBy(name='tim')[0]
63
+ else:
64
+ phone.person = Person.selectBy(name='bob')[0]
65
+ _l = [p.phone for p in Person.selectBy(name='tim')[0].phones]
66
+ _l.sort()
67
+ assert _l == ['555-394-2930', '555-555-5555']
68
+ Phone.sqlmeta.delColumn(col, changeSchema=True)
69
+ Person.sqlmeta.delJoin(join)
70
+
71
+ def _test_collidingName(self):
72
+ class CollidingName(SQLObject):
73
+ expire = StringCol()
74
+
75
+ def test_collidingName(self):
76
+ raises(AssertionError, Person.sqlmeta.addColumn,
77
+ StringCol(name="name"))
78
+ raises(AssertionError, Person.sqlmeta.addColumn,
79
+ StringCol(name="_init"))
80
+ raises(AssertionError, Person.sqlmeta.addColumn,
81
+ StringCol(name="expire"))
82
+ raises(AssertionError, Person.sqlmeta.addColumn,
83
+ StringCol(name="set"))
84
+ raises(AssertionError, self._test_collidingName)
85
+
86
+
87
+ ########################################
88
+ # Auto class generation
89
+ ########################################
90
+
91
+
92
+ class TestAuto:
93
+
94
+ mysqlCreate = """
95
+ CREATE TABLE IF NOT EXISTS auto_test (
96
+ auto_id INT AUTO_INCREMENT PRIMARY KEY,
97
+ first_name VARCHAR(100),
98
+ last_name VARCHAR(200) NOT NULL,
99
+ age INT DEFAULT NULL,
100
+ created DATETIME NOT NULL,
101
+ happy char(1) DEFAULT 'Y' NOT NULL,
102
+ long_field TEXT,
103
+ wannahavefun TINYINT DEFAULT 0 NOT NULL
104
+ )
105
+ """
106
+
107
+ postgresCreate = """
108
+ CREATE TABLE auto_test (
109
+ auto_id SERIAL PRIMARY KEY,
110
+ first_name VARCHAR(100),
111
+ last_name VARCHAR(200) NOT NULL,
112
+ age INT DEFAULT 0,
113
+ created TIMESTAMP NOT NULL,
114
+ happy char(1) DEFAULT 'Y' NOT NULL,
115
+ long_field TEXT,
116
+ wannahavefun BOOL DEFAULT FALSE NOT NULL
117
+ )
118
+ """
119
+
120
+ sqliteCreate = """
121
+ CREATE TABLE auto_test (
122
+ auto_id INTEGER PRIMARY KEY AUTOINCREMENT ,
123
+ first_name VARCHAR(100),
124
+ last_name VARCHAR(200) NOT NULL,
125
+ age INT DEFAULT NULL,
126
+ created DATETIME NOT NULL,
127
+ happy char(1) DEFAULT 'Y' NOT NULL,
128
+ long_field TEXT,
129
+ wannahavefun INT DEFAULT 0 NOT NULL
130
+ )
131
+ """
132
+
133
+ sybaseCreate = """
134
+ CREATE TABLE auto_test (
135
+ auto_id integer,
136
+ first_name VARCHAR(100),
137
+ last_name VARCHAR(200) NOT NULL,
138
+ age INT DEFAULT 0,
139
+ created DATETIME NOT NULL,
140
+ happy char(1) DEFAULT 'Y' NOT NULL,
141
+ long_field TEXT,
142
+ wannahavefun BIT default(0) NOT NULL
143
+ )
144
+ """
145
+
146
+ mssqlCreate = """
147
+ CREATE TABLE auto_test (
148
+ auto_id int identity(1,1),
149
+ first_name VARCHAR(100),
150
+ last_name VARCHAR(200) NOT NULL,
151
+ age INT DEFAULT 0,
152
+ created DATETIME NOT NULL,
153
+ happy char(1) DEFAULT 'Y' NOT NULL,
154
+ long_field TEXT,
155
+ wannahavefun BIT default(0) NOT NULL
156
+ )
157
+ """
158
+
159
+ mysqlDrop = """
160
+ DROP TABLE IF EXISTS auto_test
161
+ """
162
+
163
+ postgresDrop = """
164
+ DROP TABLE auto_test
165
+ """
166
+
167
+ sqliteDrop = sybaseDrop = mssqlDrop = postgresDrop
168
+
169
+ def setup_method(self, meth):
170
+ conn = getConnection()
171
+ dbName = conn.dbName
172
+ creator = getattr(self, dbName + 'Create', None)
173
+ if creator:
174
+ conn.query(creator)
175
+
176
+ def teardown_method(self, meth):
177
+ conn = getConnection()
178
+ dbName = conn.dbName
179
+ dropper = getattr(self, dbName + 'Drop', None)
180
+ if dropper:
181
+ try:
182
+ conn.query(dropper)
183
+ except Exception: # Perhaps we don't have DROP permission
184
+ pass
185
+
186
+ def test_classCreate(self):
187
+ class AutoTest(SQLObject):
188
+ _connection = getConnection()
189
+
190
+ class sqlmeta(sqlmeta):
191
+ idName = 'auto_id'
192
+ fromDatabase = True
193
+ if AutoTest._connection.dbName == 'mssql':
194
+ use_microseconds(False)
195
+ john = AutoTest(firstName='john',
196
+ lastName='doe',
197
+ age=10,
198
+ created=now(),
199
+ wannahavefun=False,
200
+ longField='x' * 1000)
201
+ jane = AutoTest(firstName='jane',
202
+ lastName='doe',
203
+ happy='N',
204
+ created=now(),
205
+ wannahavefun=True,
206
+ longField='x' * 1000)
207
+ assert not john.wannahavefun
208
+ assert jane.wannahavefun
209
+ assert john.longField == 'x' * 1000
210
+ assert jane.longField == 'x' * 1000
211
+ del classregistry.registry(
212
+ AutoTest.sqlmeta.registry).classes['AutoTest']
213
+
214
+ columns = AutoTest.sqlmeta.columns
215
+ assert columns["lastName"].dbName == "last_name"
216
+ assert columns["wannahavefun"].dbName == "wannahavefun"
217
+ if AutoTest._connection.dbName == 'mssql':
218
+ use_microseconds(True)
@@ -0,0 +1,359 @@
1
+ import codecs
2
+ import pytest
3
+ from sqlobject import BoolCol, ForeignKey, IntCol, KeyCol, SQLObject, \
4
+ StringCol, connectionForURI, sqlhub
5
+ from sqlobject.tests.dbtest import inserts, raises, setupClass, supports
6
+
7
+
8
+ class SOTestSO1(SQLObject):
9
+
10
+ name = StringCol(length=50, dbName='name_col')
11
+ name.title = 'Your Name'
12
+ name.foobar = 1
13
+ passwd = StringCol(length=10)
14
+
15
+ class sqlmeta:
16
+ cacheValues = False
17
+
18
+ def _set_passwd(self, passwd):
19
+ self._SO_set_passwd(codecs.encode(passwd, 'rot13'))
20
+
21
+
22
+ def setupGetters(cls):
23
+ setupClass(cls)
24
+ inserts(cls, [('bob', 'god'), ('sally', 'sordid'),
25
+ ('dave', 'dremel'), ('fred', 'forgo')],
26
+ 'name passwd')
27
+
28
+
29
+ def test_case1():
30
+ setupGetters(SOTestSO1)
31
+ bob = SOTestSO1.selectBy(name='bob')[0]
32
+ assert bob.name == 'bob'
33
+ assert bob.passwd == codecs.encode('god', 'rot13')
34
+ bobs = SOTestSO1.selectBy(name='bob')[:10]
35
+ assert len(list(bobs)) == 1
36
+
37
+
38
+ def test_newline():
39
+ setupGetters(SOTestSO1)
40
+ bob = SOTestSO1.selectBy(name='bob')[0]
41
+ testString = 'hey\nyou\\can\'t you see me?\t'
42
+ bob.name = testString
43
+ bob.expire()
44
+ assert bob.name == testString
45
+
46
+
47
+ def test_count():
48
+ setupGetters(SOTestSO1)
49
+ assert SOTestSO1.selectBy(name=None).count() == 0
50
+ assert SOTestSO1.selectBy(name='bob').count() == 1
51
+ assert SOTestSO1.select(SOTestSO1.q.name == 'bob').count() == 1
52
+ assert SOTestSO1.select().count() == len(list(SOTestSO1.select()))
53
+
54
+
55
+ def test_getset():
56
+ setupGetters(SOTestSO1)
57
+ bob = SOTestSO1.selectBy(name='bob')[0]
58
+ assert bob.name == 'bob'
59
+ bob.name = 'joe'
60
+ assert bob.name == 'joe'
61
+ bob.set(name='joebob', passwd='testtest')
62
+ assert bob.name == 'joebob'
63
+
64
+
65
+ def test_extra_vars():
66
+ setupGetters(SOTestSO1)
67
+ col = SOTestSO1.sqlmeta.columns['name']
68
+ assert col.title == 'Your Name'
69
+ assert col.foobar == 1
70
+ assert getattr(SOTestSO1.sqlmeta.columns['passwd'], 'title', None) is None
71
+
72
+
73
+ class SOTestSO2(SQLObject):
74
+ name = StringCol(length=50, dbName='name_col')
75
+ passwd = StringCol(length=10)
76
+
77
+ def _set_passwd(self, passwd):
78
+ self._SO_set_passwd(codecs.encode(passwd, 'rot13'))
79
+
80
+
81
+ def test_case2():
82
+ setupGetters(SOTestSO2)
83
+ bob = SOTestSO2.selectBy(name='bob')[0]
84
+ assert bob.name == 'bob'
85
+ assert bob.passwd == codecs.encode('god', 'rot13')
86
+
87
+
88
+ class Student(SQLObject):
89
+ is_smart = BoolCol()
90
+
91
+
92
+ def test_boolCol():
93
+ setupClass(Student)
94
+ student = Student(is_smart=False)
95
+ assert not student.is_smart
96
+ student2 = Student(is_smart=1)
97
+ assert student2.is_smart
98
+
99
+
100
+ class SOTestSO3(SQLObject):
101
+ name = StringCol(length=10, dbName='name_col')
102
+ other = ForeignKey('SOTestSO4', default=None)
103
+ other2 = KeyCol(foreignKey='SOTestSO4', default=None)
104
+
105
+
106
+ class SOTestSO4(SQLObject):
107
+ me = StringCol(length=10)
108
+
109
+
110
+ def test_foreignKey():
111
+ setupClass([SOTestSO4, SOTestSO3])
112
+ test3_order = [col.name for col in SOTestSO3.sqlmeta.columnList]
113
+ assert test3_order == ['name', 'otherID', 'other2ID']
114
+ tc3 = SOTestSO3(name='a')
115
+ assert tc3.other is None
116
+ assert tc3.other2 is None
117
+ assert tc3.otherID is None
118
+ assert tc3.other2ID is None
119
+ tc4a = SOTestSO4(me='1')
120
+ tc3.other = tc4a
121
+ assert tc3.other == tc4a
122
+ assert tc3.otherID == tc4a.id
123
+ tc4b = SOTestSO4(me='2')
124
+ tc3.other = tc4b.id
125
+ assert tc3.other == tc4b
126
+ assert tc3.otherID == tc4b.id
127
+ tc4c = SOTestSO4(me='3')
128
+ tc3.other2 = tc4c
129
+ assert tc3.other2 == tc4c
130
+ assert tc3.other2ID == tc4c.id
131
+ tc4d = SOTestSO4(me='4')
132
+ tc3.other2 = tc4d.id
133
+ assert tc3.other2 == tc4d
134
+ assert tc3.other2ID == tc4d.id
135
+ tcc = SOTestSO3(name='b', other=tc4a)
136
+ assert tcc.other == tc4a
137
+ tcc2 = SOTestSO3(name='c', other=tc4a.id)
138
+ assert tcc2.other == tc4a
139
+
140
+
141
+ def test_selectBy():
142
+ setupClass([SOTestSO4, SOTestSO3])
143
+ tc4 = SOTestSO4(me='another')
144
+ tc3 = SOTestSO3(name='sel', other=tc4)
145
+ SOTestSO3(name='not joined')
146
+ assert tc3.other == tc4
147
+ assert list(SOTestSO3.selectBy(other=tc4)) == [tc3]
148
+ assert list(SOTestSO3.selectBy(otherID=tc4.id)) == [tc3]
149
+ assert SOTestSO3.selectBy(otherID=tc4.id)[0] == tc3
150
+ assert list(SOTestSO3.selectBy(otherID=tc4.id)[:10]) == [tc3]
151
+ assert list(SOTestSO3.selectBy(other=tc4)[:10]) == [tc3]
152
+
153
+
154
+ class SOTestSO5(SQLObject):
155
+ name = StringCol(length=10, dbName='name_col')
156
+ other = ForeignKey('SOTestSO6', default=None, cascade=True)
157
+ another = ForeignKey('SOTestSO7', default=None, cascade=True)
158
+
159
+
160
+ class SOTestSO6(SQLObject):
161
+ name = StringCol(length=10, dbName='name_col')
162
+ other = ForeignKey('SOTestSO7', default=None, cascade=True)
163
+
164
+
165
+ class SOTestSO7(SQLObject):
166
+ name = StringCol(length=10, dbName='name_col')
167
+
168
+
169
+ def test_foreignKeyDestroySelfCascade():
170
+ setupClass([SOTestSO7, SOTestSO6, SOTestSO5])
171
+
172
+ tc5 = SOTestSO5(name='a')
173
+ tc6a = SOTestSO6(name='1')
174
+ tc5.other = tc6a
175
+ tc7a = SOTestSO7(name='2')
176
+ tc6a.other = tc7a
177
+ tc5.another = tc7a
178
+ assert tc5.other == tc6a
179
+ assert tc5.otherID == tc6a.id
180
+ assert tc6a.other == tc7a
181
+ assert tc6a.otherID == tc7a.id
182
+ assert tc5.other.other == tc7a
183
+ assert tc5.other.otherID == tc7a.id
184
+ assert tc5.another == tc7a
185
+ assert tc5.anotherID == tc7a.id
186
+ assert tc5.other.other == tc5.another
187
+ assert SOTestSO5.select().count() == 1
188
+ assert SOTestSO6.select().count() == 1
189
+ assert SOTestSO7.select().count() == 1
190
+ tc6b = SOTestSO6(name='3')
191
+ tc6c = SOTestSO6(name='4')
192
+ tc7b = SOTestSO7(name='5')
193
+ tc6b.other = tc7b
194
+ tc6c.other = tc7b
195
+ assert SOTestSO5.select().count() == 1
196
+ assert SOTestSO6.select().count() == 3
197
+ assert SOTestSO7.select().count() == 2
198
+ tc6b.destroySelf()
199
+ assert SOTestSO5.select().count() == 1
200
+ assert SOTestSO6.select().count() == 2
201
+ assert SOTestSO7.select().count() == 2
202
+ tc7b.destroySelf()
203
+ assert SOTestSO5.select().count() == 1
204
+ assert SOTestSO6.select().count() == 1
205
+ assert SOTestSO7.select().count() == 1
206
+ tc7a.destroySelf()
207
+ assert SOTestSO5.select().count() == 0
208
+ assert SOTestSO6.select().count() == 0
209
+ assert SOTestSO7.select().count() == 0
210
+
211
+
212
+ def testForeignKeyDropTableCascade():
213
+ if not supports('dropTableCascade'):
214
+ pytest.skip("dropTableCascade isn't supported")
215
+ setupClass(SOTestSO7)
216
+ setupClass(SOTestSO6)
217
+ setupClass(SOTestSO5)
218
+
219
+ tc5a = SOTestSO5(name='a')
220
+ tc6a = SOTestSO6(name='1')
221
+ tc5a.other = tc6a
222
+ tc7a = SOTestSO7(name='2')
223
+ tc6a.other = tc7a
224
+ tc5a.another = tc7a
225
+ tc5b = SOTestSO5(name='b')
226
+ tc5c = SOTestSO5(name='c')
227
+ tc6b = SOTestSO6(name='3')
228
+ tc5c.other = tc6b
229
+ assert SOTestSO5.select().count() == 3
230
+ assert SOTestSO6.select().count() == 2
231
+ assert SOTestSO7.select().count() == 1
232
+ SOTestSO7.dropTable(cascade=True)
233
+ assert SOTestSO5.select().count() == 3
234
+ assert SOTestSO6.select().count() == 2
235
+ tc6a.destroySelf()
236
+ assert SOTestSO5.select().count() == 2
237
+ assert SOTestSO6.select().count() == 1
238
+ tc6b.destroySelf()
239
+ assert SOTestSO5.select().count() == 1
240
+ assert SOTestSO6.select().count() == 0
241
+ assert next(iter(SOTestSO5.select())) == tc5b
242
+ tc6c = SOTestSO6(name='3')
243
+ tc5b.other = tc6c
244
+ assert SOTestSO5.select().count() == 1
245
+ assert SOTestSO6.select().count() == 1
246
+ tc6c.destroySelf()
247
+ assert SOTestSO5.select().count() == 0
248
+ assert SOTestSO6.select().count() == 0
249
+
250
+
251
+ class SOTestSO8(SQLObject):
252
+ name = StringCol(length=10, dbName='name_col')
253
+ other = ForeignKey('SOTestSO9', default=None, cascade=False)
254
+
255
+
256
+ class SOTestSO9(SQLObject):
257
+ name = StringCol(length=10, dbName='name_col')
258
+
259
+
260
+ def testForeignKeyDestroySelfRestrict():
261
+ setupClass([SOTestSO9, SOTestSO8])
262
+
263
+ tc8a = SOTestSO8(name='a')
264
+ tc9a = SOTestSO9(name='1')
265
+ tc8a.other = tc9a
266
+ tc8b = SOTestSO8(name='b')
267
+ tc9b = SOTestSO9(name='2')
268
+ assert tc8a.other == tc9a
269
+ assert tc8a.otherID == tc9a.id
270
+ assert SOTestSO8.select().count() == 2
271
+ assert SOTestSO9.select().count() == 2
272
+ raises(Exception, tc9a.destroySelf)
273
+ tc9b.destroySelf()
274
+ assert SOTestSO8.select().count() == 2
275
+ assert SOTestSO9.select().count() == 1
276
+ tc8a.destroySelf()
277
+ tc8b.destroySelf()
278
+ tc9a.destroySelf()
279
+ assert SOTestSO8.select().count() == 0
280
+ assert SOTestSO9.select().count() == 0
281
+
282
+
283
+ class SOTestSO10(SQLObject):
284
+ name = StringCol()
285
+
286
+
287
+ class SOTestSO11(SQLObject):
288
+ name = StringCol()
289
+ other = ForeignKey('SOTestSO10', default=None, cascade='null')
290
+
291
+
292
+ def testForeignKeySetNull():
293
+ setupClass([SOTestSO10, SOTestSO11])
294
+ obj1 = SOTestSO10(name='foo')
295
+ obj2 = SOTestSO10(name='bar')
296
+ dep1 = SOTestSO11(name='xxx', other=obj1)
297
+ dep2 = SOTestSO11(name='yyy', other=obj1)
298
+ dep3 = SOTestSO11(name='zzz', other=obj2)
299
+ for name in 'xxx', 'yyy', 'zzz':
300
+ assert len(list(SOTestSO11.selectBy(name=name))) == 1
301
+ obj1.destroySelf()
302
+ for name in 'xxx', 'yyy', 'zzz':
303
+ assert len(list(SOTestSO11.selectBy(name=name))) == 1
304
+ assert dep1.other is None
305
+ assert dep2.other is None
306
+ assert dep3.other is obj2
307
+
308
+
309
+ def testAsDict():
310
+ setupGetters(SOTestSO1)
311
+ bob = SOTestSO1.selectBy(name='bob')[0]
312
+ assert bob.sqlmeta.asDict() == {
313
+ 'passwd': 'tbq', 'name': 'bob', 'id': bob.id}
314
+
315
+
316
+ def test_nonexisting_attr():
317
+ setupClass(Student)
318
+ raises(AttributeError, getattr, Student.q, 'nonexisting')
319
+
320
+
321
+ class SOTestSO12(SQLObject):
322
+ name = StringCol()
323
+ so_value = IntCol(defaultSQL='1')
324
+
325
+
326
+ def test_defaultSQL():
327
+ setupClass(SOTestSO12)
328
+ test = SOTestSO12(name="test")
329
+ assert test.so_value == 1
330
+
331
+
332
+ def test_connection_override():
333
+ sqlhub.processConnection = connectionForURI('sqlite:///db1')
334
+
335
+ class SOTestSO13(SQLObject):
336
+ _connection = connectionForURI('sqlite:///db2')
337
+
338
+ assert SOTestSO13._connection.uri() == 'sqlite:///db2'
339
+ del sqlhub.processConnection
340
+
341
+
342
+ def _test_wrong_sqlmeta_idType():
343
+ class SOTestSO13(SQLObject):
344
+ class sqlmeta:
345
+ idType = dict
346
+
347
+
348
+ def test_wrong_sqlmeta_idType():
349
+ pytest.raises(TypeError, _test_wrong_sqlmeta_idType)
350
+
351
+
352
+ def _test_wrong_sqlmeta_idSize():
353
+ class SOTestSO14(SQLObject):
354
+ class sqlmeta:
355
+ idSize = 'DEFAULT'
356
+
357
+
358
+ def test_wrong_sqlmeta_idSize():
359
+ pytest.raises(ValueError, _test_wrong_sqlmeta_idSize)
@@ -0,0 +1,34 @@
1
+ import pytest
2
+ from sqlobject import BLOBCol, SQLObject
3
+ from sqlobject.compat import PY2
4
+ from sqlobject.tests.dbtest import setupClass, supports
5
+
6
+
7
+ ########################################
8
+ # BLOB columns
9
+ ########################################
10
+
11
+
12
+ class ImageData(SQLObject):
13
+ image = BLOBCol(default=b'emptydata', length=256)
14
+
15
+
16
+ def test_BLOBCol():
17
+ if not supports('blobData'):
18
+ pytest.skip("blobData isn't supported")
19
+ setupClass(ImageData)
20
+ if PY2:
21
+ data = ''.join([chr(x) for x in range(256)])
22
+ else:
23
+ data = bytes(range(256))
24
+
25
+ prof = ImageData(image=data)
26
+ iid = prof.id
27
+
28
+ ImageData._connection.cache.clear()
29
+
30
+ prof2 = ImageData.get(iid)
31
+ assert prof2.image == data
32
+
33
+ ImageData(image=b'string')
34
+ assert ImageData.selectBy(image=b'string').count() == 1
@@ -0,0 +1,67 @@
1
+ import pytest
2
+
3
+ from sqlobject import boundattributes
4
+ from sqlobject import declarative
5
+
6
+ pytestmark = pytest.mark.skipif(
7
+ True,
8
+ reason='The module "boundattributes" and its tests were not finished yet')
9
+
10
+
11
+ class SOTestMe(object):
12
+ pass
13
+
14
+
15
+ class AttrReplace(boundattributes.BoundAttribute):
16
+
17
+ __unpackargs__ = ('replace',)
18
+
19
+ replace = None
20
+
21
+ @declarative.classinstancemethod
22
+ def make_object(self, cls, added_class, attr_name, **attrs):
23
+ if not self:
24
+ return cls.singleton().make_object(
25
+ added_class, attr_name, **attrs)
26
+ self.replace.added_class = added_class
27
+ self.replace.name = attr_name
28
+ assert attrs['replace'] is self.replace
29
+ del attrs['replace']
30
+ self.replace.attrs = attrs
31
+ return self.replace
32
+
33
+
34
+ class Holder:
35
+ def __init__(self, name):
36
+ self.holder_name = name
37
+
38
+ def __repr__(self):
39
+ return '<Holder %s>' % self.holder_name
40
+
41
+
42
+ def test_1():
43
+ v1 = Holder('v1')
44
+ v2 = Holder('v2')
45
+ v3 = Holder('v3')
46
+
47
+ class V2Class(AttrReplace):
48
+ arg1 = 'nothing'
49
+ arg2 = ['something']
50
+
51
+ class A1(SOTestMe):
52
+ a = AttrReplace(v1)
53
+ v = V2Class(v2)
54
+
55
+ class inline(AttrReplace):
56
+ replace = v3
57
+ arg3 = 'again'
58
+ arg4 = 'so there'
59
+ for n in ('a', 'v', 'inline'):
60
+ assert getattr(A1, n).name == n
61
+ assert getattr(A1, n).added_class is A1
62
+ assert A1.a is v1
63
+ assert A1.a.attrs == {}
64
+ assert A1.v is v2
65
+ assert A1.v.attrs == {'arg1': 'nothing', 'arg2': ['something']}
66
+ assert A1.inline is v3
67
+ assert A1.inline.attrs == {'arg3': 'again', 'arg4': 'so there'}