Package gensaschema :: Module _constraint
[frames] | no frames]

Source Code for Module gensaschema._constraint

  1  # -*- coding: ascii -*- 
  2  r""" 
  3  ========================================== 
  4   Constraint inspection and representation 
  5  ========================================== 
  6   
  7  Constraint inspection and representation. 
  8   
  9  :Copyright: 
 10   
 11   Copyright 2010 - 2016 
 12   Andr\xe9 Malo or his licensors, as applicable 
 13   
 14  :License: 
 15   
 16   Licensed under the Apache License, Version 2.0 (the "License"); 
 17   you may not use this file except in compliance with the License. 
 18   You may obtain a copy of the License at 
 19   
 20       http://www.apache.org/licenses/LICENSE-2.0 
 21   
 22   Unless required by applicable law or agreed to in writing, software 
 23   distributed under the License is distributed on an "AS IS" BASIS, 
 24   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 25   See the License for the specific language governing permissions and 
 26   limitations under the License. 
 27   
 28  """ 
 29  if __doc__:  # pragma: no branch 
 30      # pylint: disable = redefined-builtin 
 31      __doc__ = __doc__.encode('ascii').decode('unicode_escape') 
 32  __author__ = r"Andr\xe9 Malo".encode('ascii').decode('unicode_escape') 
 33  __docformat__ = "restructuredtext en" 
 34   
 35  import keyword as _keyword 
 36  import re as _re 
 37  import tokenize as _tokenize 
 38   
 39  from . import _util 
 40   
 41   
