Project

General

Profile

« Previous | Next » 

Revision 3449

sql_gen.py: Added RowExcIgnore

View differences:

lib/sql_gen.py
469 469
'''
470 470
        return str_
471 471

  
472
class RowExcIgnore(Code):
473
    def __init__(self, row_type, select_query, with_row, cols=None,
474
        exc='unique_violation'):
475
        Code.__init__(self, lang='plpgsql')
476
        
477
        select_query = as_Code(select_query)
478
        with_row = as_Code(with_row)
479
        
480
        self.row_type = row_type
481
        self.select_query = select_query
482
        self.with_row = with_row
483
        self.cols = cols
484
        self.exc = exc
485
    
486
    def to_str(self, db):
487
        if self.cols == None: row_vars = [Table('row')]
488
        else: row_vars = [Col(c.name, 'row') for c in self.cols]
489
        
490
        str_ = '''\
491
DECLARE
492
    row '''+self.row_type+''';
493
BEGIN
494
    /* Need an EXCEPTION block for each individual row because "When an error is
495
    caught by an EXCEPTION clause, [...] all changes to persistent database
496
    state within the block are rolled back."
497
    This is unfortunate because "A block containing an EXCEPTION clause is
498
    significantly more expensive to enter and exit than a block without one."
499
    (http://www.postgresql.org/docs/8.3/static/plpgsql-control-structures.html\
500
#PLPGSQL-ERROR-TRAPPING)
501
    */
502
    FOR '''+(', '.join((v.to_str(db) for v in row_vars)))+''' IN
503
'''+self.select_query.to_str(db)+'''
504
    LOOP
505
        BEGIN
506
            RETURN QUERY
507
'''+self.with_row.to_str(db)+'''
508
;
509
        EXCEPTION
510
            WHEN '''+self.exc+''' THEN NULL; -- continue to next row
511
        END;
512
    END LOOP;
513
END;\
514
'''
515
        return str_
516

  
472 517
##### Casts
473 518

  
474 519
class Cast(FunctionCall):

Also available in: Unified diff