Changeset 73
- Timestamp:
- 04/12/07 00:05:17
- Files:
-
- trunk/geniusql/adapters.py (modified) (1 diff)
- trunk/geniusql/dbtypes.py (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/geniusql/adapters.py
r72 r73 43 43 maxint_bytes = 1 44 44 while True: 45 # Signed values have half the max of unsigned (hence the "-1"). 45 46 if sys.maxint <= 2 ** ((maxint_bytes * 8) - 1): 46 47 break trunk/geniusql/dbtypes.py
r72 r73 3 3 4 4 import datetime 5 import math 5 6 6 7 from geniusql import adapters, errors, typerefs … … 324 325 """Base class for SQL 92 REAL types.""" 325 326 default_pytype = float 327 # By "precision" here, we mean the number of binary digits 328 # which can be safely round-tripped to the DB and back. 329 # Even though almost every DB will use 32 bits to represent this 330 # number (1 sign bit, 8 exponent bits, and 24 significand bits), 331 # we're only interested in the significand bits; therefore, the 332 # max() for this type should be (2 ** 24) - 1. 333 # See http://babbage.cs.qc.edu/IEEE-754/Decimal.html 326 334 _precision = max_precision = 24 327 335 default_adapters = {float: adapters.float_to_SQL92REAL()} … … 480 488 that merely looks up synonyms, database types MUST be 481 489 canonicalized for all Column and SQLExpression objects. 490 491 Note that the caller is responsible to strip out any metadata from 492 the supplied type name; for example, "NUMERIC(18, 2)" should 493 (usually) be reduced to "NUMERIC" before calling this function. 494 However, this is not mandatory; some providers may need to use 495 such metadata to select the most appropriate type. 482 496 """ 483 497 for typeset in self.known_types.itervalues(): … … 493 507 hints: if provided, this should be a dict of property attributes 494 508 which can be used to distinguish between similar database types. 495 Canonical keys include 'bytes', 'precision', and 'scale'. 509 Canonical keys include 'bytes', 'precision', 'scale', 510 and 'signed'. 496 511 """ 497 512 xform = "dbtype_for_" + getCoerceName(pytype) … … 507 522 def dbtype_for_float(self, hints): 508 523 """Return a DatabaseType for floats of the given binary precision.""" 509 # Note that 'precision' is binary digits, not decimal. 524 # Note that 'precision' is binary digits, not decimal digits or bytes. 525 # FOr example, most DOUBLE PRECISION types are implemented as 526 # 64 bits ~= 53 binary precision ~= 14 decimal precision 510 527 precision = int(hints.get('precision', adapters.maxfloat_digits)) 511 528 if precision == 0: … … 618 635 619 636 def dbtype_for_long(self, hints): 637 # Assume most people want signed numbers. 638 signed = hints.get('signed', True) 639 620 640 if 'bytes' in hints: 621 641 bytes = int(hints['bytes']) 622 else: 623 bytes = self.numeric_max_precision() / 2 642 maxprec = int(math.ceil(math.log(2 ** (bytes * 8), 10))) 643 else: 644 maxprec = self.numeric_max_precision() 645 bytes = int(math.ceil(math.log(10 ** maxprec, 2) / 8)) 624 646 625 647 for dbtype in self.known_types['int']: 626 if bytes <= dbtype.max_bytes :648 if bytes <= dbtype.max_bytes and signed == dbtype.signed: 627 649 return dbtype(bytes=bytes) 628 return self.decimal_type(precision=bytes * 2, scale=0) 650 651 return self.decimal_type(precision=maxprec, scale=0) 629 652 630 653 def dbtype_for_int(self, hints): 654 # Assume most people want signed numbers; maxint_bytes assumes it. 655 signed = hints.get('signed', True) 631 656 bytes = int(hints.get('bytes', adapters.maxint_bytes)) 657 632 658 for dbtype in self.known_types['int']: 633 if bytes <= dbtype.max_bytes :659 if bytes <= dbtype.max_bytes and signed == dbtype.signed: 634 660 return dbtype(bytes=bytes) 635 return self.decimal_type(precision=bytes * 2, scale=0) 636 661 662 maxprec = int(math.ceil(math.log(2 ** (bytes * 8), 10))) 663 return self.decimal_type(precision=maxprec, scale=0) 664
