1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2009 Oracle. All rights reserved. 5 * 6 */ 7using System; 8using System.Collections.Generic; 9using System.Text; 10using BerkeleyDB.Internal; 11 12namespace BerkeleyDB { 13 /// <summary> 14 /// A class representing a RecnoDatabase. The Recno format supports fixed- 15 /// or variable-length records, accessed sequentially or by logical record 16 /// number, and optionally backed by a flat text file. 17 /// </summary> 18 public class SecondaryRecnoDatabase : SecondaryDatabase { 19 20 #region Constructors 21 internal SecondaryRecnoDatabase(DatabaseEnvironment env, uint flags) 22 : base(env, flags) { } 23 24 private void Config(SecondaryRecnoDatabaseConfig cfg) { 25 base.Config((SecondaryDatabaseConfig)cfg); 26 db.set_flags(cfg.flags); 27 28 if (cfg.delimiterIsSet) 29 db.set_re_delim(cfg.Delimiter); 30 if (cfg.lengthIsSet) 31 db.set_re_len(cfg.Length); 32 if (cfg.padIsSet) 33 db.set_re_pad(cfg.PadByte); 34 if (cfg.BackingFile != null) 35 db.set_re_source(cfg.BackingFile); 36 } 37 38 /// <summary> 39 /// Instantiate a new SecondaryRecnoDatabase object, open the 40 /// database represented by <paramref name="Filename"/> and associate 41 /// the database with the 42 /// <see cref="SecondaryDatabaseConfig.Primary">primary index</see>. 43 /// </summary> 44 /// <remarks> 45 /// <para> 46 /// If <paramref name="Filename"/> is null, the database is strictly 47 /// temporary and cannot be opened by any other thread of control, thus 48 /// the database can only be accessed by sharing the single database 49 /// object that created it, in circumstances where doing so is safe. 50 /// </para> 51 /// <para> 52 /// If <see cref="DatabaseConfig.AutoCommit"/> is set, the operation 53 /// will be implicitly transaction protected. Note that transactionally 54 /// protected operations on a datbase object requires the object itself 55 /// be transactionally protected during its open. 56 /// </para> 57 /// </remarks> 58 /// <param name="Filename"> 59 /// The name of an underlying file that will be used to back the 60 /// database. In-memory databases never intended to be preserved on disk 61 /// may be created by setting this parameter to null. 62 /// </param> 63 /// <param name="cfg">The database's configuration</param> 64 /// <returns>A new, open database object</returns> 65 public static SecondaryRecnoDatabase Open( 66 string Filename, SecondaryRecnoDatabaseConfig cfg) { 67 return Open(Filename, null, cfg, null); 68 } 69 /// <summary> 70 /// Instantiate a new SecondaryRecnoDatabase object, open the 71 /// database represented by <paramref name="Filename"/> and associate 72 /// the database with the 73 /// <see cref="SecondaryDatabaseConfig.Primary">primary index</see>. 74 /// </summary> 75 /// <remarks> 76 /// <para> 77 /// If both <paramref name="Filename"/> and 78 /// <paramref name="DatabaseName"/> are null, the database is strictly 79 /// temporary and cannot be opened by any other thread of control, thus 80 /// the database can only be accessed by sharing the single database 81 /// object that created it, in circumstances where doing so is safe. If 82 /// <paramref name="Filename"/> is null and 83 /// <paramref name="DatabaseName"/> is non-null, the database can be 84 /// opened by other threads of control and will be replicated to client 85 /// sites in any replication group. 86 /// </para> 87 /// <para> 88 /// If <see cref="DatabaseConfig.AutoCommit"/> is set, the operation 89 /// will be implicitly transaction protected. Note that transactionally 90 /// protected operations on a datbase object requires the object itself 91 /// be transactionally protected during its open. 92 /// </para> 93 /// </remarks> 94 /// <param name="Filename"> 95 /// The name of an underlying file that will be used to back the 96 /// database. In-memory databases never intended to be preserved on disk 97 /// may be created by setting this parameter to null. 98 /// </param> 99 /// <param name="DatabaseName"> 100 /// This parameter allows applications to have multiple databases in a 101 /// single file. Although no DatabaseName needs to be specified, it is 102 /// an error to attempt to open a second database in a file that was not 103 /// initially created using a database name. 104 /// </param> 105 /// <param name="cfg">The database's configuration</param> 106 /// <returns>A new, open database object</returns> 107 public static SecondaryRecnoDatabase Open(string Filename, 108 string DatabaseName, SecondaryRecnoDatabaseConfig cfg) { 109 return Open(Filename, DatabaseName, cfg, null); 110 } 111 /// <summary> 112 /// Instantiate a new SecondaryRecnoDatabase object, open the 113 /// database represented by <paramref name="Filename"/> and associate 114 /// the database with the 115 /// <see cref="SecondaryDatabaseConfig.Primary">primary index</see>. 116 /// </summary> 117 /// <remarks> 118 /// <para> 119 /// If <paramref name="Filename"/> is null, the database is strictly 120 /// temporary and cannot be opened by any other thread of control, thus 121 /// the database can only be accessed by sharing the single database 122 /// object that created it, in circumstances where doing so is safe. 123 /// </para> 124 /// <para> 125 /// If <paramref name="txn"/> is null, but 126 /// <see cref="DatabaseConfig.AutoCommit"/> is set, the operation will 127 /// be implicitly transaction protected. Note that transactionally 128 /// protected operations on a datbase object requires the object itself 129 /// be transactionally protected during its open. Also note that the 130 /// transaction must be committed before the object is closed. 131 /// </para> 132 /// </remarks> 133 /// <param name="Filename"> 134 /// The name of an underlying file that will be used to back the 135 /// database. In-memory databases never intended to be preserved on disk 136 /// may be created by setting this parameter to null. 137 /// </param> 138 /// <param name="cfg">The database's configuration</param> 139 /// <param name="txn"> 140 /// If the operation is part of an application-specified transaction, 141 /// <paramref name="txn"/> is a Transaction object returned from 142 /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if 143 /// the operation is part of a Berkeley DB Concurrent Data Store group, 144 /// <paramref name="txn"/> is a handle returned from 145 /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. 146 /// </param> 147 /// <returns>A new, open database object</returns> 148 public static SecondaryRecnoDatabase Open(string Filename, 149 SecondaryRecnoDatabaseConfig cfg, Transaction txn) { 150 return Open(Filename, null, cfg, txn); 151 } 152 /// <summary> 153 /// Instantiate a new SecondaryRecnoDatabase object, open the 154 /// database represented by <paramref name="Filename"/> and associate 155 /// the database with the 156 /// <see cref="SecondaryDatabaseConfig.Primary">primary index</see>. 157 /// </summary> 158 /// <remarks> 159 /// <para> 160 /// If both <paramref name="Filename"/> and 161 /// <paramref name="DatabaseName"/> are null, the database is strictly 162 /// temporary and cannot be opened by any other thread of control, thus 163 /// the database can only be accessed by sharing the single database 164 /// object that created it, in circumstances where doing so is safe. If 165 /// <paramref name="Filename"/> is null and 166 /// <paramref name="DatabaseName"/> is non-null, the database can be 167 /// opened by other threads of control and will be replicated to client 168 /// sites in any replication group. 169 /// </para> 170 /// <para> 171 /// If <paramref name="txn"/> is null, but 172 /// <see cref="DatabaseConfig.AutoCommit"/> is set, the operation will 173 /// be implicitly transaction protected. Note that transactionally 174 /// protected operations on a datbase object requires the object itself 175 /// be transactionally protected during its open. Also note that the 176 /// transaction must be committed before the object is closed. 177 /// </para> 178 /// </remarks> 179 /// <param name="Filename"> 180 /// The name of an underlying file that will be used to back the 181 /// database. In-memory databases never intended to be preserved on disk 182 /// may be created by setting this parameter to null. 183 /// </param> 184 /// <param name="DatabaseName"> 185 /// This parameter allows applications to have multiple databases in a 186 /// single file. Although no DatabaseName needs to be specified, it is 187 /// an error to attempt to open a second database in a file that was not 188 /// initially created using a database name. 189 /// </param> 190 /// <param name="cfg">The database's configuration</param> 191 /// <param name="txn"> 192 /// If the operation is part of an application-specified transaction, 193 /// <paramref name="txn"/> is a Transaction object returned from 194 /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if 195 /// the operation is part of a Berkeley DB Concurrent Data Store group, 196 /// <paramref name="txn"/> is a handle returned from 197 /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. 198 /// </param> 199 /// <returns>A new, open database object</returns> 200 public static SecondaryRecnoDatabase Open(string Filename, 201 string DatabaseName, 202 SecondaryRecnoDatabaseConfig cfg, Transaction txn) { 203 SecondaryRecnoDatabase ret = new SecondaryRecnoDatabase(cfg.Env, 0); 204 ret.Config(cfg); 205 ret.db.open(Transaction.getDB_TXN(txn), Filename, 206 DatabaseName, cfg.DbType.getDBTYPE(), cfg.openFlags, 0); 207 ret.isOpen = true; 208 ret.doAssocRef = 209 new BDB_AssociateDelegate(SecondaryDatabase.doAssociate); 210 cfg.Primary.db.associate(Transaction.getDB_TXN(null), 211 ret.db, ret.doAssocRef, cfg.assocFlags); 212 213 if (cfg.ForeignKeyDatabase != null) { 214 if (cfg.OnForeignKeyDelete == ForeignKeyDeleteAction.NULLIFY) 215 ret.doNullifyRef = 216 new BDB_AssociateForeignDelegate(doNullify); 217 else 218 ret.doNullifyRef = null; 219 cfg.ForeignKeyDatabase.db.associate_foreign( 220 ret.db, ret.doNullifyRef, cfg.foreignFlags); 221 } 222 return ret; 223 } 224 225 #endregion Constructors 226 227 #region Properties 228 /// <summary> 229 /// If true, the logical record numbers are mutable, and change as 230 /// records are added to and deleted from the database. 231 /// </summary> 232 public bool Renumber { 233 get { 234 uint flags = 0; 235 db.get_flags(ref flags); 236 return (flags & DbConstants.DB_RENUMBER) != 0; 237 } 238 } 239 /// <summary> 240 /// If true, any <see cref="BackingFile"/> file will be read in its 241 /// entirety when <see cref="Open"/> is called. If false, 242 /// <see cref="BackingFile"/> may be read lazily. 243 /// </summary> 244 public bool Snapshot { 245 get { 246 uint flags = 0; 247 db.get_flags(ref flags); 248 return (flags & DbConstants.DB_SNAPSHOT) != 0; 249 } 250 } 251 /// <summary> 252 /// The delimiting byte used to mark the end of a record in 253 /// <see cref="BackingFile"/>. 254 /// </summary> 255 public int Delimiter { 256 get { 257 int ret = 0; 258 db.get_re_delim(ref ret); 259 return ret; 260 } 261 } 262 /// <summary> 263 /// If using fixed-length, not byte-delimited records, the length of the 264 /// records. 265 /// </summary> 266 public uint Length { 267 get { 268 uint ret = 0; 269 db.get_re_len(ref ret); 270 return ret; 271 } 272 } 273 /// <summary> 274 /// The padding character for short, fixed-length records. 275 /// </summary> 276 public int PadByte { 277 get { 278 int ret = 0; 279 db.get_re_pad(ref ret); 280 return ret; 281 } 282 } 283 /// <summary> 284 /// The underlying source file for the Recno access method. 285 /// </summary> 286 public string BackingFile { 287 get { 288 string ret = ""; 289 db.get_re_source(ref ret); 290 return ret; 291 } 292 } 293 #endregion Properties 294 295 } 296} 297