##// END OF EJS Templates
requirements: fixed pycrypto backport and sqlalchemy <2.0
super-admin -
r4918:dbcd47ca default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,267 +1,268 b''
1 # deps, generated via pipdeptree --exclude setuptools,wheel,pipdeptree,pip -f | tr '[:upper:]' '[:lower:]'
1 # deps, generated via pipdeptree --exclude setuptools,wheel,pipdeptree,pip -f | tr '[:upper:]' '[:lower:]'
2
2
3 alembic==1.10.0
3 alembic==1.10.0
4 mako==1.2.4
4 mako==1.2.4
5 markupsafe==2.1.2
5 markupsafe==2.1.2
6 sqlalchemy==2.0.5.post1
6 sqlalchemy==1.4.46
7 greenlet==2.0.2
7 greenlet==2.0.2
8 typing_extensions==4.5.0
8 typing_extensions==4.5.0
9 typing_extensions==4.5.0
9 typing_extensions==4.5.0
10 babel==2.12.1
10 babel==2.12.1
11 celery==5.2.7
11 celery==5.2.7
12 billiard==3.6.4.0
12 billiard==3.6.4.0
13 click==8.1.3
13 click==8.1.3
14 click-didyoumean==0.3.0
14 click-didyoumean==0.3.0
15 click==8.1.3
15 click==8.1.3
16 click-plugins==1.1.1
16 click-plugins==1.1.1
17 click==8.1.3
17 click==8.1.3
18 click-repl==0.2.0
18 click-repl==0.2.0
19 click==8.1.3
19 click==8.1.3
20 prompt-toolkit==3.0.38
20 prompt-toolkit==3.0.38
21 wcwidth==0.2.6
21 wcwidth==0.2.6
22 six==1.16.0
22 six==1.16.0
23 kombu==5.2.4
23 kombu==5.2.4
24 amqp==5.1.1
24 amqp==5.1.1
25 vine==5.0.0
25 vine==5.0.0
26 vine==5.0.0
26 vine==5.0.0
27 pytz==2022.7.1
27 pytz==2022.7.1
28 vine==5.0.0
28 vine==5.0.0
29 channelstream==0.7.1
29 channelstream==0.7.1
30 gevent==22.10.2
30 gevent==22.10.2
31 greenlet==2.0.2
31 greenlet==2.0.2
32 zope.event==4.6
32 zope.event==4.6
33 zope.interface==5.5.2
33 zope.interface==5.5.2
34 itsdangerous==1.1.0
34 itsdangerous==1.1.0
35 marshmallow==2.18.0
35 marshmallow==2.18.0
36 pyramid==2.0.1
36 pyramid==2.0.1
37 hupper==1.11
37 hupper==1.11
38 plaster==1.1.2
38 plaster==1.1.2
39 plaster-pastedeploy==1.0.1
39 plaster-pastedeploy==1.0.1
40 pastedeploy==3.0.1
40 pastedeploy==3.0.1
41 plaster==1.1.2
41 plaster==1.1.2
42 translationstring==1.4
42 translationstring==1.4
43 venusian==3.0.0
43 venusian==3.0.0
44 webob==1.8.7
44 webob==1.8.7
45 zope.deprecation==4.4.0
45 zope.deprecation==4.4.0
46 zope.interface==5.5.2
46 zope.interface==5.5.2
47 pyramid-apispec==0.3.3
47 pyramid-apispec==0.3.3
48 apispec==1.3.3
48 apispec==1.3.3
49 pyramid-jinja2==2.10
49 pyramid-jinja2==2.10
50 jinja2==3.1.2
50 jinja2==3.1.2
51 markupsafe==2.1.2
51 markupsafe==2.1.2
52 markupsafe==2.1.2
52 markupsafe==2.1.2
53 pyramid==2.0.1
53 pyramid==2.0.1
54 hupper==1.11
54 hupper==1.11
55 plaster==1.1.2
55 plaster==1.1.2
56 plaster-pastedeploy==1.0.1
56 plaster-pastedeploy==1.0.1
57 pastedeploy==3.0.1
57 pastedeploy==3.0.1
58 plaster==1.1.2
58 plaster==1.1.2
59 translationstring==1.4
59 translationstring==1.4
60 venusian==3.0.0
60 venusian==3.0.0
61 webob==1.8.7
61 webob==1.8.7
62 zope.deprecation==4.4.0
62 zope.deprecation==4.4.0
63 zope.interface==5.5.2
63 zope.interface==5.5.2
64 zope.deprecation==4.4.0
64 zope.deprecation==4.4.0
65 python-dateutil==2.8.2
65 python-dateutil==2.8.2
66 six==1.16.0
66 six==1.16.0
67 requests==2.28.2
67 requests==2.28.2
68 certifi==2022.12.7
68 certifi==2022.12.7
69 charset-normalizer==3.1.0
69 charset-normalizer==3.1.0
70 idna==3.4
70 idna==3.4
71 urllib3==1.26.14
71 urllib3==1.26.14
72 ws4py==0.5.1
72 ws4py==0.5.1
73 configobj==5.0.8
73 configobj==5.0.8
74 six==1.16.0
74 six==1.16.0
75 deform==2.0.15
75 deform==2.0.15
76 chameleon==3.10.2
76 chameleon==3.10.2
77 colander==2.0
77 colander==2.0
78 iso8601==1.1.0
78 iso8601==1.1.0
79 translationstring==1.4
79 translationstring==1.4
80 iso8601==1.1.0
80 iso8601==1.1.0
81 peppercorn==0.6
81 peppercorn==0.6
82 translationstring==1.4
82 translationstring==1.4
83 zope.deprecation==4.4.0
83 zope.deprecation==4.4.0
84 docutils==0.19
84 docutils==0.19
85 dogpile.cache==1.1.8
85 dogpile.cache==1.1.8
86 decorator==5.1.1
86 decorator==5.1.1
87 stevedore==5.0.0
87 stevedore==5.0.0
88 pbr==5.11.1
88 pbr==5.11.1
89 formencode==2.0.1
89 formencode==2.0.1
90 six==1.16.0
90 six==1.16.0
91 gunicorn==20.1.0
91 gunicorn==20.1.0
92 infrae.cache==1.0.1
92 infrae.cache==1.0.1
93 beaker==1.12.1
93 beaker==1.12.1
94 repoze.lru==0.7
94 repoze.lru==0.7
95 msgpack-python==0.5.6
95 msgpack-python==0.5.6
96 mysqlclient==2.1.1
96 mysqlclient==2.1.1
97 nbconvert==7.2.9
97 nbconvert==7.2.9
98 beautifulsoup4==4.11.2
98 beautifulsoup4==4.11.2
99 soupsieve==2.4
99 soupsieve==2.4
100 bleach==6.0.0
100 bleach==6.0.0
101 six==1.16.0
101 six==1.16.0
102 webencodings==0.5.1
102 webencodings==0.5.1
103 defusedxml==0.7.1
103 defusedxml==0.7.1
104 jinja2==3.1.2
104 jinja2==3.1.2
105 markupsafe==2.1.2
105 markupsafe==2.1.2
106 jupyter_core==5.2.0
106 jupyter_core==5.2.0
107 platformdirs==3.1.0
107 platformdirs==3.1.0
108 traitlets==5.9.0
108 traitlets==5.9.0
109 jupyterlab-pygments==0.2.2
109 jupyterlab-pygments==0.2.2
110 markupsafe==2.1.2
110 markupsafe==2.1.2
111 mistune==2.0.5
111 mistune==2.0.5
112 nbclient==0.7.2
112 nbclient==0.7.2
113 jupyter_client==8.0.3
113 jupyter_client==8.0.3
114 jupyter_core==5.2.0
114 jupyter_core==5.2.0
115 platformdirs==3.1.0
115 platformdirs==3.1.0
116 traitlets==5.9.0
116 traitlets==5.9.0
117 python-dateutil==2.8.2
117 python-dateutil==2.8.2
118 six==1.16.0
118 six==1.16.0
119 pyzmq==25.0.0
119 pyzmq==25.0.0
120 tornado==6.2
120 tornado==6.2
121 traitlets==5.9.0
121 traitlets==5.9.0
122 jupyter_core==5.2.0
122 jupyter_core==5.2.0
123 platformdirs==3.1.0
123 platformdirs==3.1.0
124 traitlets==5.9.0
124 traitlets==5.9.0
125 nbformat==5.7.3
125 nbformat==5.7.3
126 fastjsonschema==2.16.3
126 fastjsonschema==2.16.3
127 jsonschema==4.17.3
127 jsonschema==4.17.3
128 attrs==22.2.0
128 attrs==22.2.0
129 pyrsistent==0.19.3
129 pyrsistent==0.19.3
130 jupyter_core==5.2.0
130 jupyter_core==5.2.0
131 platformdirs==3.1.0
131 platformdirs==3.1.0
132 traitlets==5.9.0
132 traitlets==5.9.0
133 traitlets==5.9.0
133 traitlets==5.9.0
134 traitlets==5.9.0
134 traitlets==5.9.0
135 nbformat==5.7.3
135 nbformat==5.7.3
136 fastjsonschema==2.16.3
136 fastjsonschema==2.16.3
137 jsonschema==4.17.3
137 jsonschema==4.17.3
138 attrs==22.2.0
138 attrs==22.2.0
139 pyrsistent==0.19.3
139 pyrsistent==0.19.3
140 jupyter_core==5.2.0
140 jupyter_core==5.2.0
141 platformdirs==3.1.0
141 platformdirs==3.1.0
142 traitlets==5.9.0
142 traitlets==5.9.0
143 traitlets==5.9.0
143 traitlets==5.9.0
144 packaging==23.0
144 packaging==23.0
145 pandocfilters==1.5.0
145 pandocfilters==1.5.0
146 pygments==2.14.0
146 pygments==2.14.0
147 tinycss2==1.2.1
147 tinycss2==1.2.1
148 webencodings==0.5.1
148 webencodings==0.5.1
149 traitlets==5.9.0
149 traitlets==5.9.0
150 pastescript==3.3.0
150 pastescript==3.3.0
151 paste==3.5.2
151 paste==3.5.2
152 six==1.16.0
152 six==1.16.0
153 pastedeploy==3.0.1
153 pastedeploy==3.0.1
154 six==1.16.0
154 six==1.16.0
155 pathlib2==2.3.7.post1
155 pathlib2==2.3.7.post1
156 six==1.16.0
156 six==1.16.0
157 premailer==3.10.0
157 premailer==3.10.0
158 cachetools==5.3.0
158 cachetools==5.3.0
159 cssselect==1.2.0
159 cssselect==1.2.0
160 cssutils==2.6.0
160 cssutils==2.6.0
161 lxml==4.9.2
161 lxml==4.9.2
162 requests==2.28.2
162 requests==2.28.2
163 certifi==2022.12.7
163 certifi==2022.12.7
164 charset-normalizer==3.1.0
164 charset-normalizer==3.1.0
165 idna==3.4
165 idna==3.4
166 urllib3==1.26.14
166 urllib3==1.26.14
167 psutil==5.9.4
167 psutil==5.9.4
168 psycopg2==2.9.5
168 psycopg2==2.9.5
169 py-bcrypt==0.4
169 py-bcrypt==0.4
170 py-gfm==2.0.0
170 py-gfm==2.0.0
171 markdown==3.4.1
171 markdown==3.4.1
172 pycurl==7.45.2
172 pycurl==7.45.2
173 pycryptodome==3.17
173 pymysql==1.0.2
174 pymysql==1.0.2
174 pyotp==2.8.0
175 pyotp==2.8.0
175 pyparsing==3.0.9
176 pyparsing==3.0.9
176 pyramid-debugtoolbar==4.10
177 pyramid-debugtoolbar==4.10
177 pygments==2.14.0
178 pygments==2.14.0
178 pyramid==2.0.1
179 pyramid==2.0.1
179 hupper==1.11
180 hupper==1.11
180 plaster==1.1.2
181 plaster==1.1.2
181 plaster-pastedeploy==1.0.1
182 plaster-pastedeploy==1.0.1
182 pastedeploy==3.0.1
183 pastedeploy==3.0.1
183 plaster==1.1.2
184 plaster==1.1.2
184 translationstring==1.4
185 translationstring==1.4
185 venusian==3.0.0
186 venusian==3.0.0
186 webob==1.8.7
187 webob==1.8.7
187 zope.deprecation==4.4.0
188 zope.deprecation==4.4.0
188 zope.interface==5.5.2
189 zope.interface==5.5.2
189 pyramid-mako==1.1.0
190 pyramid-mako==1.1.0
190 mako==1.2.4
191 mako==1.2.4
191 markupsafe==2.1.2
192 markupsafe==2.1.2
192 pyramid==2.0.1
193 pyramid==2.0.1
193 hupper==1.11
194 hupper==1.11
194 plaster==1.1.2
195 plaster==1.1.2
195 plaster-pastedeploy==1.0.1
196 plaster-pastedeploy==1.0.1
196 pastedeploy==3.0.1
197 pastedeploy==3.0.1
197 plaster==1.1.2
198 plaster==1.1.2
198 translationstring==1.4
199 translationstring==1.4
199 venusian==3.0.0
200 venusian==3.0.0
200 webob==1.8.7
201 webob==1.8.7
201 zope.deprecation==4.4.0
202 zope.deprecation==4.4.0
202 zope.interface==5.5.2
203 zope.interface==5.5.2
203 pyramid-mailer==0.15.1
204 pyramid-mailer==0.15.1
204 pyramid==2.0.1
205 pyramid==2.0.1
205 hupper==1.11
206 hupper==1.11
206 plaster==1.1.2
207 plaster==1.1.2
207 plaster-pastedeploy==1.0.1
208 plaster-pastedeploy==1.0.1
208 pastedeploy==3.0.1
209 pastedeploy==3.0.1
209 plaster==1.1.2
210 plaster==1.1.2
210 translationstring==1.4
211 translationstring==1.4
211 venusian==3.0.0
212 venusian==3.0.0
212 webob==1.8.7
213 webob==1.8.7
213 zope.deprecation==4.4.0
214 zope.deprecation==4.4.0
214 zope.interface==5.5.2
215 zope.interface==5.5.2
215 repoze.sendmail==4.4.1
216 repoze.sendmail==4.4.1
216 transaction==3.0.1
217 transaction==3.0.1
217 zope.interface==5.5.2
218 zope.interface==5.5.2
218 zope.interface==5.5.2
219 zope.interface==5.5.2
219 transaction==3.0.1
220 transaction==3.0.1
220 zope.interface==5.5.2
221 zope.interface==5.5.2
221 python-ldap==3.4.3
222 python-ldap==3.4.3
222 pyasn1==0.4.8
223 pyasn1==0.4.8
223 pyasn1-modules==0.2.8
224 pyasn1-modules==0.2.8
224 pyasn1==0.4.8
225 pyasn1==0.4.8
225 python-memcached==1.59
226 python-memcached==1.59
226 six==1.16.0
227 six==1.16.0
227 python-pam==2.0.2
228 python-pam==2.0.2
228 python3-saml==1.15.0
229 python3-saml==1.15.0
229 isodate==0.6.1
230 isodate==0.6.1
230 six==1.16.0
231 six==1.16.0
231 lxml==4.9.2
232 lxml==4.9.2
232 xmlsec==1.3.13
233 xmlsec==1.3.13
233 lxml==4.9.2
234 lxml==4.9.2
234 pyyaml==6.0
235 pyyaml==6.0
235 redis==4.5.1
236 redis==4.5.1
236 async-timeout==4.0.2
237 async-timeout==4.0.2
237 regex==2022.10.31
238 regex==2022.10.31
238 routes==2.5.1
239 routes==2.5.1
239 repoze.lru==0.7
240 repoze.lru==0.7
240 six==1.16.0
241 six==1.16.0
241 simplejson==3.18.3
242 simplejson==3.18.3
242 sshpubkeys==3.3.1
243 sshpubkeys==3.3.1
243 cryptography==39.0.2
244 cryptography==39.0.2
244 cffi==1.15.1
245 cffi==1.15.1
245 pycparser==2.21
246 pycparser==2.21
246 ecdsa==0.18.0
247 ecdsa==0.18.0
247 six==1.16.0
248 six==1.16.0
248 supervisor==4.2.5
249 supervisor==4.2.5
249 tzlocal==4.2
250 tzlocal==4.2
250 pytz-deprecation-shim==0.1.0.post0
251 pytz-deprecation-shim==0.1.0.post0
251 tzdata==2022.7
252 tzdata==2022.7
252 urlobject==2.4.3
253 urlobject==2.4.3
253 waitress==2.1.2
254 waitress==2.1.2
254 weberror==0.13.1
255 weberror==0.13.1
255 paste==3.5.2
256 paste==3.5.2
256 six==1.16.0
257 six==1.16.0
257 pygments==2.14.0
258 pygments==2.14.0
258 tempita==0.5.2
259 tempita==0.5.2
259 webob==1.8.7
260 webob==1.8.7
260 webhelpers2==2.0
261 webhelpers2==2.0
261 markupsafe==2.1.2
262 markupsafe==2.1.2
262 six==1.16.0
263 six==1.16.0
263 whoosh==2.7.4
264 whoosh==2.7.4
264 zope.cachedescriptors==4.4
265 zope.cachedescriptors==4.4
265
266
266 ## uncomment to add the debug libraries
267 ## uncomment to add the debug libraries
267 #-r requirements_debug.txt
268 #-r requirements_debug.txt
@@ -1,279 +1,279 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2020 RhodeCode GmbH
3 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import collections
21 import collections
22
22
23 import sqlalchemy
23 import sqlalchemy
24 from sqlalchemy import UnicodeText
24 from sqlalchemy import UnicodeText
25 from sqlalchemy.ext.mutable import Mutable
25 from sqlalchemy.ext.mutable import Mutable
26
26
27 from rhodecode.lib.ext_json import json
27 from rhodecode.lib.ext_json import json
28 from rhodecode.lib.utils2 import safe_unicode
28 from rhodecode.lib.utils2 import safe_unicode
29
29
30
30
31 class JsonRaw(unicode):
31 class JsonRaw(str):
32 """
32 """
33 Allows interacting with a JSON types field using a raw string.
33 Allows interacting with a JSON types field using a raw string.
34
34
35 For example::
35 For example::
36 db_instance = JsonTable()
36 db_instance = JsonTable()
37 db_instance.enabled = True
37 db_instance.enabled = True
38 db_instance.json_data = JsonRaw('{"a": 4}')
38 db_instance.json_data = JsonRaw('{"a": 4}')
39
39
40 This will bypass serialization/checks, and allow storing
40 This will bypass serialization/checks, and allow storing
41 raw values
41 raw values
42 """
42 """
43 pass
43 pass
44
44
45
45
46 # Set this to the standard dict if Order is not required
46 # Set this to the standard dict if Order is not required
47 DictClass = collections.OrderedDict
47 DictClass = collections.OrderedDict
48
48
49
49
50 class JSONEncodedObj(sqlalchemy.types.TypeDecorator):
50 class JSONEncodedObj(sqlalchemy.types.TypeDecorator):
51 """
51 """
52 Represents an immutable structure as a json-encoded string.
52 Represents an immutable structure as a json-encoded string.
53
53
54 If default is, for example, a dict, then a NULL value in the
54 If default is, for example, a dict, then a NULL value in the
55 database will be exposed as an empty dict.
55 database will be exposed as an empty dict.
56 """
56 """
57
57
58 impl = UnicodeText
58 impl = UnicodeText
59 safe = True
59 safe = True
60 enforce_unicode = True
60 enforce_unicode = True
61
61
62 def __init__(self, *args, **kwargs):
62 def __init__(self, *args, **kwargs):
63 self.default = kwargs.pop('default', None)
63 self.default = kwargs.pop('default', None)
64 self.safe = kwargs.pop('safe_json', self.safe)
64 self.safe = kwargs.pop('safe_json', self.safe)
65 self.enforce_unicode = kwargs.pop('enforce_unicode', self.enforce_unicode)
65 self.enforce_unicode = kwargs.pop('enforce_unicode', self.enforce_unicode)
66 self.dialect_map = kwargs.pop('dialect_map', {})
66 self.dialect_map = kwargs.pop('dialect_map', {})
67 super(JSONEncodedObj, self).__init__(*args, **kwargs)
67 super(JSONEncodedObj, self).__init__(*args, **kwargs)
68
68
69 def load_dialect_impl(self, dialect):
69 def load_dialect_impl(self, dialect):
70 if dialect.name in self.dialect_map:
70 if dialect.name in self.dialect_map:
71 return dialect.type_descriptor(self.dialect_map[dialect.name])
71 return dialect.type_descriptor(self.dialect_map[dialect.name])
72 return dialect.type_descriptor(self.impl)
72 return dialect.type_descriptor(self.impl)
73
73
74 def process_bind_param(self, value, dialect):
74 def process_bind_param(self, value, dialect):
75 if isinstance(value, JsonRaw):
75 if isinstance(value, JsonRaw):
76 value = value
76 value = value
77 elif value is not None:
77 elif value is not None:
78 value = json.dumps(value)
78 value = json.dumps(value)
79 if self.enforce_unicode:
79 if self.enforce_unicode:
80 value = safe_unicode(value)
80 value = safe_unicode(value)
81 return value
81 return value
82
82
83 def process_result_value(self, value, dialect):
83 def process_result_value(self, value, dialect):
84 if self.default is not None and (not value or value == '""'):
84 if self.default is not None and (not value or value == '""'):
85 return self.default()
85 return self.default()
86
86
87 if value is not None:
87 if value is not None:
88 try:
88 try:
89 value = json.loads(value, object_pairs_hook=DictClass)
89 value = json.loads(value, object_pairs_hook=DictClass)
90 except Exception as e:
90 except Exception as e:
91 if self.safe and self.default is not None:
91 if self.safe and self.default is not None:
92 return self.default()
92 return self.default()
93 else:
93 else:
94 raise
94 raise
95 return value
95 return value
96
96
97
97
98 class MutationObj(Mutable):
98 class MutationObj(Mutable):
99 @classmethod
99 @classmethod
100 def coerce(cls, key, value):
100 def coerce(cls, key, value):
101 if isinstance(value, dict) and not isinstance(value, MutationDict):
101 if isinstance(value, dict) and not isinstance(value, MutationDict):
102 return MutationDict.coerce(key, value)
102 return MutationDict.coerce(key, value)
103 if isinstance(value, list) and not isinstance(value, MutationList):
103 if isinstance(value, list) and not isinstance(value, MutationList):
104 return MutationList.coerce(key, value)
104 return MutationList.coerce(key, value)
105 return value
105 return value
106
106
107 def de_coerce(self):
107 def de_coerce(self):
108 return self
108 return self
109
109
110 @classmethod
110 @classmethod
111 def _listen_on_attribute(cls, attribute, coerce, parent_cls):
111 def _listen_on_attribute(cls, attribute, coerce, parent_cls):
112 key = attribute.key
112 key = attribute.key
113 if parent_cls is not attribute.class_:
113 if parent_cls is not attribute.class_:
114 return
114 return
115
115
116 # rely on "propagate" here
116 # rely on "propagate" here
117 parent_cls = attribute.class_
117 parent_cls = attribute.class_
118
118
119 def load(state, *args):
119 def load(state, *args):
120 val = state.dict.get(key, None)
120 val = state.dict.get(key, None)
121 if coerce:
121 if coerce:
122 val = cls.coerce(key, val)
122 val = cls.coerce(key, val)
123 state.dict[key] = val
123 state.dict[key] = val
124 if isinstance(val, cls):
124 if isinstance(val, cls):
125 val._parents[state.obj()] = key
125 val._parents[state.obj()] = key
126
126
127 def set(target, value, oldvalue, initiator):
127 def set(target, value, oldvalue, initiator):
128 if not isinstance(value, cls):
128 if not isinstance(value, cls):
129 value = cls.coerce(key, value)
129 value = cls.coerce(key, value)
130 if isinstance(value, cls):
130 if isinstance(value, cls):
131 value._parents[target.obj()] = key
131 value._parents[target.obj()] = key
132 if isinstance(oldvalue, cls):
132 if isinstance(oldvalue, cls):
133 oldvalue._parents.pop(target.obj(), None)
133 oldvalue._parents.pop(target.obj(), None)
134 return value
134 return value
135
135
136 def pickle(state, state_dict):
136 def pickle(state, state_dict):
137 val = state.dict.get(key, None)
137 val = state.dict.get(key, None)
138 if isinstance(val, cls):
138 if isinstance(val, cls):
139 if 'ext.mutable.values' not in state_dict:
139 if 'ext.mutable.values' not in state_dict:
140 state_dict['ext.mutable.values'] = []
140 state_dict['ext.mutable.values'] = []
141 state_dict['ext.mutable.values'].append(val)
141 state_dict['ext.mutable.values'].append(val)
142
142
143 def unpickle(state, state_dict):
143 def unpickle(state, state_dict):
144 if 'ext.mutable.values' in state_dict:
144 if 'ext.mutable.values' in state_dict:
145 for val in state_dict['ext.mutable.values']:
145 for val in state_dict['ext.mutable.values']:
146 val._parents[state.obj()] = key
146 val._parents[state.obj()] = key
147
147
148 sqlalchemy.event.listen(parent_cls, 'load', load, raw=True,
148 sqlalchemy.event.listen(parent_cls, 'load', load, raw=True,
149 propagate=True)
149 propagate=True)
150 sqlalchemy.event.listen(parent_cls, 'refresh', load, raw=True,
150 sqlalchemy.event.listen(parent_cls, 'refresh', load, raw=True,
151 propagate=True)
151 propagate=True)
152 sqlalchemy.event.listen(parent_cls, 'pickle', pickle, raw=True,
152 sqlalchemy.event.listen(parent_cls, 'pickle', pickle, raw=True,
153 propagate=True)
153 propagate=True)
154 sqlalchemy.event.listen(attribute, 'set', set, raw=True, retval=True,
154 sqlalchemy.event.listen(attribute, 'set', set, raw=True, retval=True,
155 propagate=True)
155 propagate=True)
156 sqlalchemy.event.listen(parent_cls, 'unpickle', unpickle, raw=True,
156 sqlalchemy.event.listen(parent_cls, 'unpickle', unpickle, raw=True,
157 propagate=True)
157 propagate=True)
158
158
159
159
160 class MutationDict(MutationObj, DictClass):
160 class MutationDict(MutationObj, DictClass):
161 @classmethod
161 @classmethod
162 def coerce(cls, key, value):
162 def coerce(cls, key, value):
163 """Convert plain dictionary to MutationDict"""
163 """Convert plain dictionary to MutationDict"""
164 self = MutationDict(
164 self = MutationDict(
165 (k, MutationObj.coerce(key, v)) for (k, v) in value.items())
165 (k, MutationObj.coerce(key, v)) for (k, v) in value.items())
166 self._key = key
166 self._key = key
167 return self
167 return self
168
168
169 def de_coerce(self):
169 def de_coerce(self):
170 return dict(self)
170 return dict(self)
171
171
172 def __setitem__(self, key, value):
172 def __setitem__(self, key, value):
173 # Due to the way OrderedDict works, this is called during __init__.
173 # Due to the way OrderedDict works, this is called during __init__.
174 # At this time we don't have a key set, but what is more, the value
174 # At this time we don't have a key set, but what is more, the value
175 # being set has already been coerced. So special case this and skip.
175 # being set has already been coerced. So special case this and skip.
176 if hasattr(self, '_key'):
176 if hasattr(self, '_key'):
177 value = MutationObj.coerce(self._key, value)
177 value = MutationObj.coerce(self._key, value)
178 DictClass.__setitem__(self, key, value)
178 DictClass.__setitem__(self, key, value)
179 self.changed()
179 self.changed()
180
180
181 def __delitem__(self, key):
181 def __delitem__(self, key):
182 DictClass.__delitem__(self, key)
182 DictClass.__delitem__(self, key)
183 self.changed()
183 self.changed()
184
184
185 def __setstate__(self, state):
185 def __setstate__(self, state):
186 self.__dict__ = state
186 self.__dict__ = state
187
187
188 def __reduce_ex__(self, proto):
188 def __reduce_ex__(self, proto):
189 # support pickling of MutationDicts
189 # support pickling of MutationDicts
190 d = dict(self)
190 d = dict(self)
191 return (self.__class__, (d,))
191 return (self.__class__, (d,))
192
192
193
193
194 class MutationList(MutationObj, list):
194 class MutationList(MutationObj, list):
195 @classmethod
195 @classmethod
196 def coerce(cls, key, value):
196 def coerce(cls, key, value):
197 """Convert plain list to MutationList"""
197 """Convert plain list to MutationList"""
198 self = MutationList((MutationObj.coerce(key, v) for v in value))
198 self = MutationList((MutationObj.coerce(key, v) for v in value))
199 self._key = key
199 self._key = key
200 return self
200 return self
201
201
202 def de_coerce(self):
202 def de_coerce(self):
203 return list(self)
203 return list(self)
204
204
205 def __setitem__(self, idx, value):
205 def __setitem__(self, idx, value):
206 list.__setitem__(self, idx, MutationObj.coerce(self._key, value))
206 list.__setitem__(self, idx, MutationObj.coerce(self._key, value))
207 self.changed()
207 self.changed()
208
208
209 def __setslice__(self, start, stop, values):
209 def __setslice__(self, start, stop, values):
210 list.__setslice__(self, start, stop,
210 list.__setslice__(self, start, stop,
211 (MutationObj.coerce(self._key, v) for v in values))
211 (MutationObj.coerce(self._key, v) for v in values))
212 self.changed()
212 self.changed()
213
213
214 def __delitem__(self, idx):
214 def __delitem__(self, idx):
215 list.__delitem__(self, idx)
215 list.__delitem__(self, idx)
216 self.changed()
216 self.changed()
217
217
218 def __delslice__(self, start, stop):
218 def __delslice__(self, start, stop):
219 list.__delslice__(self, start, stop)
219 list.__delslice__(self, start, stop)
220 self.changed()
220 self.changed()
221
221
222 def append(self, value):
222 def append(self, value):
223 list.append(self, MutationObj.coerce(self._key, value))
223 list.append(self, MutationObj.coerce(self._key, value))
224 self.changed()
224 self.changed()
225
225
226 def insert(self, idx, value):
226 def insert(self, idx, value):
227 list.insert(self, idx, MutationObj.coerce(self._key, value))
227 list.insert(self, idx, MutationObj.coerce(self._key, value))
228 self.changed()
228 self.changed()
229
229
230 def extend(self, values):
230 def extend(self, values):
231 list.extend(self, (MutationObj.coerce(self._key, v) for v in values))
231 list.extend(self, (MutationObj.coerce(self._key, v) for v in values))
232 self.changed()
232 self.changed()
233
233
234 def pop(self, *args, **kw):
234 def pop(self, *args, **kw):
235 value = list.pop(self, *args, **kw)
235 value = list.pop(self, *args, **kw)
236 self.changed()
236 self.changed()
237 return value
237 return value
238
238
239 def remove(self, value):
239 def remove(self, value):
240 list.remove(self, value)
240 list.remove(self, value)
241 self.changed()
241 self.changed()
242
242
243
243
244 def JsonType(impl=None, **kwargs):
244 def JsonType(impl=None, **kwargs):
245 """
245 """
246 Helper for using a mutation obj, it allows to use .with_variant easily.
246 Helper for using a mutation obj, it allows to use .with_variant easily.
247 example::
247 example::
248
248
249 settings = Column('settings_json',
249 settings = Column('settings_json',
250 MutationObj.as_mutable(
250 MutationObj.as_mutable(
251 JsonType(dialect_map=dict(mysql=UnicodeText(16384))))
251 JsonType(dialect_map=dict(mysql=UnicodeText(16384))))
252 """
252 """
253
253
254 if impl == 'list':
254 if impl == 'list':
255 return JSONEncodedObj(default=list, **kwargs)
255 return JSONEncodedObj(default=list, **kwargs)
256 elif impl == 'dict':
256 elif impl == 'dict':
257 return JSONEncodedObj(default=DictClass, **kwargs)
257 return JSONEncodedObj(default=DictClass, **kwargs)
258 else:
258 else:
259 return JSONEncodedObj(**kwargs)
259 return JSONEncodedObj(**kwargs)
260
260
261
261
262 JSON = MutationObj.as_mutable(JsonType())
262 JSON = MutationObj.as_mutable(JsonType())
263 """
263 """
264 A type to encode/decode JSON on the fly
264 A type to encode/decode JSON on the fly
265
265
266 sqltype is the string type for the underlying DB column::
266 sqltype is the string type for the underlying DB column::
267
267
268 Column(JSON) (defaults to UnicodeText)
268 Column(JSON) (defaults to UnicodeText)
269 """
269 """
270
270
271 JSONDict = MutationObj.as_mutable(JsonType('dict'))
271 JSONDict = MutationObj.as_mutable(JsonType('dict'))
272 """
272 """
273 A type to encode/decode JSON dictionaries on the fly
273 A type to encode/decode JSON dictionaries on the fly
274 """
274 """
275
275
276 JSONList = MutationObj.as_mutable(JsonType('list'))
276 JSONList = MutationObj.as_mutable(JsonType('list'))
277 """
277 """
278 A type to encode/decode JSON lists` on the fly
278 A type to encode/decode JSON lists` on the fly
279 """
279 """
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,45 +1,45 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2020 RhodeCode GmbH
3 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 SQLAlchemy Metadata and Session object
22 SQLAlchemy Metadata and Session object
23 """
23 """
24
24
25 from sqlalchemy.ext.declarative import declarative_base
25 from sqlalchemy.orm import declarative_base
26 from sqlalchemy.orm import scoped_session, sessionmaker
26 from sqlalchemy.orm import scoped_session, sessionmaker
27
27
28 from rhodecode.lib import caching_query
28 from rhodecode.lib import caching_query
29
29
30 __all__ = ['Base', 'Session']
30 __all__ = ['Base', 'Session']
31
31
32 # scoped_session. Apply our custom CachingQuery class to it,
32 # scoped_session. Apply our custom CachingQuery class to it,
33 # using a callable that will associate the dictionary
33 # using a callable that will associate the dictionary
34 # of regions with the Query.
34 # of regions with the Query.
35 # to use cache use this in query
35 # to use cache use this in query
36 # .options(FromCache("sqlalchemy_cache_type", "cachekey"))
36 # .options(FromCache("sqlalchemy_cache_type", "cachekey"))
37 Session = scoped_session(
37 Session = scoped_session(
38 sessionmaker(
38 sessionmaker(
39 query_cls=caching_query.query_callable(),
39 query_cls=caching_query.query_callable(),
40 expire_on_commit=True,
40 expire_on_commit=True,
41 )
41 )
42 )
42 )
43
43
44 # The declarative Base
44 # The declarative Base
45 Base = declarative_base()
45 Base = declarative_base()
General Comments 0
You need to be logged in to leave comments. Login now