Package orm2 :: Package adapters :: Package firebird :: Module datatypes
[hide private]
[frames] | no frames]

Source Code for Module orm2.adapters.firebird.datatypes

  1  #!/usr/bin/env python 
  2  # -*- coding: iso-8859-1 -*- 
  3   
  4  ##  This file is part of orm, The Object Relational Membrane Version 2. 
  5  ## 
  6  ##  Copyright 2002-2006 by Diedrich Vorberg <diedrich@tux4web.de> 
  7  ## 
  8  ##  All Rights Reserved 
  9  ## 
 10  ##  For more Information on orm see the README file. 
 11  ## 
 12  ##  This program is free software; you can redistribute it and/or modify 
 13  ##  it under the terms of the GNU General Public License as published by 
 14  ##  the Free Software Foundation; either version 2 of the License, or 
 15  ##  (at your option) any later version. 
 16  ## 
 17  ##  This program is distributed in the hope that it will be useful, 
 18  ##  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 19  ##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 20  ##  GNU General Public License for more details. 
 21  ## 
 22  ##  You should have received a copy of the GNU General Public License 
 23  ##  along with this program; if not, write to the Free Software 
 24  ##  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
 25  ## 
 26  ##  I have added a copy of the GPL in the file COPYING 
 27   
 28  # Changelog 
 29  # --------- 
 30  # 
 31  # $Log: datatypes.py,v $ 
 32  # Revision 1.2  2006/05/13 17:23:41  diedrich 
 33  # Massive docstring update. 
 34  # 
 35  # Revision 1.1  2006/05/10 21:53:28  diedrich 
 36  # Initial commit 
 37  # 
 38  # 
 39  # 
 40  # 
 41   
 42  """ 
 43  This module defines those datatypes that are specific for FireBird. 
 44   
 45  @author: Diedrich Vorberg <diedrich@tux4web.de>, May 2006 
 46  """ 
 47   
 48   
 49  # Python 
 50  import sys 
 51  from types import * 
 52  from string import * 
 53   
 54  # orm 
 55  from orm2 import sql 
 56  from orm2.datatypes import * 
 57   
58 -class serial(integer):
59 """ 60 Datatype for automatically gernerated ids. 61 62 From U{The FireBird FAQ <http://firebird.sourceforge.net/index.php?op=faq#q0011.dat>} 63 64 How can i make an auto-incrementing primary key column? and is the NOT NULL constraint mandatory for a primary key? 65 =================================================================================================================== 66 In Firebird, you achieve an auto-incrementing PK using a generator 67 and a BEFORE INSERT trigger:: 68 69 CREATE GENERATOR GEN_PK_ATABLE; 70 COMMIT; 71 72 Define the column, e.g., ATABLE_ID, as BIGINT or INTEGER and yes, 73 the NOT NULL constraint is mandatory for a primary key. 74 75 The trigger for automatic population of the key is this:: 76 77 CREATE TRIGGER BI_ATABLE FOR ATABLE 78 ACTIVE BEFORE INSERT 79 AS 80 BEGIN 81 IF(NEW.ATABLE_ID IS NULL) THEN 82 NEW.ATABLE_ID = GEN_ID(GEN_PK_ATABLE, 1); 83 END 84 85 I{This is B{NOT} what orm does! It does...} 86 87 How can I get the value of my generated primary key after an insert ? 88 ===================================================================== 89 Firebird doesn't currently return values from insert statements 90 and, in multi-user, it isn't safe to query the generator 91 afterwards (GEN_ID(Generator_name, 0) because you have no way 92 to know whether the current 'latest' value was yours or someone 93 else's. The trick is to get the generator value into your 94 application as a variable before you post your insert. This 95 way, you make it available not just for your insert but for any 96 dependent rows you need to create for it inside the same 97 transaction:: 98 99 SELECT GEN_ID(Generator_name, 1) AS MyVar FROM RDB$DATABASE; 100 101 Some data access interfaces and drivers provide ways to do this 102 automatically for you. For example, IB Objects implements the 103 GeneratorLinks property for statement classes. 104 105 106 How it is handeld by orm 107 ======================== 108 orm is the kind of interface that does this automatically for 109 you. For any serial (and in fact L{common_serial 110 <orm2.datatypes.common_serial>}, see above) column it will query 111 the corresponding sequence and store the resulting value in the 112 right attribute to be used in the INSERT statement. If you use 113 a serial as your primary key, the select_after_insert() 114 mechanism (see L{orm2.datasource.datasource}) will work 115 correctly. 116 117 """ 118
119 - def __init__(self, column=None, sequence=None, title=None, 120 validators=(), widget_specs=()):
121 """ 122 @param sequence: Either a string or a sql.identifyer instance, 123 naming the sequence to be used by this serial column. Defaults 124 to GEN_PK_<relation name> 125 """ 126 integer.__init__(self, column, title, validators, widget_specs, 127 has_default=True) 128 129 self.sequence = sequence
130
131 - def __init_dbclass__(self, dbclass, attribute_name):
132 integer.__init_dbclass__(self, dbclass, attribute_name) 133 134 if self.sequence is None: 135 self.sequence = "GEN_PK_%s" % upper(dbclass.__relation__.name) 136 137 if type(self.sequence) == StringType: 138 self.sequence = sql.identifyer(self.sequence)
139
140 - def __set__(self, dbobj, value):
141 if self.isset(dbobj): 142 raise ORMException( "A auto_increment property is not mutable, "+\ 143 "once it is on object creation" ) 144 else: 145 integer.__set__(self, dbobj, value)
146 147 148 149 150 151 152 # Local variables: 153 # mode: python 154 # ispell-local-dictionary: "english" 155 # End: 156