42 -class Constraint(object):
43 """ 44 Reflected Constraint 45 46 :IVariables: 47 `constraint` : SA Constraint 48 Constraint 49 """ 50 _SYMBOL, _IMPORT = None, None 51
52 - def __new__(cls, constraint, table, symbols, options=None):
53 """ Constraint factory """ 54 if cls == Constraint: 55 name = constraint.__class__.__name__ 56 if name == 'CheckConstraint': 57 return None 58 return globals()[name]( 59 constraint, table, symbols, options=options 60 ) 61 return object.__new__(cls)
62
63 - def __init__(self, constraint, table, symbols, options=None):
64 """ 65 Initialization 66 67 :Parameters: 68 `constraint` : SA Constraint 69 Constraint 70 71 `table` : ``str`` 72 Table varname 73 """ 74 self.constraint = constraint 75 self.table = table 76 self._symbols = symbols 77 self._symbols.imports[self._SYMBOL] = self._IMPORT 78 self.options = options
79
80 - def copy(self):
81 """ Create shallow copy """ 82 return self.__class__( 83 self.constraint, self.table, self._symbols, self.options 84 )
85
86 - def __cmp__(self, other):
87 """ Compare """ 88 names = [ 89 'PrimaryKeyConstraint', 'UniqueConstraint', 90 'ForeignKeyConstraint', 'CheckConstraint' 91 ] 92 93 def bytype(const): 94 """ Sort by type """ 95 try: 96 return names.index(const.__class__.__name__) 97 except IndexError: 98 return -1
99 100 return _util.cmp(( 101 bytype(self.constraint), 102 self.options is not None, 103 self.constraint.name, 104 repr(self), 105 ), ( 106 bytype(other.constraint), 107 other.options is not None, 108 other.constraint.name, 109 repr(other), 110 ))
111
112 - def __lt__(self, other, _cmp=__cmp__):
113 """ Check for '<' """ 114 return _cmp(self, other) < 0
115
116 - def repr(self, symbol, args, keywords=(), short=False):
117 """ 118 Base repr for all constraints 119 120 :Parameters: 121 `args` : iterable 122 Positional arguments 123 124 :Return: The constraint repr 125 :Rtype: ``str`` 126 """ 127 # pylint: disable = R0912 128 # (too many branches) 129 130 params = [] 131 if self.constraint.name is not None: 132 params.append('name=%r' % (self.constraint.name,)) 133 if self.constraint.deferrable is not None: 134 params.append('deferrable=%r' % (self.constraint.deferrable,)) 135 if self.constraint.initially is not None: 136 params.append('initially=%r' % (self.constraint.initially,)) 137 for keyword in keywords: 138 if getattr(self.constraint, keyword) is not None: 139 params.append("%s=%r" % ( 140 keyword, getattr(self.constraint, keyword) 141 )) 142 if short and len(params) > 1: 143 short = False 144 if args: 145 if short: 146 args = ', '.join(args) 147 else: 148 args = '\n ' + ',\n '.join(args) + ',' 149 else: 150 args = '' 151 152 if short: 153 params = ', '.join(params) 154 if args and params: 155 params = ', ' + params 156 else: 157 params = ',\n '.join(params) 158 if params: 159 params = '\n ' + params + ',' 160 if args or params: 161 params += '\n' 162 163 return "%s(%s%s)" % (self._symbols[symbol], args, params)
164 165
166 -def access_col(col):
167 """ 168 Generate column access string (either as attribute or via dict access) 169 170 :Parameters: 171 `col` : SA Column 172 Column 173 174 :Return: Access string 175 :Rtype: ``str`` 176 """ 177 try: 178 name = col.name 179 except AttributeError: 180 name = col 181 try: 182 if _util.py2 and isinstance(name, _util.bytes): # pragma: no cover 183 name.decode('ascii') 184 else: 185 name.encode('ascii') 186 except UnicodeError: 187 is_ascii = False 188 else: 189 is_ascii = True 190 if is_ascii and not _keyword.iskeyword(name) and \ 191 _re.match(_tokenize.Name + '$', name): 192 return ".c.%s" % name 193 return ".c[%r]" % name
194 195
196 -class UniqueConstraint(Constraint):
197 """ Unique constraint """ 198 _SYMBOL = 'uk' 199 _IMPORT = 'from %(constraints)s import Unique as %(uk)s' 200
201 - def __repr__(self):
202 """ 203 Make string representation 204 205 :Return: The string representation 206 :Rtype: ``str`` 207 """ 208 empty = len(self.constraint.columns) == 0 209 short = len(self.constraint.columns) <= 1 210 result = self.repr(self._SYMBOL, [ 211 "%s%s" % (self.table, access_col(col)) 212 for col in self.constraint.columns 213 ], short=short) 214 if empty: 215 result = "# %s" % result 216 return result
217 218
219 -class PrimaryKeyConstraint(UniqueConstraint):
220 """ Primary Key constraint """ 221 _SYMBOL = 'pk' 222 _IMPORT = 'from %(constraints)s import PrimaryKey as %(pk)s'
223 224
225 -class ForeignKeyConstraint(Constraint):
226 """ ForeignKey constraint """ 227 _SYMBOL = 'fk' 228 _IMPORT = 'from %(constraints)s import ForeignKey as %(fk)s' 229
230 - def __repr__(self):
231 """ 232 Make string representation 233 234 :Return: The string representation 235 :Rtype: ``str`` 236 """ 237 columns = "[%s]" % ',\n '.join([ 238 "%s%s" % (self.table, access_col(col)) 239 for col in self.constraint.columns 240 ]) 241 refcolumns = "[%s]" % ',\n '.join(["%s%s" % ( 242 self._symbols[u'table_%s' % key.column.table.name], 243 access_col(key.column), 244 ) for key in self.constraint.elements]) 245 keywords = ['onupdate', 'ondelete'] 246 if self.constraint.use_alter: 247 keywords.append('use_alter') 248 result = self.repr('fk', [columns, refcolumns], keywords) 249 250 if self.options: 251 cyclic = self.constraint.use_alter 252 if self.options.startswith('seen:'): 253 table = self.options.split(None, 1)[1] 254 if cyclic: 255 result = '\n# Cyclic foreign key:\n' + result 256 else: 257 result = '\n# Foreign key belongs to %r:\n%s' % ( 258 table, result 259 ) 260 elif self.options.startswith('unseen:'): 261 table = self.options.split(None, 1)[1] 262 result = result.splitlines(True) 263 if cyclic: 264 result.insert( 265 0, 266 'Cyclic foreign key, defined at table %r:\n' % table 267 ) 268 else: 269 result.insert(0, 'Defined at table %r:\n' % table) 270 result = '\n' + ''.join(['# %s' % item for item in result]) 271 272 return result
273