From: Billy G. A. <bal...@us...> - 2002-12-04 07:08:46
|
Update of /cvsroot/pypgsql/pypgsql/pyPgSQL In directory sc8-pr-cvs1:/tmp/cvs-serv14980/pyPgSQL Modified Files: PgSQL.py Log Message: 03DEC2002 bga Fixed various problems with the constructor and the formatting routine. These correct the problems reported by Adam Buraczewski. Index: PgSQL.py =================================================================== RCS file: /cvsroot/pypgsql/pypgsql/pyPgSQL/PgSQL.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** PgSQL.py 1 Dec 2002 22:12:30 -0000 1.25 --- PgSQL.py 4 Dec 2002 07:08:44 -0000 1.26 *************** *** 30,33 **** --- 30,36 ---- # Date Ini Description | # --------- --- ------------------------------------------------------- | + # 03DEC2002 bga - Fixed various problems with the constructor and the | + # formatting routine. These correct the problems re- | + # ported by Adam Buraczewski. | # 01DEC2002 bga - Fixed problems with new __setupTransaction function: | # 1. Made it a method of Connection, not Cursor. | *************** *** 1215,1300 **** self.__p = prec self.__s = scale ! elif type(value) is FloatType: ! _s = repr(value) ! _d = _s.rfind('.') ! _e = _s.rfind('e') ! _exp = 0 ! if (_e >= 0): ! _exp = int(_s[_e+1:]) ! _s = _s[:_e] ! if _exp > 31: ! raise OverflowError, "float too large for PgNumeric" ! if _exp < -31: ! raise OverflowError, "float too small for PgNumeric" ! _s = _s[:_d] + _s[_d+1:] ! if _exp == 0: ! _sc = len(_s) - _d ! elif _exp > 0: ! _s = _s + ("0" * (_exp - len(_s) + 1)) ! _sc = 0 ! else: ! _sc = -_exp + len(_s) - 1 ! self.__v = long(_s) ! self.__p = len(_s) ! if self.__p < _sc: ! self.__p = _sc ! self.__s = _sc ! elif type(value) is StringType: ! _v = value.split() ! if len(_v) == 0 or len(_v) > 1: ! raise ValueError, \ ! "invalid literal for PgNumeric: %s" % value ! _v = _v[0] ! # At this point _v is value with leading and trailing blanks ! # removed. Initalize the precision and scale values. They will be ! # determined from the input string (value) is prec and scale are ! # None. ! _vs = value.rfind('.') # Get the location of the decimal point. ! # It's used to determine the precision and ! if prec: # scale if they aren't passed in, and to ! self.__p = prec # adjust the input string to match the ! else: # passed in scale. ! self.__p = len(value) ! if _vs >= 0: ! self.__p = self.__p - 1 ! # Calculate the scale of the passed in string. _vs will contain the ! # calulated scale. ! if _vs >= 0: ! _vs = len(value) - _vs - 1 ! else: ! _vs = 0 ! ! if scale: ! self.__s = scale ! else: ! self.__s = _vs ! # Calculate the number of character to add/remove from the end of ! # the input string in order to have it match the given scale. _sd ! # will contain the number of characters to add (>0) or remove (<0). ! _sd = self.__s - _vs ! if _sd == 0: ! pass # No change to value needed. ! elif _sd > 0: ! _v = _v + ('0' * _sd) # Add needed zeros to the end of value ! else: ! _v = _v[:_sd] # Remove excess digits from the end. ! if self.__s: ! _s = _v[:-(self.__s + 1)] + _v[-self.__s:] else: ! _s = _v ! try: ! self.__v = long(_s) except: raise ValueError, \ "invalid literal for PgNumeric: %s" % value elif isinstance(value, PgNumeric): # This is used to "cast" a PgNumeric to the specified precision --- 1218,1319 ---- self.__p = prec self.__s = scale ! elif type(value) in (FloatType, StringType): ! # Get the value to convert as a string. ! # The expected input is in the form of [+|-][d]*[.[d]*][e[d]+] ! # First get the value as a (trimmed) string ! if type(value) is FloatType: ! _v = repr(value) ! else: ! _v = value.split() ! if len(_v) == 0 or len(_v) > 1: ! raise ValueError, \ ! "invalid literal for PgNumeric: %s" % value ! _v = _v[0] ! ! # Save the sign character (if any) and remove from the string ! _sign = '+' ! if _v[0] in ('-', '+'): ! _sign = _v[0] ! _v = _v[1:] ! # Split the remaining string into int part, frac part and exponet ! _d = _v.rfind('.') ! _e = _v.rfind('e') ! _ip = _v[:_d] ! if _e >= 0: ! _fp = _v[_d+1:_e] ! _xp = _v[_e+1:] ! else: ! _fp = _v[_d+1:] ! _xp = '' ! # Check the validity of the input ! if len(_ip) == 0 and len(_fp) == 0: ! raise ValueError, \ ! "invalid literal for PgNumeric: %s" % value ! if len(_xp) > 0: ! try: ! _exp = int(_xp) ! except: ! raise ValueError, \ ! "invalid literal for PgNumeric: %s" % value ! else: ! _exp = 0 ! if _exp > 999: ! raise OverflowError, "value too large for PgNumeric" ! if _exp < -999: ! raise OverflowError, "value too small for PgNumeric" ! # Create the string that will become the base (long) object ! _v = _ip + _fp ! _sc = len(_fp) ! if _exp > 0: ! if _exp > _sc: ! _v = _v + ("0" * (_exp - _sc + 1)) ! _sc = 0 ! else: ! _sc = _sc - _exp else: ! _sc = _sc - _exp ! try: ! self.__v = long(_sign + _v) except: raise ValueError, \ "invalid literal for PgNumeric: %s" % value + + self.__p = len(_v) + if self.__p < _sc: + self.__p = _sc + self.__s = _sc + + # Now adjust for the inputted scale (if any) + if scale is None: + pass + else: + _adj = scale - self.__s + if _adj > 0: + self.__v = self.__v * (10L ** (scale - self.__s)) + elif _adj < 0: + self.__v = self._round(self.__v, -_adj) + + self.__p = self.__p + _adj + self.__s = scale + + # Apply the inputted precision (if any) + if prec is None: + pass + else: + if prec > 1000: + raise ValueError, "precision too large for PgNumeric" + elif self.__p > prec: + raise OverflowError, "value too large for PgNumeric" + else: + self.__p = prec elif isinstance(value, PgNumeric): # This is used to "cast" a PgNumeric to the specified precision *************** *** 1318,1322 **** self.__v = self.__v * (10L ** _ds) elif _ds < 0: ! self.__v = self._round(self.__v, abs(_ds)) if self.__v > (10L ** self.__p): raise OverflowError, "result exceeds precision of %d" % self.__p --- 1337,1341 ---- self.__v = self.__v * (10L ** _ds) elif _ds < 0: ! self.__v = self._round(self.__v, -_ds) if self.__v > (10L ** self.__p): raise OverflowError, "result exceeds precision of %d" % self.__p *************** *** 1324,1327 **** --- 1343,1350 ---- raise TypeError, "value can not be converted to a PgNumeric." + if self.__s > self.__p: + raise ValueError, \ + "scale of %d exceeds precision of %d" % (self.__s, self.__p) + # The value (10L ** self.__s) is used a lot. Save it as a constant # to save a (small) bit of time. *************** *** 1334,1355 **** # Python 1.6 does not. if value is None: ! _v = str(self.__v) else: ! _v = str(value) if _v[-1:] == 'L': _v = _v[:-1] ! # Check to see if the numeric is less than zero and fix string if so. if len(_v) <= self.__s: _v = ("0" * (self.__s - len(_v) + 1)) + _v if self.__s: ! _s = "%s.%s" % (_v[:-(self.__s)], _v[-(self.__s):]) else: ! _s = "%s" % _v return _s def __repr__(self): ! return "<PgNumeric instance - precision: %d scale: %d value: %s" % \ (self.__p, self.__s, self.__fmtNumeric()) --- 1357,1387 ---- # Python 1.6 does not. if value is None: ! _v = self.__v else: ! _v = value ! ! # Check for a negative value and adjust if necessary ! if _v < 0: ! _sign = '-' ! _v = -_v ! else: ! _sign = '' ! _v = str(_v) ! if _v[-1:] == 'L': _v = _v[:-1] ! # Check to see if the numeric is less than one and fix string if so. if len(_v) <= self.__s: _v = ("0" * (self.__s - len(_v) + 1)) + _v if self.__s: ! _s = "%s%s.%s" % (_sign, _v[:-(self.__s)], _v[-(self.__s):]) else: ! _s = "%s%s" % (_sign, _v) return _s def __repr__(self): ! return "<PgNumeric instance - precision: %d scale: %d value: %s>" % \ (self.__p, self.__s, self.__fmtNumeric()) |