Project

General

Profile

« Previous | Next » 

Revision 5577

sql.py: run_query(): Factored exception parsing out into new parse_exception()

View differences:

sql.py
496 496

  
497 497
##### Recoverable querying
498 498

  
499
def parse_exception(db, e, recover=False):
500
    msg = strings.ustr(e.args[0])
501
    msg = re.sub(r'^(?:PL/Python: )?ValueError: ', r'', msg)
502
    
503
    match = re.match(r'^invalid byte sequence for encoding "(.+?)":', msg)
504
    if match:
505
        encoding, = match.groups()
506
        raise EncodingException(encoding, e)
507
    
508
    match = re.match(r'^duplicate key value violates unique constraint "(.+?)"',
509
        msg)
510
    if match:
511
        constraint, = match.groups()
512
        cols = []
513
        cond = None
514
        if recover: # need auto-rollback to run index_cols()
515
            try:
516
                cols = index_cols(db, constraint)
517
                cond = index_cond(db, constraint)
518
            except NotImplementedError: pass
519
        raise DuplicateKeyException(constraint, cond, cols, e)
520
    
521
    match = re.match(r'^null value in column "(.+?)" violates not-null'
522
        r' constraint', msg)
523
    if match:
524
        col, = match.groups()
525
        raise NullValueException('NOT NULL', None, [col], e)
526
    
527
    match = re.match(r'^new row for relation "(.+?)" violates check '
528
        r'constraint "(.+?)"', msg)
529
    if match:
530
        table, constraint = match.groups()
531
        constraint = sql_gen.Col(constraint, table)
532
        cond = None
533
        if recover: # need auto-rollback to run constraint_cond()
534
            try: cond = constraint_cond(db, constraint)
535
            except NotImplementedError: pass
536
        raise CheckException(constraint.to_str(db), cond, [], e)
537
    
538
    match = re.match(r'^(?:invalid input (?:syntax|value)\b.*?'
539
        r'|.+? out of range): "(.+?)"', msg)
540
    if match:
541
        value, = match.groups()
542
        raise InvalidValueException(strings.to_unicode(value), e)
543
    
544
    match = re.match(r'^column "(.+?)" is of type (.+?) but expression '
545
        r'is of type', msg)
546
    if match:
547
        col, type_ = match.groups()
548
        raise MissingCastException(type_, col, e)
549
    
550
    match = re.match(r'^could not determine polymorphic type because '
551
        r'input has type "unknown"', msg)
552
    if match: raise MissingCastException('text', None, e)
553
    
554
    match = re.match(r'^.+? types .+? and .+? cannot be matched', msg)
555
    if match: raise MissingCastException('text', None, e)
556
    
557
    typed_name_re = r'^(\S+) "(.+?)"(?: of relation ".+?")?'
558
    
559
    match = re.match(typed_name_re+r'.*? already exists', msg)
560
    if match:
561
        type_, name = match.groups()
562
        raise DuplicateException(type_, name, e)
563
    
564
    match = re.match(r'more than one (\S+) named ""(.+?)""', msg)
565
    if match:
566
        type_, name = match.groups()
567
        raise DuplicateException(type_, name, e)
568
    
569
    match = re.match(typed_name_re+r' does not exist', msg)
570
    if match:
571
        type_, name = match.groups()
572
        raise DoesNotExistException(type_, name, e)
573
    
574
    raise # no specific exception raised
575

  
499 576
def with_savepoint(db, func): return db.with_savepoint(func)
500 577

  
501 578
def run_query(db, query, recover=None, cacheable=False, log_level=2,
......
515 592
            if recover and not db.is_cached(query):
516 593
                return with_savepoint(db, run)
517 594
            else: return run() # don't need savepoint if cached
518
        except Exception, e:
519
            msg = strings.ustr(e.args[0])
520
            msg = re.sub(r'^(?:PL/Python: )?ValueError: ', r'', msg)
521
            
522
            match = re.match(r'^invalid byte sequence for encoding "(.+?)":',
523
                msg)
524
            if match:
525
                encoding, = match.groups()
526
                raise EncodingException(encoding, e)
527
            
528
            match = re.match(r'^duplicate key value violates unique constraint '
529
                r'"(.+?)"', msg)
530
            if match:
531
                constraint, = match.groups()
532
                cols = []
533
                cond = None
534
                if recover: # need auto-rollback to run index_cols()
535
                    try:
536
                        cols = index_cols(db, constraint)
537
                        cond = index_cond(db, constraint)
538
                    except NotImplementedError: pass
539
                raise DuplicateKeyException(constraint, cond, cols, e)
540
            
541
            match = re.match(r'^null value in column "(.+?)" violates not-null'
542
                r' constraint', msg)
543
            if match:
544
                col, = match.groups()
545
                raise NullValueException('NOT NULL', None, [col], e)
546
            
547
            match = re.match(r'^new row for relation "(.+?)" violates check '
548
                r'constraint "(.+?)"', msg)
549
            if match:
550
                table, constraint = match.groups()
551
                constraint = sql_gen.Col(constraint, table)
552
                cond = None
553
                if recover: # need auto-rollback to run constraint_cond()
554
                    try: cond = constraint_cond(db, constraint)
555
                    except NotImplementedError: pass
556
                raise CheckException(constraint.to_str(db), cond, [], e)
557
            
558
            match = re.match(r'^(?:invalid input (?:syntax|value)\b.*?'
559
                r'|.+? out of range): "(.+?)"', msg)
560
            if match:
561
                value, = match.groups()
562
                raise InvalidValueException(strings.to_unicode(value), e)
563
            
564
            match = re.match(r'^column "(.+?)" is of type (.+?) but expression '
565
                r'is of type', msg)
566
            if match:
567
                col, type_ = match.groups()
568
                raise MissingCastException(type_, col, e)
569
            
570
            match = re.match(r'^could not determine polymorphic type because '
571
                r'input has type "unknown"', msg)
572
            if match: raise MissingCastException('text', None, e)
573
            
574
            match = re.match(r'^.+? types .+? and .+? cannot be matched', msg)
575
            if match: raise MissingCastException('text', None, e)
576
            
577
            typed_name_re = r'^(\S+) "(.+?)"(?: of relation ".+?")?'
578
            
579
            match = re.match(typed_name_re+r'.*? already exists', msg)
580
            if match:
581
                type_, name = match.groups()
582
                raise DuplicateException(type_, name, e)
583
            
584
            match = re.match(r'more than one (\S+) named ""(.+?)""', msg)
585
            if match:
586
                type_, name = match.groups()
587
                raise DuplicateException(type_, name, e)
588
            
589
            match = re.match(typed_name_re+r' does not exist', msg)
590
            if match:
591
                type_, name = match.groups()
592
                raise DoesNotExistException(type_, name, e)
593
            
594
            raise # no specific exception raised
595
        except Exception, e: parse_exception(db, e, recover)
595 596
    except log_ignore_excs:
596 597
        log_level += 2
597 598
        raise

Also available in: Unified diff