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,143 @@
1
+ from sqlobject import SQLObject, StringCol
2
+ from sqlobject.sqlbuilder import JOIN, LEFTJOIN, LEFTJOINConditional, \
3
+ LEFTJOINOn, LEFTJOINUsing
4
+ from sqlobject.tests.dbtest import getConnection, setupClass
5
+
6
+
7
+ ########################################
8
+ # Condiotional joins
9
+ ########################################
10
+
11
+
12
+ class SOTestJoin1(SQLObject):
13
+ col1 = StringCol()
14
+
15
+
16
+ class SOTestJoin2(SQLObject):
17
+ col2 = StringCol()
18
+
19
+
20
+ class SOTestJoin3(SQLObject):
21
+ col3 = StringCol()
22
+
23
+
24
+ class SOTestJoin4(SQLObject):
25
+ col4 = StringCol()
26
+
27
+
28
+ class SOTestJoin5(SQLObject):
29
+ col5 = StringCol()
30
+
31
+
32
+ def setup():
33
+ setupClass(SOTestJoin1)
34
+ setupClass(SOTestJoin2)
35
+
36
+
37
+ def test_1syntax():
38
+ setup()
39
+ join = JOIN("table1", "table2")
40
+ assert str(join) == "table1 JOIN table2"
41
+ join = LEFTJOIN("table1", "table2")
42
+ assert str(join) == "table1 LEFT JOIN table2"
43
+ join = LEFTJOINOn("table1", "table2", "tabl1.col1 = table2.col2")
44
+ assert getConnection().sqlrepr(join) == \
45
+ "table1 LEFT JOIN table2 ON tabl1.col1 = table2.col2"
46
+
47
+
48
+ def test_2select_syntax():
49
+ setup()
50
+ select = SOTestJoin1.select(
51
+ join=LEFTJOINConditional(SOTestJoin1, SOTestJoin2,
52
+ on_condition=(
53
+ SOTestJoin1.q.col1 == SOTestJoin2.q.col2))
54
+ )
55
+ assert str(select) == \
56
+ "SELECT so_test_join1.id, so_test_join1.col1 " \
57
+ "FROM so_test_join1 " \
58
+ "LEFT JOIN so_test_join2 " \
59
+ "ON ((so_test_join1.col1) = (so_test_join2.col2)) WHERE 1 = 1"
60
+
61
+
62
+ def test_3perform_join():
63
+ setup()
64
+ SOTestJoin1(col1="test1")
65
+ SOTestJoin1(col1="test2")
66
+ SOTestJoin1(col1="test3")
67
+ SOTestJoin2(col2="test1")
68
+ SOTestJoin2(col2="test2")
69
+
70
+ select = SOTestJoin1.select(
71
+ join=LEFTJOINOn(SOTestJoin1, SOTestJoin2,
72
+ SOTestJoin1.q.col1 == SOTestJoin2.q.col2)
73
+ )
74
+ assert select.count() == 3
75
+
76
+
77
+ def test_4join_3tables_syntax():
78
+ setup()
79
+ setupClass(SOTestJoin3)
80
+
81
+ select = SOTestJoin1.select(
82
+ join=LEFTJOIN(SOTestJoin2, SOTestJoin3)
83
+ )
84
+ assert str(select) == \
85
+ "SELECT so_test_join1.id, so_test_join1.col1 " \
86
+ "FROM so_test_join1, so_test_join2 LEFT JOIN so_test_join3 WHERE 1 = 1"
87
+
88
+
89
+ def test_5join_3tables_syntax2():
90
+ setup()
91
+ setupClass(SOTestJoin3)
92
+
93
+ select = SOTestJoin1.select(
94
+ join=(LEFTJOIN(None, SOTestJoin2), LEFTJOIN(None, SOTestJoin3))
95
+ )
96
+ assert str(select) == \
97
+ "SELECT so_test_join1.id, so_test_join1.col1 " \
98
+ "FROM so_test_join1 " \
99
+ "LEFT JOIN so_test_join2 LEFT JOIN so_test_join3 WHERE 1 = 1"
100
+
101
+ select = SOTestJoin1.select(
102
+ join=(LEFTJOIN(SOTestJoin1, SOTestJoin2),
103
+ LEFTJOIN(SOTestJoin1, SOTestJoin3))
104
+ )
105
+ assert str(select) == \
106
+ "SELECT so_test_join1.id, so_test_join1.col1 " \
107
+ "FROM so_test_join1 " \
108
+ "LEFT JOIN so_test_join2, so_test_join1 " \
109
+ "LEFT JOIN so_test_join3 WHERE 1 = 1"
110
+
111
+
112
+ def test_6join_using():
113
+ setup()
114
+ setupClass(SOTestJoin3)
115
+
116
+ select = SOTestJoin1.select(
117
+ join=LEFTJOINUsing(None, SOTestJoin2, [SOTestJoin2.q.id])
118
+ )
119
+ assert str(select) == \
120
+ "SELECT so_test_join1.id, so_test_join1.col1 " \
121
+ "FROM so_test_join1 " \
122
+ "LEFT JOIN so_test_join2 USING (so_test_join2.id) WHERE 1 = 1"
123
+
124
+
125
+ def test_7join_on():
126
+ setup()
127
+ setupClass(SOTestJoin3)
128
+ setupClass(SOTestJoin4)
129
+ setupClass(SOTestJoin5)
130
+
131
+ select = SOTestJoin1.select(join=(
132
+ LEFTJOINOn(SOTestJoin2, SOTestJoin3,
133
+ SOTestJoin2.q.col2 == SOTestJoin3.q.col3),
134
+ LEFTJOINOn(SOTestJoin4, SOTestJoin5,
135
+ SOTestJoin4.q.col4 == SOTestJoin5.q.col5)
136
+ ))
137
+ assert str(select) == \
138
+ "SELECT so_test_join1.id, so_test_join1.col1 " \
139
+ "FROM so_test_join1, so_test_join2 " \
140
+ "LEFT JOIN so_test_join3 " \
141
+ "ON ((so_test_join2.col2) = (so_test_join3.col3)), so_test_join4 " \
142
+ "LEFT JOIN so_test_join5 " \
143
+ "ON ((so_test_join4.col4) = (so_test_join5.col5)) WHERE 1 = 1"
@@ -0,0 +1,53 @@
1
+ import pytest
2
+ from sqlobject import SQLObject, JsonbCol
3
+ from sqlobject.tests.dbtest import getConnection, setupClass
4
+
5
+
6
+ ########################################
7
+ # Jsonb columns
8
+ ########################################
9
+
10
+
11
+ class JsonbContainer(SQLObject):
12
+ jsondata = JsonbCol(default=None)
13
+ jsondata_none = JsonbCol(default=None)
14
+ jsondata_list = JsonbCol(default=None)
15
+
16
+
17
+ dictdata = dict(
18
+ ship=u'USS Voyager',
19
+ number='NCC-74656',
20
+ crew=['Cpt. Janeway', 'Doctor', 'Lt. Torries', 'Seven of Nine'],
21
+ races=('Borg', 'Kason',),
22
+ distance2earth=70000,
23
+ coming_home=True)
24
+
25
+ nonedata = None
26
+
27
+ listofdictsdata = [dict(Erath=7390000000),
28
+ dict(Vulcan=6000000000),
29
+ dict(Kronos='unknown')]
30
+
31
+
32
+ def test_jsonbCol():
33
+ connection = getConnection()
34
+ if connection.dbName != "postgres":
35
+ pytest.skip("These tests require PostgreSQL")
36
+
37
+ setupClass([JsonbContainer], force=True)
38
+
39
+ my_jsonb = JsonbContainer(
40
+ jsondata=dictdata,
41
+ jsondata_none=nonedata,
42
+ jsondata_list=listofdictsdata)
43
+ iid = my_jsonb.id
44
+
45
+ JsonbContainer._connection.cache.clear()
46
+
47
+ my_jsonb_2 = JsonbContainer.get(iid)
48
+
49
+ assert my_jsonb_2.jsondata['coming_home'] == dictdata['coming_home']
50
+ assert my_jsonb_2.jsondata['crew'] == dictdata['crew']
51
+ assert my_jsonb_2.jsondata['races'] == ['Borg', 'Kason']
52
+ assert my_jsonb_2.jsondata_none is None
53
+ assert my_jsonb_2.jsondata_list == listofdictsdata
@@ -0,0 +1,56 @@
1
+ import pytest
2
+ from sqlobject import SQLObject, JSONCol
3
+ from sqlobject.tests.dbtest import setupClass
4
+
5
+
6
+ class JSONTest(SQLObject):
7
+ json = JSONCol(default=None)
8
+
9
+
10
+ _json_test_data = (
11
+ None, True, 1, 2.0,
12
+ {u"test": [None, True, 1, 2.0,
13
+ {u"unicode'with'apostrophes": u"unicode\"with\"quotes"},
14
+ [],
15
+ u"unicode"]},
16
+ [None, True, 1, 2.0,
17
+ [],
18
+ {u"unicode'with'apostrophes": u"unicode\"with\"quotes"},
19
+ u"unicode", u"unicode'with'apostrophes", u"unicode\"with\"quotes",
20
+ ],
21
+ u"unicode", u"unicode'with'apostrophes", u"unicode\"with\"quotes",
22
+ {'test': 'Test'},
23
+ )
24
+
25
+
26
+ def _setup():
27
+ setupClass(JSONTest)
28
+
29
+ for _id, test_data in enumerate(_json_test_data):
30
+ JSONTest(id=_id + 1, json=test_data)
31
+
32
+
33
+ def test_JSONCol():
34
+ _setup()
35
+ JSONTest._connection.cache.clear()
36
+
37
+ for _id, test_data in enumerate(_json_test_data):
38
+ json = JSONTest.get(_id + 1)
39
+ assert json.json == test_data
40
+
41
+
42
+ def test_JSONCol_funcs():
43
+ connection = JSONTest._connection
44
+ if not hasattr(connection, 'can_use_json_funcs') \
45
+ or not connection.can_use_json_funcs():
46
+ pytest.skip(
47
+ "The database doesn't support JSON functions; "
48
+ "JSON functions are supported by MariaDB since version 10.2.7 "
49
+ "and by MySQL since version 5.7.")
50
+ _setup()
51
+
52
+ rows = list(
53
+ JSONTest.select(JSONTest.q.json.json_extract('test') == 'Test')
54
+ )
55
+ assert len(rows) == 1
56
+ assert rows[0].json == {'test': 'Test'}
@@ -0,0 +1,165 @@
1
+ from sqlobject import SQLObject, StringCol
2
+ from sqlobject.tests.dbtest import setupClass
3
+
4
+
5
+ ########################################
6
+ # Lazy updates
7
+ ########################################
8
+
9
+
10
+ class Lazy(SQLObject):
11
+
12
+ class sqlmeta:
13
+ lazyUpdate = True
14
+ name = StringCol()
15
+ other = StringCol(default='nothing')
16
+ third = StringCol(default='third')
17
+
18
+
19
+ class TestLazyTest:
20
+
21
+ def setup_method(self, meth):
22
+ # All this stuff is so that we can track when the connection
23
+ # does an actual update; we put in a new _SO_update method
24
+ # that calls the original and sets an instance variable that
25
+ # we can later check.
26
+ setupClass(Lazy)
27
+ self.conn = Lazy._connection
28
+ self.conn.didUpdate = False
29
+ self._oldUpdate = self.conn._SO_update
30
+ newUpdate = (
31
+ lambda so, values, s=self, c=self.conn, o=self._oldUpdate:
32
+ self._alternateUpdate(so, values, c, o))
33
+ self.conn._SO_update = newUpdate
34
+
35
+ def teardown_method(self, meth):
36
+ self.conn._SO_update = self._oldUpdate
37
+ del self._oldUpdate
38
+
39
+ def _alternateUpdate(self, so, values, conn, oldUpdate):
40
+ conn.didUpdate = True
41
+ return oldUpdate(so, values)
42
+
43
+ def test_lazy(self):
44
+ assert not self.conn.didUpdate
45
+ obj = Lazy(name='tim')
46
+ # We just did an insert, but not an update:
47
+ assert not self.conn.didUpdate
48
+ obj.set(name='joe')
49
+ assert obj.sqlmeta.dirty
50
+ assert obj.name == 'joe'
51
+ assert not self.conn.didUpdate
52
+ obj.syncUpdate()
53
+ assert obj.name == 'joe'
54
+ assert self.conn.didUpdate
55
+ assert not obj.sqlmeta.dirty
56
+ assert obj.name == 'joe'
57
+ self.conn.didUpdate = False
58
+
59
+ obj = Lazy(name='frank')
60
+ obj.name = 'joe'
61
+ assert not self.conn.didUpdate
62
+ assert obj.sqlmeta.dirty
63
+ assert obj.name == 'joe'
64
+ obj.name = 'joe2'
65
+ assert not self.conn.didUpdate
66
+ assert obj.sqlmeta.dirty
67
+ assert obj.name == 'joe2'
68
+ obj.syncUpdate()
69
+ assert obj.name == 'joe2'
70
+ assert not obj.sqlmeta.dirty
71
+ assert self.conn.didUpdate
72
+ self.conn.didUpdate = False
73
+
74
+ obj = Lazy(name='loaded')
75
+ assert not obj.sqlmeta.dirty
76
+ assert not self.conn.didUpdate
77
+ assert obj.name == 'loaded'
78
+ obj.name = 'unloaded'
79
+ assert obj.sqlmeta.dirty
80
+ assert obj.name == 'unloaded'
81
+ assert not self.conn.didUpdate
82
+ obj.sync()
83
+ assert not obj.sqlmeta.dirty
84
+ assert obj.name == 'unloaded'
85
+ assert self.conn.didUpdate
86
+ self.conn.didUpdate = False
87
+ obj.name = 'whatever'
88
+ assert obj.sqlmeta.dirty
89
+ assert obj.name == 'whatever'
90
+ assert not self.conn.didUpdate
91
+ obj._SO_loadValue('name')
92
+ assert obj.sqlmeta.dirty
93
+ assert obj.name == 'whatever'
94
+ assert not self.conn.didUpdate
95
+ obj._SO_loadValue('other')
96
+ assert obj.name == 'whatever'
97
+ assert not self.conn.didUpdate
98
+ obj.syncUpdate()
99
+ assert self.conn.didUpdate
100
+ self.conn.didUpdate = False
101
+
102
+ # Now, check that get() doesn't screw
103
+ # cached objects' validator state.
104
+ obj_id = obj.id
105
+ old_state = obj._SO_validatorState
106
+ obj = Lazy.get(obj_id)
107
+ assert not obj.sqlmeta.dirty
108
+ assert not self.conn.didUpdate
109
+ assert obj._SO_validatorState is old_state
110
+ assert obj.name == 'whatever'
111
+ obj.name = 'unloaded'
112
+ assert obj.name == 'unloaded'
113
+ assert obj.sqlmeta.dirty
114
+ assert not self.conn.didUpdate
115
+ # Fetch the object again with get() and
116
+ # make sure sqlmeta.dirty is still set, as the
117
+ # object should come from the cache.
118
+ obj = Lazy.get(obj_id)
119
+ assert obj.sqlmeta.dirty
120
+ assert not self.conn.didUpdate
121
+ assert obj.name == 'unloaded'
122
+ obj.syncUpdate()
123
+ assert self.conn.didUpdate
124
+ assert not obj.sqlmeta.dirty
125
+ self.conn.didUpdate = False
126
+
127
+ # Then clear the cache, and try a get()
128
+ # again, to make sure stuf like _SO_createdValues
129
+ # is properly initialized.
130
+ self.conn.cache.clear()
131
+ obj = Lazy.get(obj_id)
132
+ assert not obj.sqlmeta.dirty
133
+ assert not self.conn.didUpdate
134
+ assert obj.name == 'unloaded'
135
+ obj.name = 'spongebob'
136
+ assert obj.name == 'spongebob'
137
+ assert obj.sqlmeta.dirty
138
+ assert not self.conn.didUpdate
139
+ obj.syncUpdate()
140
+ assert self.conn.didUpdate
141
+ assert not obj.sqlmeta.dirty
142
+ self.conn.didUpdate = False
143
+
144
+ obj = Lazy(name='last')
145
+ assert not obj.sqlmeta.dirty
146
+ obj.syncUpdate()
147
+ assert not self.conn.didUpdate
148
+ assert not obj.sqlmeta.dirty
149
+ # Check that setting multiple values
150
+ # actually works. This was broken
151
+ # and just worked because we were testing
152
+ # only one value at a time, so 'name'
153
+ # had the right value after the for loop *wink*
154
+ # Also, check that passing a name that is not
155
+ # a valid column doesn't break, but instead
156
+ # just does a plain setattr.
157
+ obj.set(name='first', other='who', third='yes')
158
+ assert obj.name == 'first'
159
+ assert obj.other == 'who'
160
+ assert obj.third == 'yes'
161
+ assert obj.sqlmeta.dirty
162
+ assert not self.conn.didUpdate
163
+ obj.syncUpdate()
164
+ assert self.conn.didUpdate
165
+ assert not obj.sqlmeta.dirty
@@ -0,0 +1,13 @@
1
+ from hashlib import md5
2
+
3
+
4
+ ########################################
5
+ # hashlib.md5
6
+ ########################################
7
+
8
+
9
+ def test_md5():
10
+ assert md5(b'').hexdigest() == 'd41d8cd98f00b204e9800998ecf8427e'
11
+ assert md5(b'\n').hexdigest() == '68b329da9893e34099c7d8ad5cb9c940'
12
+ assert md5(b'123').hexdigest() == '202cb962ac59075b964b07152d234b70'
13
+ assert md5(b'123\n').hexdigest() == 'ba1f2511fc30423bdbb183fe33f3dd0f'
@@ -0,0 +1,50 @@
1
+ import pytest
2
+ from sqlobject import SQLObject, IntCol
3
+ from sqlobject.sqlbuilder import Select, ANY
4
+ from sqlobject.tests.dbtest import getConnection, setupClass
5
+
6
+
7
+ try:
8
+ connection = getConnection()
9
+ except (AttributeError, NameError):
10
+ # The module was imported during documentation building
11
+ pass
12
+ else:
13
+ if connection.dbName != "mysql":
14
+ pytestmark = pytest.mark.skip("These tests require MySQL")
15
+
16
+
17
+ class SOTestSOListMySQL(SQLObject):
18
+ pass
19
+
20
+
21
+ def test_list_databases():
22
+ assert connection.db in connection.listDatabases()
23
+
24
+
25
+ def test_list_tables():
26
+ setupClass(SOTestSOListMySQL)
27
+ assert SOTestSOListMySQL.sqlmeta.table in connection.listTables()
28
+
29
+
30
+ class SOTestANY(SQLObject):
31
+ value = IntCol()
32
+
33
+
34
+ def test_ANY():
35
+ setupClass(SOTestANY)
36
+ SOTestANY(value=10)
37
+ SOTestANY(value=20)
38
+ SOTestANY(value=30)
39
+ assert len(list(SOTestANY.select(
40
+ SOTestANY.q.value > ANY(Select([SOTestANY.q.value]))))) == 2
41
+
42
+
43
+ class SOTestMySQLidSize(SQLObject):
44
+ class sqlmeta:
45
+ idSize = 'BIG'
46
+
47
+
48
+ def test_idSize():
49
+ assert 'id BIGINT PRIMARY KEY AUTO_INCREMENT' \
50
+ in SOTestMySQLidSize.createTableSQL(connection=connection)[0]
@@ -0,0 +1,165 @@
1
+ from __future__ import print_function
2
+
3
+ from sqlobject import ForeignKey, ManyToMany, OneToMany, SQLObject, StringCol
4
+ from sqlobject.tests.dbtest import setupClass
5
+
6
+
7
+ ########################################
8
+ # Joins
9
+ ########################################
10
+
11
+
12
+ class PersonJNew(SQLObject):
13
+
14
+ name = StringCol(length=40, alternateID=True)
15
+ addressJs = ManyToMany('AddressJNew')
16
+
17
+
18
+ class AddressJNew(SQLObject):
19
+
20
+ zip = StringCol(length=5, alternateID=True)
21
+ personJs = ManyToMany('PersonJNew')
22
+
23
+
24
+ class ImplicitJoiningSONew(SQLObject):
25
+ foo = ManyToMany('Bar')
26
+
27
+
28
+ class ExplicitJoiningSONew(SQLObject):
29
+ foo = OneToMany('Bar')
30
+
31
+
32
+ class TestJoin:
33
+
34
+ def setup_method(self, meth):
35
+ setupClass(PersonJNew)
36
+ setupClass(AddressJNew)
37
+ for n in ['bob', 'tim', 'jane', 'joe', 'fred', 'barb']:
38
+ PersonJNew(name=n)
39
+ for z in ['11111', '22222', '33333', '44444']:
40
+ AddressJNew(zip=z)
41
+
42
+ def test_join(self):
43
+ b = PersonJNew.byName('bob')
44
+ assert list(b.addressJs) == []
45
+ z = AddressJNew.byZip('11111')
46
+ b.addressJs.add(z)
47
+ self.assertZipsEqual(b.addressJs, ['11111'])
48
+ print(str(z.personJs), repr(z.personJs))
49
+ self.assertNamesEqual(z.personJs, ['bob'])
50
+ z2 = AddressJNew.byZip('22222')
51
+ b.addressJs.add(z2)
52
+ print(str(b.addressJs))
53
+ self.assertZipsEqual(b.addressJs, ['11111', '22222'])
54
+ self.assertNamesEqual(z2.personJs, ['bob'])
55
+ b.addressJs.remove(z)
56
+ self.assertZipsEqual(b.addressJs, ['22222'])
57
+ self.assertNamesEqual(z.personJs, [])
58
+
59
+ def assertZipsEqual(self, zips, dest):
60
+ assert [a.zip for a in zips] == dest
61
+
62
+ def assertNamesEqual(self, people, dest):
63
+ assert [p.name for p in people] == dest
64
+
65
+ def test_joinAttributeWithUnderscores(self):
66
+ # Make sure that the implicit setting of joinMethodName works
67
+ assert hasattr(ImplicitJoiningSONew, 'foo')
68
+ assert not hasattr(ImplicitJoiningSONew, 'bars')
69
+
70
+ # And make sure explicit setting also works
71
+ assert hasattr(ExplicitJoiningSONew, 'foo')
72
+ assert not hasattr(ExplicitJoiningSONew, 'bars')
73
+
74
+
75
+ class PersonJNew2(SQLObject):
76
+
77
+ name = StringCol('name', length=40, alternateID=True)
78
+ addressJ2s = OneToMany('AddressJNew2')
79
+
80
+
81
+ class AddressJNew2(SQLObject):
82
+
83
+ class sqlmeta:
84
+ defaultOrder = ['-zip', 'plus4']
85
+
86
+ zip = StringCol(length=5)
87
+ plus4 = StringCol(length=4, default=None)
88
+ personJNew2 = ForeignKey('PersonJNew2')
89
+
90
+
91
+ class TestJoin2:
92
+
93
+ def setup_method(self, meth):
94
+ setupClass([PersonJNew2, AddressJNew2])
95
+ p1 = PersonJNew2(name='bob')
96
+ p2 = PersonJNew2(name='sally')
97
+ for z in ['11111', '22222', '33333']:
98
+ AddressJNew2(zip=z, personJNew2=p1)
99
+ AddressJNew2(zip='00000', personJNew2=p2)
100
+
101
+ def test_basic(self):
102
+ bob = PersonJNew2.byName('bob')
103
+ sally = PersonJNew2.byName('sally')
104
+ print(bob.addressJ2s)
105
+ print(bob)
106
+ assert len(list(bob.addressJ2s)) == 3
107
+ assert len(list(sally.addressJ2s)) == 1
108
+ bob.addressJ2s[0].destroySelf()
109
+ assert len(list(bob.addressJ2s)) == 2
110
+ z = bob.addressJ2s[0]
111
+ z.zip = 'xxxxx'
112
+ id = z.id
113
+ del z
114
+ z = AddressJNew2.get(id)
115
+ assert z.zip == 'xxxxx'
116
+
117
+ def test_defaultOrder(self):
118
+ p1 = PersonJNew2.byName('bob')
119
+ assert ([i.zip for i in p1.addressJ2s]
120
+ == ['33333', '22222', '11111'])
121
+
122
+
123
+ _personJ3_getters = []
124
+ _personJ3_setters = []
125
+
126
+
127
+ class PersonJNew3(SQLObject):
128
+
129
+ name = StringCol('name', length=40, alternateID=True)
130
+ addressJNew3s = OneToMany('AddressJNew3')
131
+
132
+
133
+ class AddressJNew3(SQLObject):
134
+
135
+ zip = StringCol(length=5)
136
+ personJNew3 = ForeignKey('PersonJNew3')
137
+
138
+ def _get_personJNew3(self):
139
+ value = self._SO_get_personJNew3()
140
+ _personJ3_getters.append((self, value))
141
+ return value
142
+
143
+ def _set_personJNew3(self, value):
144
+ self._SO_set_personJNew3(value)
145
+ _personJ3_setters.append((self, value))
146
+
147
+
148
+ class TestJoin3:
149
+
150
+ def setup_method(self, meth):
151
+ setupClass([PersonJNew3, AddressJNew3])
152
+ p1 = PersonJNew3(name='bob')
153
+ p2 = PersonJNew3(name='sally')
154
+ for z in ['11111', '22222', '33333']:
155
+ AddressJNew3(zip=z, personJNew3=p1)
156
+ AddressJNew3(zip='00000', personJNew3=p2)
157
+
158
+ def test_accessors(self):
159
+ assert len(list(_personJ3_getters)) == 0
160
+ assert len(list(_personJ3_setters)) == 4
161
+ bob = PersonJNew3.byName('bob')
162
+ for addressJ3 in bob.addressJNew3s:
163
+ addressJ3.personJNew3
164
+ assert len(list(_personJ3_getters)) == 3
165
+ assert len(list(_personJ3_setters)) == 4