1 /*- 2 * Copyright (c) 2009, 2020 Oracle and/or its affiliates. All rights reserved. 3 * 4 * See the file LICENSE for license information. 5 * 6 */ 7 using System; 8 using System.Collections.Generic; 9 using System.IO; 10 using System.Text; 11 using BerkeleyDB.Internal; 12 13 namespace BerkeleyDB { 14 /// <summary> 15 /// A class representing a Berkeley DB database, a base class for access 16 /// method specific classes. 17 /// </summary> 18 public class Database : BaseDatabase, IDisposable { 19 private static BDB_FileWriteDelegate writeToFileRef; 20 21 #region Constructors 22 /// <summary> 23 /// Protected constructor 24 /// </summary> 25 /// <param name="env"> 26 /// The environment in which to create this database 27 /// </param> 28 /// <param name="flags">Flags to pass to the DB->create() method</param> Database(DatabaseEnvironment env, uint flags)29 protected Database(DatabaseEnvironment env, uint flags) 30 : base(env, flags) { 31 } 32 /// <summary> 33 /// Create a new database object with the same underlying DB handle as 34 /// <paramref name="clone"/>. Used during Database.Open to get an 35 /// object of the correct DBTYPE. 36 /// </summary> 37 /// <param name="clone">Database to clone</param> Database(BaseDatabase clone)38 protected Database(BaseDatabase clone) : base(clone) { } fromDB(DB dbp)39 internal static Database fromDB(DB dbp) { 40 try { 41 return (Database)dbp.api_internal; 42 } catch { } 43 return null; 44 } 45 46 /// <summary> 47 /// Instantiate a new Database object and open the database represented 48 /// by <paramref name="Filename"/>. The file specified by 49 /// <paramref name="Filename"/> must exist. 50 /// </summary> 51 /// <remarks> 52 /// <para> 53 /// If <see cref="DatabaseConfig.AutoCommit"/> is set, the operation 54 /// is implicitly transaction protected. Transactionally 55 /// protected operations on a database object requires the object itself 56 /// be transactionally protected during its open. 57 /// </para> 58 /// </remarks> 59 /// <param name="Filename"> 60 /// The name of an underlying file used to back the 61 /// database. 62 /// </param> 63 /// <param name="cfg">The database's configuration</param> 64 /// <returns>A new, open database object</returns> Open(string Filename, DatabaseConfig cfg)65 public static Database Open(string Filename, DatabaseConfig cfg) { 66 return Open(Filename, null, cfg, null); 67 } 68 /// <summary> 69 /// Instantiate a new Database object and open the database represented 70 /// by <paramref name="Filename"/> and <paramref name="DatabaseName"/>. 71 /// The file specified by <paramref name="Filename"/> must exist. 72 /// </summary> 73 /// <remarks> 74 /// <para> 75 /// If <paramref name="Filename"/> is null and 76 /// <paramref name="DatabaseName"/> is non-null, the database can be 77 /// opened by other threads of control and be replicated to client 78 /// sites in any replication group. 79 /// </para> 80 /// <para> 81 /// If <see cref="DatabaseConfig.AutoCommit"/> is set, the operation 82 /// is implicitly transaction protected. Transactionally 83 /// protected operations on a database object requires the object itself 84 /// be transactionally protected during its open. 85 /// </para> 86 /// </remarks> 87 /// <param name="Filename"> 88 /// The name of an underlying file used to back the 89 /// database. In-memory databases never intended to be preserved on disk 90 /// may be created by setting this parameter to null.</param> 91 /// <param name="DatabaseName"> 92 /// This parameter allows applications to have multiple databases in a 93 /// single file. Although no DatabaseName needs to be specified, an error 94 /// occurs if you attempt to open a second database in a file that was not 95 /// initially created using a database name. 96 /// </param> 97 /// <param name="cfg">The database's configuration</param> 98 /// <returns>A new, open database object</returns> Open( string Filename, string DatabaseName, DatabaseConfig cfg)99 public static Database Open( 100 string Filename, string DatabaseName, DatabaseConfig cfg) { 101 return Open(Filename, DatabaseName, cfg, null); 102 } 103 /// <summary> 104 /// Instantiate a new Database object and open the database represented 105 /// by <paramref name="Filename"/>. The file specified by 106 /// <paramref name="Filename"/> must exist. 107 /// </summary> 108 /// <remarks> 109 /// <para> 110 /// If <paramref name="Filename"/> is null, the database is strictly 111 /// temporary and cannot be opened by any other thread of control, thus 112 /// the database can only be accessed by sharing the single database 113 /// object that created it, in circumstances where doing so is safe. 114 /// </para> 115 /// <para> 116 /// If <paramref name="txn"/> is null, but 117 /// <see cref="DatabaseConfig.AutoCommit"/> is set, the operation 118 /// is implicitly transaction protected. Transactionally 119 /// protected operations on a database object requires the object itself 120 /// be transactionally protected during its open. The 121 /// transaction must be committed before the object is closed. 122 /// </para> 123 /// </remarks> 124 /// <param name="Filename"> 125 /// The name of an underlying file used to back the 126 /// database. In-memory databases never intended to be preserved on disk 127 /// may be created by setting this parameter to null. 128 /// </param> 129 /// <param name="cfg">The database's configuration</param> 130 /// <param name="txn"> 131 /// If the operation is part of an application-specified transaction, 132 /// <paramref name="txn"/> is a Transaction object returned from 133 /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if 134 /// the operation is part of a Berkeley DB Concurrent Data Store group, 135 /// <paramref name="txn"/> is a handle returned from 136 /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. 137 /// </param> 138 /// <returns>A new, open database object</returns> Open( string Filename, DatabaseConfig cfg, Transaction txn)139 public static Database Open( 140 string Filename, DatabaseConfig cfg, Transaction txn) { 141 return Open(Filename, null, cfg, txn); 142 } 143 /// <summary> 144 /// Instantiate a new Database object and open the database represented 145 /// by <paramref name="Filename"/> and <paramref name="DatabaseName"/>. 146 /// The file specified by <paramref name="Filename"/> must exist. 147 /// </summary> 148 /// <remarks> 149 /// <para> 150 /// If both <paramref name="Filename"/> and 151 /// <paramref name="DatabaseName"/> are null, the database is strictly 152 /// temporary and cannot be opened by any other thread of control, thus 153 /// the database can only be accessed by sharing the single database 154 /// object that created it, in circumstances where doing so is safe. If 155 /// <paramref name="Filename"/> is null and 156 /// <paramref name="DatabaseName"/> is non-null, the database can be 157 /// opened by other threads of control and be replicated to client 158 /// sites in any replication group. 159 /// </para> 160 /// <para> 161 /// If <paramref name="txn"/> is null, but 162 /// <see cref="DatabaseConfig.AutoCommit"/> is set, the operation 163 /// is implicitly transaction protected. Transactionally 164 /// protected operations on a database object requires the object itself 165 /// be transactionally protected during its open. The 166 /// transaction must be committed before the object is closed. 167 /// </para> 168 /// </remarks> 169 /// <param name="Filename"> 170 /// The name of an underlying file used to back the 171 /// database. In-memory databases never intended to be preserved on disk 172 /// may be created by setting this parameter to null. 173 /// </param> 174 /// <param name="DatabaseName"> 175 /// This parameter allows applications to have multiple databases in a 176 /// single file. Although no DatabaseName needs to be specified, it is 177 /// an error to attempt to open a second database in a file that was not 178 /// initially created using a database name. 179 /// </param> 180 /// <param name="cfg">The database's configuration</param> 181 /// <param name="txn"> 182 /// If the operation is part of an application-specified transaction, 183 /// <paramref name="txn"/> is a Transaction object returned from 184 /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if 185 /// the operation is part of a Berkeley DB Concurrent Data Store group, 186 /// <paramref name="txn"/> is a handle returned from 187 /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. 188 /// </param> 189 /// <returns>A new, open database object</returns> Open(string Filename, string DatabaseName, DatabaseConfig cfg, Transaction txn)190 public static new Database Open(string Filename, 191 string DatabaseName, DatabaseConfig cfg, Transaction txn) { 192 Database ret; 193 BaseDatabase db = BaseDatabase.Open( 194 Filename, DatabaseName, cfg, txn); 195 switch (db.Type.getDBTYPE()) { 196 case DBTYPE.DB_BTREE: 197 ret = new BTreeDatabase(db); 198 break; 199 case DBTYPE.DB_HASH: 200 ret = new HashDatabase(db); 201 break; 202 case DBTYPE.DB_HEAP: 203 ret = new HeapDatabase(db); 204 break; 205 case DBTYPE.DB_QUEUE: 206 ret = new QueueDatabase(db); 207 break; 208 case DBTYPE.DB_RECNO: 209 ret = new RecnoDatabase(db); 210 break; 211 default: 212 throw new DatabaseException(0); 213 } 214 db.Dispose(); 215 ret.isOpen = true; 216 return ret; 217 } 218 #endregion Constructor 219 writeToFile(TextWriter OutputStream, string data)220 private static int writeToFile(TextWriter OutputStream, string data) { 221 OutputStream.Write(data); 222 return 0; 223 } 224 225 #region Methods 226 /// <summary> 227 /// If a key/data pair in the database matches <paramref name="key"/> 228 /// and <paramref name="data"/>, return the key and all duplicate data 229 /// items. 230 /// </summary> 231 /// <param name="key">The key to search for</param> 232 /// <param name="data">The data to search for</param> 233 /// <exception cref="NotFoundException"> 234 /// A NotFoundException is thrown if <paramref name="key"/> and 235 /// <paramref name="data"/> are not in the database. 236 /// </exception> 237 /// <exception cref="KeyEmptyException"> 238 /// A KeyEmptyException is thrown if the database is a 239 /// <see cref="QueueDatabase"/> or <see cref="RecnoDatabase"/> 240 /// database and <paramref name="key"/> exists, but was never explicitly 241 /// created by the application or was later deleted. 242 /// </exception> 243 /// <returns> 244 /// A <see cref="KeyValuePair{T,T}"/> 245 /// whose Key parameter is <paramref name="key"/> and whose Value 246 /// parameter is the retrieved data items. 247 /// </returns> 248 public GetBothMultiple( DatabaseEntry key, DatabaseEntry data)249 KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> GetBothMultiple( 250 DatabaseEntry key, DatabaseEntry data) { 251 /* 252 * Make sure we pass a buffer that is big enough to hold data.Data 253 * and is a multiple of the page size. Cache this.Pagesize to avoid 254 * multiple P/Invoke calls. 255 */ 256 uint pgsz = Pagesize; 257 uint npgs = (data.size / pgsz) + 1; 258 return GetBothMultiple(key, data, (int)(npgs * pgsz), null, null); 259 } 260 /// <summary> 261 /// If a key/data pair in the database matches <paramref name="key"/> 262 /// and <paramref name="data"/>, return the key and all duplicate data 263 /// items. 264 /// </summary> 265 /// <param name="key">The key to search for</param> 266 /// <param name="data">The data to search for</param> 267 /// <param name="BufferSize"> 268 /// The initial size of the buffer to fill with duplicate data items. If 269 /// the buffer is not large enough, it is automatically resized. 270 /// </param> 271 /// <exception cref="NotFoundException"> 272 /// A NotFoundException is thrown if <paramref name="key"/> and 273 /// <paramref name="data"/> are not in the database. 274 /// </exception> 275 /// <exception cref="KeyEmptyException"> 276 /// A KeyEmptyException is thrown if the database is a 277 /// <see cref="QueueDatabase"/> or <see cref="RecnoDatabase"/> 278 /// database and <paramref name="key"/> exists, but was never explicitly 279 /// created by the application or was later deleted. 280 /// </exception> 281 /// <returns> 282 /// A <see cref="KeyValuePair{T,T}"/> 283 /// whose Key parameter is <paramref name="key"/> and whose Value 284 /// parameter is the retrieved data items. 285 /// </returns> 286 public GetBothMultiple( DatabaseEntry key, DatabaseEntry data, int BufferSize)287 KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> GetBothMultiple( 288 DatabaseEntry key, DatabaseEntry data, int BufferSize) { 289 return GetBothMultiple(key, data, BufferSize, null, null); 290 } 291 /// <summary> 292 /// If a key/data pair in the database matches <paramref name="key"/> 293 /// and <paramref name="data"/>, return the key and all duplicate data 294 /// items. 295 /// </summary> 296 /// <param name="key">The key to search for</param> 297 /// <param name="data">The data to search for</param> 298 /// <param name="BufferSize"> 299 /// The initial size of the buffer to fill with duplicate data items. If 300 /// the buffer is not large enough, it is automatically resized. 301 /// </param> 302 /// <param name="txn"> 303 /// <paramref name="txn"/> is a Transaction object returned from 304 /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if 305 /// the operation is part of a Berkeley DB Concurrent Data Store group, 306 /// <paramref name="txn"/> is a handle returned from 307 /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. 308 /// </param> 309 /// <exception cref="NotFoundException"> 310 /// A NotFoundException is thrown if <paramref name="key"/> and 311 /// <paramref name="data"/> are not in the database. 312 /// </exception> 313 /// <exception cref="KeyEmptyException"> 314 /// A KeyEmptyException is thrown if the database is a 315 /// <see cref="QueueDatabase"/> or <see cref="RecnoDatabase"/> 316 /// database and <paramref name="key"/> exists, but was never explicitly 317 /// created by the application or was later deleted. 318 /// </exception> 319 /// <returns> 320 /// A <see cref="KeyValuePair{T,T}"/> 321 /// whose Key parameter is <paramref name="key"/> and whose Value 322 /// parameter is the retrieved data items. 323 /// </returns> 324 public GetBothMultiple( DatabaseEntry key, DatabaseEntry data, int BufferSize, Transaction txn)325 KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> GetBothMultiple( 326 DatabaseEntry key, 327 DatabaseEntry data, int BufferSize, Transaction txn) { 328 return GetBothMultiple(key, data, BufferSize, txn, null); 329 } 330 /// <summary> 331 /// If a key/data pair in the database matches <paramref name="key"/> 332 /// and <paramref name="data"/>, return the key and all duplicate data 333 /// items. 334 /// </summary> 335 /// <param name="key">The key to search for</param> 336 /// <param name="data">The data to search for</param> 337 /// <param name="BufferSize"> 338 /// The initial size of the buffer to fill with duplicate data items. If 339 /// the buffer is not large enough, it is automatically resized. 340 /// </param> 341 /// <param name="txn"> 342 /// <paramref name="txn"/> is a Transaction object returned from 343 /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if 344 /// the operation is part of a Berkeley DB Concurrent Data Store group, 345 /// <paramref name="txn"/> is a handle returned from 346 /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. 347 /// </param> 348 /// <param name="info">The locking behavior to use.</param> 349 /// <exception cref="NotFoundException"> 350 /// A NotFoundException is thrown if <paramref name="key"/> and 351 /// <paramref name="data"/> are not in the database. 352 /// </exception> 353 /// <exception cref="KeyEmptyException"> 354 /// A KeyEmptyException is thrown if the database is a 355 /// <see cref="QueueDatabase"/> or <see cref="RecnoDatabase"/> 356 /// database and <paramref name="key"/> exists, but was never explicitly 357 /// created by the application or was later deleted. 358 /// </exception> 359 /// <returns> 360 /// A <see cref="KeyValuePair{T,T}"/> 361 /// whose Key parameter is <paramref name="key"/> and whose Value 362 /// parameter is the retrieved data items. 363 /// </returns> 364 public GetBothMultiple( DatabaseEntry key, DatabaseEntry data, int BufferSize, Transaction txn, LockingInfo info)365 KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> GetBothMultiple( 366 DatabaseEntry key, DatabaseEntry data, 367 int BufferSize, Transaction txn, LockingInfo info) { 368 KeyValuePair<DatabaseEntry, DatabaseEntry> kvp; 369 int datasz = (int)data.Data.Length; 370 371 for (; ; ) { 372 byte[] udata = new byte[BufferSize]; 373 Array.Copy(data.Data, udata, datasz); 374 data.UserData = udata; 375 data.size = (uint)datasz; 376 try { 377 kvp = Get(key, data, txn, info, 378 DbConstants.DB_MULTIPLE | DbConstants.DB_GET_BOTH); 379 break; 380 } catch (MemoryException) { 381 int sz = (int)data.size; 382 if (sz > BufferSize) 383 BufferSize = sz; 384 else 385 BufferSize *= 2; 386 } 387 } 388 MultipleDatabaseEntry dbe = new MultipleDatabaseEntry(kvp.Value); 389 return new KeyValuePair<DatabaseEntry, MultipleDatabaseEntry>( 390 kvp.Key, dbe); 391 } 392 393 /// <summary> 394 /// Retrieve a key and all duplicate data items from the database. 395 /// </summary> 396 /// <param name="key">The key to search for</param> 397 /// <exception cref="NotFoundException"> 398 /// A NotFoundException is thrown if <paramref name="key"/> is not in 399 /// the database. 400 /// </exception> 401 /// <exception cref="KeyEmptyException"> 402 /// A KeyEmptyException is thrown if the database is a 403 /// <see cref="QueueDatabase"/> or <see cref="RecnoDatabase"/> 404 /// database and <paramref name="key"/> exists, but was never explicitly 405 /// created by the application or was later deleted. 406 /// </exception> 407 /// <returns> 408 /// A <see cref="KeyValuePair{T,T}"/> 409 /// whose Key parameter is <paramref name="key"/> and whose Value 410 /// parameter is the retrieved data items. 411 /// </returns> GetMultiple( DatabaseEntry key)412 public KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> GetMultiple( 413 DatabaseEntry key) { 414 return GetMultiple(key, (int)Pagesize, null, null); 415 } 416 /// <summary> 417 /// Retrieve a key and all duplicate data items from the database. 418 /// </summary> 419 /// <param name="key">The key to search for</param> 420 /// <param name="BufferSize"> 421 /// The initial size of the buffer to fill with duplicate data items. If 422 /// the buffer is not large enough, it is automatically resized. 423 /// </param> 424 /// <exception cref="NotFoundException"> 425 /// A NotFoundException is thrown if <paramref name="key"/> is not in 426 /// the database. 427 /// </exception> 428 /// <exception cref="KeyEmptyException"> 429 /// A KeyEmptyException is thrown if the database is a 430 /// <see cref="QueueDatabase"/> or <see cref="RecnoDatabase"/> 431 /// database and <paramref name="key"/> exists, but was never explicitly 432 /// created by the application or was later deleted. 433 /// </exception> 434 /// <returns> 435 /// A <see cref="KeyValuePair{T,T}"/> 436 /// whose Key parameter is <paramref name="key"/> and whose Value 437 /// parameter is the retrieved data items. 438 /// </returns> GetMultiple( DatabaseEntry key, int BufferSize)439 public KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> GetMultiple( 440 DatabaseEntry key, int BufferSize) { 441 return GetMultiple(key, BufferSize, null, null); 442 } 443 /// <summary> 444 /// Retrieve a key and all duplicate data items from the database. 445 /// </summary> 446 /// <param name="key">The key to search for</param> 447 /// <param name="BufferSize"> 448 /// The initial size of the buffer to fill with duplicate data items. If 449 /// the buffer is not large enough, it is automatically resized. 450 /// </param> 451 /// <param name="txn"> 452 /// <paramref name="txn"/> is a Transaction object returned from 453 /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if 454 /// the operation is part of a Berkeley DB Concurrent Data Store group, 455 /// <paramref name="txn"/> is a handle returned from 456 /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. 457 /// </param> 458 /// <returns> 459 /// A <see cref="KeyValuePair{T,T}"/> 460 /// whose Key parameter is <paramref name="key"/> and whose Value 461 /// parameter is the retrieved data items. 462 /// </returns> GetMultiple( DatabaseEntry key, int BufferSize, Transaction txn)463 public KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> GetMultiple( 464 DatabaseEntry key, int BufferSize, Transaction txn) { 465 return GetMultiple(key, BufferSize, txn, null); 466 } 467 /// <summary> 468 /// Retrieve a key and all duplicate data items from the database. 469 /// </summary> 470 /// <param name="key">The key to search for</param> 471 /// <param name="BufferSize"> 472 /// The initial size of the buffer to fill with duplicate data items. If 473 /// the buffer is not large enough, it is automatically resized. 474 /// </param> 475 /// <param name="txn"> 476 /// <paramref name="txn"/> is a Transaction object returned from 477 /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if 478 /// the operation is part of a Berkeley DB Concurrent Data Store group, 479 /// <paramref name="txn"/> is a handle returned from 480 /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. 481 /// </param> 482 /// <param name="info">The locking behavior to use.</param> 483 /// <returns> 484 /// A <see cref="KeyValuePair{T,T}"/> 485 /// whose Key parameter is <paramref name="key"/> and whose Value 486 /// parameter is the retrieved data items. 487 /// </returns> GetMultiple( DatabaseEntry key, int BufferSize, Transaction txn, LockingInfo info)488 public KeyValuePair<DatabaseEntry, MultipleDatabaseEntry> GetMultiple( 489 DatabaseEntry key, 490 int BufferSize, Transaction txn, LockingInfo info) { 491 KeyValuePair<DatabaseEntry, DatabaseEntry> kvp; 492 493 DatabaseEntry data = new DatabaseEntry(); 494 for (; ; ) { 495 data.UserData = new byte[BufferSize]; 496 try { 497 kvp = Get(key, data, txn, info, DbConstants.DB_MULTIPLE); 498 break; 499 } catch (MemoryException) { 500 int sz = (int)data.size; 501 if (sz > BufferSize) 502 BufferSize = sz; 503 else 504 BufferSize *= 2; 505 } 506 } 507 MultipleDatabaseEntry dbe = new MultipleDatabaseEntry(kvp.Value); 508 return new KeyValuePair<DatabaseEntry, MultipleDatabaseEntry>( 509 kvp.Key, dbe); 510 } 511 512 /// <summary> 513 /// Create a specialized join cursor for use in performing equality or 514 /// natural joins on secondary indices. 515 /// </summary> 516 /// <remarks> 517 /// <para> 518 /// Once the cursors have been passed as part of <paramref name="lst"/>, 519 /// they should not be accessed or modified until the newly created 520 /// <see cref="JoinCursor"/>has been closed, or else inconsistent 521 /// results may be returned. 522 /// </para> 523 /// <para> 524 /// Joined values are retrieved by doing a sequential iteration over the 525 /// first cursor in <paramref name="lst"/>, and a nested iteration over 526 /// each secondary cursor in the order they are specified in the 527 /// curslist parameter. This requires database traversals to search for 528 /// the current datum in all the cursors after the first. For this 529 /// reason, the best join performance normally results from sorting the 530 /// cursors from the one that refers to the least number of data items 531 /// to the one that refers to the most. 532 /// </para> 533 /// </remarks> 534 /// <param name="lst"> 535 /// An array of SecondaryCursors. Each cursor must have been initialized 536 /// to refer to the key on which the underlying database should be 537 /// joined. 538 /// </param> 539 /// <param name="sortCursors"> 540 /// If true, sort the cursors from the one that refers to the least 541 /// number of data items to the one that refers to the most. If the 542 /// data is structured so that cursors with many data items also share 543 /// many common elements, higher performance results from listing 544 /// those cursors before cursors with fewer data items; a sort 545 /// order other than the default. A setting of false permits 546 /// applications to perform join optimization prior to calling Join. 547 /// </param> 548 /// <returns> 549 /// A specialized join cursor for use in performing equality or natural 550 /// joins on secondary indices. 551 /// </returns> Join(SecondaryCursor[] lst, bool sortCursors)552 public JoinCursor Join(SecondaryCursor[] lst, bool sortCursors) { 553 int i; 554 IntPtr[] cursList = new IntPtr[lst.Length + 1]; 555 for (i = 0; i < lst.Length; i++) 556 cursList[i] = DBC.getCPtr( 557 SecondaryCursor.getDBC(lst[i])).Handle; 558 cursList[i] = IntPtr.Zero; 559 return new JoinCursor(db.join(cursList, 560 sortCursors ? 0 : DbConstants.DB_JOIN_NOSORT)); 561 } 562 563 /// <summary> 564 /// Store multiple data items using keys from the buffer to which the 565 /// key parameter refers and data values from the buffer to which the 566 /// data parameter refers. A successful bulk operation is logically 567 /// equivalent to a loop through each key/data pair, performing a Put 568 /// for each one. 569 /// </summary> 570 /// <remarks> 571 /// 572 /// </remarks> 573 /// <param name="key">Multiple key/data pairs to store in the database 574 /// </param> Put(MultipleKeyDatabaseEntry key)575 public void Put(MultipleKeyDatabaseEntry key) { 576 Put(key, null, null); 577 } 578 579 /// <summary> 580 /// Store the key/data pair in the database, replacing any previously 581 /// existing key if duplicates are disallowed, or adding a duplicate 582 /// data item if duplicates are allowed. 583 /// </summary> 584 /// <overloads> 585 /// <para> 586 /// If the database supports duplicates, add the new data value at the 587 /// end of the duplicate set. If the database supports sorted 588 /// duplicates, the new data value is inserted at the correct sorted 589 /// location. 590 /// </para> 591 /// </overloads> 592 /// <param name="key">The key to store in the database</param> 593 /// <param name="data">The data item to store in the database</param> 594 /// <exception cref="DatabaseException"> 595 /// Partial put to a duplicate database, or <see cref="QueueDatabase"/> 596 /// or <see cref="RecnoDatabase"/> with fixed-length records. 597 /// </exception> Put(DatabaseEntry key, DatabaseEntry data)598 public void Put(DatabaseEntry key, DatabaseEntry data) { 599 Put(key, data, null); 600 } 601 602 /// <summary> 603 /// Store multiple data items using keys from the buffer to which the 604 /// key parameter refers and data values from the buffer to which the 605 /// data parameter refers. A successful bulk operation is logically 606 /// equivalent to a loop through each key/data pair, performing a Put 607 /// for each one. 608 /// </summary> 609 /// <param name="key">Multiple key/data pairs to store in the database 610 /// </param> 611 /// <param name="txn"> 612 /// If the operation is part of an application-specified transaction, 613 /// <paramref name="txn"/> is a Transaction object returned from 614 /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if 615 /// the operation is part of a Berkeley DB Concurrent Data Store group, 616 /// <paramref name="txn"/> is a handle returned from 617 /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. 618 /// </param> Put(MultipleKeyDatabaseEntry key, Transaction txn)619 public void Put(MultipleKeyDatabaseEntry key, Transaction txn) { 620 Put(key, null, txn, 0); 621 } 622 623 /// <summary> 624 /// Store the key/data pair in the database, replacing any previously 625 /// existing key if duplicates are disallowed, or adding a duplicate 626 /// data item if duplicates are allowed. 627 /// </summary> 628 /// <remarks> 629 /// <para> 630 /// When partial put to a duplicate database, a 631 /// <see cref="DatabaseException"/> is thrown. 632 /// </para> 633 /// </remarks> 634 /// <param name="key">The key to store in the database</param> 635 /// <param name="data">The data item to store in the database</param> 636 /// <param name="txn"> 637 /// If the operation is part of an application-specified transaction, 638 /// <paramref name="txn"/> is a Transaction object returned from 639 /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if 640 /// the operation is part of a Berkeley DB Concurrent Data Store group, 641 /// <paramref name="txn"/> is a handle returned from 642 /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. 643 /// </param> 644 /// <exception cref="DatabaseException"> 645 /// Partial put to a duplicate database, or <see cref="QueueDatabase"/> 646 /// or <see cref="RecnoDatabase"/> with fixed-length records. 647 /// </exception> Put( DatabaseEntry key, DatabaseEntry data, Transaction txn)648 public void Put( 649 DatabaseEntry key, DatabaseEntry data, Transaction txn) { 650 Put(key, data, txn, 0); 651 } 652 653 /// <summary> 654 /// Store the key/data pairs in the database, only if the key does not 655 /// already appear in the database. 656 /// </summary> 657 /// <param name="key">Key/data pairs to store in the database</param> PutNoOverwrite(MultipleKeyDatabaseEntry key)658 public void PutNoOverwrite(MultipleKeyDatabaseEntry key) { 659 PutNoOverwrite(key, null, null); 660 } 661 662 /// <summary> 663 /// Store the key/data pair in the database, only if the key does not 664 /// already appear in the database. 665 /// </summary> 666 /// <remarks> 667 /// This enforcement of uniqueness of keys applies only to the primary 668 /// key, the behavior of insertions into secondary databases is not 669 /// affected. In particular, the insertion of a record that would result 670 /// in the creation of a duplicate key in a secondary database that 671 /// allows duplicates would not be prevented by the use of this flag. 672 /// </remarks> 673 /// <param name="key">The key to store in the database</param> 674 /// <param name="data">The data item to store in the database</param> PutNoOverwrite(DatabaseEntry key, DatabaseEntry data)675 public void PutNoOverwrite(DatabaseEntry key, DatabaseEntry data) { 676 PutNoOverwrite(key, data, null); 677 } 678 679 /// <summary> 680 /// Store the key/data pairs in the database, only if the key does not 681 /// already appear in the database. 682 /// </summary> 683 /// <param name="key">Key/data pairs to store in the database</param> 684 /// <param name="txn"> 685 /// If the operation is part of an application-specified transaction, 686 /// <paramref name="txn"/> is a Transaction object returned from 687 /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if 688 /// the operation is part of a Berkeley DB Concurrent Data Store group, 689 /// <paramref name="txn"/> is a handle returned from 690 /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. 691 /// </param> PutNoOverwrite( MultipleKeyDatabaseEntry key, Transaction txn)692 public void PutNoOverwrite( 693 MultipleKeyDatabaseEntry key, Transaction txn) { 694 Put(key, null, txn, DbConstants.DB_NOOVERWRITE); 695 } 696 697 /// <summary> 698 /// Store the key/data pair in the database, only if the key does not 699 /// already appear in the database. 700 /// </summary> 701 /// <remarks> 702 /// This enforcement of uniqueness of keys applies only to the primary 703 /// key, the behavior of insertions into secondary databases is not 704 /// affected. In particular, the insertion of a record that would result 705 /// in the creation of a duplicate key in a secondary database that 706 /// allows duplicates would not be prevented by the use of this flag. 707 /// </remarks> 708 /// <param name="key">The key to store in the database</param> 709 /// <param name="data">The data item to store in the database</param> 710 /// <param name="txn"> 711 /// If the operation is part of an application-specified transaction, 712 /// <paramref name="txn"/> is a Transaction object returned from 713 /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if 714 /// the operation is part of a Berkeley DB Concurrent Data Store group, 715 /// <paramref name="txn"/> is a handle returned from 716 /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. 717 /// </param> PutNoOverwrite( DatabaseEntry key, DatabaseEntry data, Transaction txn)718 public void PutNoOverwrite( 719 DatabaseEntry key, DatabaseEntry data, Transaction txn) { 720 Put(key, data, txn, DbConstants.DB_NOOVERWRITE); 721 } 722 723 /// <summary> 724 /// Protected wrapper for DB->put. Used by subclasses for access method 725 /// specific operations. 726 /// </summary> 727 /// <param name="key">The key to store in the database</param> 728 /// <param name="data">The data item to store in the database</param> 729 /// <param name="txn">Transaction with which to protect the put</param> 730 /// <param name="flags">Flags to pass to DB->put</param> Put(DatabaseEntry key, DatabaseEntry data, Transaction txn, uint flags)731 protected void Put(DatabaseEntry key, 732 DatabaseEntry data, Transaction txn, uint flags) { 733 System.Type type = key.GetType(); 734 if (type == typeof(MultipleDatabaseEntry)) 735 flags |= DbConstants.DB_MULTIPLE; 736 else if (type == typeof(MultipleKeyDatabaseEntry)) 737 flags |= DbConstants.DB_MULTIPLE_KEY; 738 db.put(Transaction.getDB_TXN(txn), key, data, flags); 739 } 740 741 /// <summary> 742 /// Write the key/data pairs from all databases in the file to 743 /// <see cref="Console.Out"/>. Key values are written for Btree, Hash 744 /// and Queue databases, but not for Recno databases. 745 /// </summary> 746 /// <param name="file"> 747 /// The physical file in which the databases to be salvaged are found. 748 /// </param> 749 /// <param name="cfg"> 750 /// Configuration parameters for the databases to be salvaged. 751 /// </param> Salvage(string file, DatabaseConfig cfg)752 public static void Salvage(string file, DatabaseConfig cfg) { 753 Salvage(file, cfg, false, false, null); 754 } 755 /// <summary> 756 /// Write the key/data pairs from all databases in the file to 757 /// <see cref="Console.Out"/>. Key values are written for Btree, Hash 758 /// and Queue databases, but not for Recno databases. 759 /// </summary> 760 /// <param name="file"> 761 /// The physical file in which the databases to be salvaged are found. 762 /// </param> 763 /// <param name="cfg"> 764 /// Configuration parameters for the databases to be salvaged. 765 /// </param> 766 /// <param name="Printable"> 767 /// If true and characters in either the key or data items are printing 768 /// characters (as defined by isprint(3)), use printing characters to 769 /// represent them. This setting permits users to use standard text 770 /// editors and tools to modify the contents of databases or selectively 771 /// remove data from salvager output. 772 /// </param> Salvage( string file, DatabaseConfig cfg, bool Printable)773 public static void Salvage( 774 string file, DatabaseConfig cfg, bool Printable) { 775 Salvage(file, cfg, Printable, false, null); 776 } 777 /// <summary> 778 /// Write the key/data pairs from all databases in the file to 779 /// <paramref name="OutputStream"/>. Key values are written for Btree, 780 /// Hash and Queue databases, but not for Recno databases. 781 /// </summary> 782 /// <param name="file"> 783 /// The physical file in which the databases to be salvaged are found. 784 /// </param> 785 /// <param name="cfg"> 786 /// Configuration parameters for the databases to be salvaged. 787 /// </param> 788 /// <param name="OutputStream"> 789 /// The TextWriter to which the databases' key/data pairs are written. 790 /// If null, <see cref="Console.Out"/> is used. 791 /// </param> Salvage( string file, DatabaseConfig cfg, TextWriter OutputStream)792 public static void Salvage( 793 string file, DatabaseConfig cfg, TextWriter OutputStream) { 794 Salvage(file, cfg, false, false, OutputStream); 795 } 796 /// <summary> 797 /// Write the key/data pairs from all databases in the file to 798 /// <paramref name="OutputStream"/>. Key values are written for Btree, 799 /// Hash and Queue databases, but not for Recno databases. 800 /// </summary> 801 /// <param name="file"> 802 /// The physical file in which the databases to be salvaged are found. 803 /// </param> 804 /// <param name="cfg"> 805 /// Configuration parameters for the databases to be salvaged. 806 /// </param> 807 /// <param name="Printable"> 808 /// If true and characters in either the key or data items are printing 809 /// characters (as defined by isprint(3)), use printing characters to 810 /// represent them. This setting permits users to use standard text 811 /// editors and tools to modify the contents of databases or selectively 812 /// remove data from salvager output. 813 /// </param> 814 /// <param name="OutputStream"> 815 /// The TextWriter to which the databases' key/data pairs are written. 816 /// If null, <see cref="Console.Out"/> is used. 817 /// </param> Salvage(string file, DatabaseConfig cfg, bool Printable, TextWriter OutputStream)818 public static void Salvage(string file, 819 DatabaseConfig cfg, bool Printable, TextWriter OutputStream) { 820 Salvage(file, cfg, Printable, false, OutputStream); 821 } 822 /// <summary> 823 /// Write the key/data pairs from all databases in the file to 824 /// <see cref="Console.Out"/>. Key values are written for Btree, Hash 825 /// and Queue databases, but not for Recno databases. 826 /// </summary> 827 /// <param name="file"> 828 /// The physical file in which the databases to be salvaged are found. 829 /// </param> 830 /// <param name="cfg"> 831 /// Configuration parameters for the databases to be salvaged. 832 /// </param> 833 /// <param name="Printable"> 834 /// If true and characters in either the key or data items are printing 835 /// characters (as defined by isprint(3)), use printing characters to 836 /// represent them. This setting permits users to use standard text 837 /// editors and tools to modify the contents of databases or selectively 838 /// remove data from salvager output. 839 /// </param> 840 /// <param name="Aggressive"> 841 /// If true, output all the key/data pairs found in the file. 842 /// Corruption of these data pairs is assumed, and corrupted or deleted 843 /// data pairs may appear in the output (even if the salvaged file is in no 844 /// way corrupt). This output almost certainly requires editing before being 845 /// loaded into a database. 846 /// </param> Salvage(string file, DatabaseConfig cfg, bool Printable, bool Aggressive)847 public static void Salvage(string file, 848 DatabaseConfig cfg, bool Printable, bool Aggressive) { 849 Salvage(file, cfg, Printable, Aggressive, null); 850 } 851 /// <summary> 852 /// Write the key/data pairs from all databases in the file to 853 /// <paramref name="OutputStream"/>. Key values are written for Btree, 854 /// Hash and Queue databases, but not for Recno databases. 855 /// </summary> 856 /// <param name="file"> 857 /// The physical file in which the databases to be salvaged are found. 858 /// </param> 859 /// <param name="cfg"> 860 /// Configuration parameters for the databases to be salvaged. 861 /// </param> 862 /// <param name="Printable"> 863 /// If true and characters in either the key or data items are printing 864 /// characters (as defined by isprint(3)), use printing characters to 865 /// represent them. This setting permits users to use standard text 866 /// editors and tools to modify the contents of databases or selectively 867 /// remove data from salvager output. 868 /// </param> 869 /// <param name="Aggressive"> 870 /// If true, output all the key/data pairs found in the file. 871 /// Corruption of these data pairs is assumed, and corrupted or deleted 872 /// data pairs may appear in the output (even if the salvaged file is in no 873 /// way corrupt). This output almost certainly requires editing before being 874 /// loaded into a database. 875 /// </param> 876 /// <param name="OutputStream"> 877 /// The TextWriter to which the databases' key/data pairs are written. 878 /// If null, <see cref="Console.Out"/> is used. 879 /// </param> Salvage(string file, DatabaseConfig cfg, bool Printable, bool Aggressive, TextWriter OutputStream)880 public static void Salvage(string file, DatabaseConfig cfg, 881 bool Printable, bool Aggressive, TextWriter OutputStream) { 882 using (Database db = new Database(cfg.Env, 0)) { 883 db.Config(cfg); 884 if (OutputStream == null) 885 OutputStream = Console.Out; 886 uint flags = DbConstants.DB_SALVAGE; 887 flags |= Aggressive ? DbConstants.DB_AGGRESSIVE : 0; 888 flags |= Printable ? DbConstants.DB_PRINTABLE : 0; 889 writeToFileRef = new BDB_FileWriteDelegate(writeToFile); 890 db.db.verify(file, null, OutputStream, writeToFileRef, flags); 891 } 892 } 893 894 /// <summary> 895 /// Upgrade all of the databases included in the file 896 /// <paramref name="file"/>, if necessary. If no upgrade is necessary, 897 /// Upgrade always returns successfully. 898 /// </summary> 899 /// <param name="file"> 900 /// The physical file containing the databases to be upgraded. 901 /// </param> 902 /// <param name="cfg"> 903 /// Configuration parameters for the databases to be upgraded. 904 /// </param> Upgrade(string file, DatabaseConfig cfg)905 public static void Upgrade(string file, DatabaseConfig cfg) { 906 Upgrade(file, cfg, false); 907 } 908 /// <summary> 909 /// Upgrade all of the databases included in the file 910 /// <paramref name="file"/>, if necessary. If no upgrade is necessary, 911 /// Upgrade always returns successfully. 912 /// </summary> 913 /// <overloads> 914 /// Database upgrades are done in place and are destructive. For 915 /// example, if pages need to be allocated and no disk space is 916 /// available, the database may be left corrupted. Backups should be 917 /// made before databases are upgraded. See Upgrading databases in the 918 /// Programmer's Reference Guide for more information. 919 /// </overloads> 920 /// <remarks> 921 /// <para> 922 /// As part of the upgrade from the Berkeley DB 3.0 release to the 3.1 923 /// release, the on-disk format of duplicate data items changed. To 924 /// correctly upgrade the format requires applications to specify 925 /// whether duplicate data items in the database are sorted or not. 926 /// Specifying <paramref name="dupSortUpgraded"/> informs Upgrade that 927 /// the duplicates are sorted; otherwise they are assumed to be 928 /// unsorted. Incorrectly specifying the value of this flag may lead to 929 /// database corruption. 930 /// </para> 931 /// <para> 932 /// Further, because this method upgrades a physical file (including all 933 /// the databases it contains), it is not possible to use Upgrade to 934 /// upgrade files in which some of the databases it includes have sorted 935 /// duplicate data items, and some of the databases it includes have 936 /// unsorted duplicate data items. If the file does not have more than a 937 /// single database, if the databases do not support duplicate data 938 /// items, or if all of the databases that support duplicate data items 939 /// support the same style of duplicates (either sorted or unsorted), 940 /// Upgrade works correctly as long as 941 /// <paramref name="dupSortUpgraded"/> is correctly specified. 942 /// Otherwise, the file cannot be upgraded using Upgrade it must be 943 /// upgraded manually by dumping and reloading the databases. 944 /// </para> 945 /// </remarks> 946 /// <param name="file"> 947 /// The physical file containing the databases to be upgraded. 948 /// </param> 949 /// <param name="cfg"> 950 /// Configuration parameters for the databases to be upgraded. 951 /// </param> 952 /// <param name="dupSortUpgraded"> 953 /// If true, the duplicates in the upgraded database are sorted; 954 /// otherwise they are assumed to be unsorted. This setting is only 955 /// meaningful when upgrading databases from releases before the 956 /// Berkeley DB 3.1 release. 957 /// </param> Upgrade( string file, DatabaseConfig cfg, bool dupSortUpgraded)958 public static void Upgrade( 959 string file, DatabaseConfig cfg, bool dupSortUpgraded) { 960 Database db = new Database(cfg.Env, 0); 961 db.Config(cfg); 962 db.db.upgrade(file, dupSortUpgraded ? DbConstants.DB_DUPSORT : 0); 963 } 964 965 /// <summary> 966 /// Convert all of the databases included in the file 967 /// <paramref name="file"/> to the byte order 968 /// <paramref name="use_big_endian"/>, if necessary. If no conversion 969 /// is necessary, Convert always returns successfully. If the database 970 /// is partitioned, <paramref name="cfg"/> must contain the correct 971 /// partition configuration in order to convert database partitions. 972 /// </summary> 973 /// <overloads> 974 /// Database conversions are done in place and are destructive. For 975 /// example, if the conversion is interrupted, the database may be 976 /// left corrupted. Backups should be made before databases are 977 /// converted. 978 /// </overloads> 979 /// <param name="file"> 980 /// The physical file containing the databases to be converted. 981 /// </param> 982 /// <param name="cfg"> 983 /// Configuration parameters for the databases to be converted. 984 /// </param> 985 /// <param name="useBigEndian"> 986 /// If true, the databases are converted to big-endian; otherwise 987 /// they are converted to little-endian. 988 /// </param> Convert( string file, DatabaseConfig cfg, bool useBigEndian)989 public static void Convert( 990 string file, DatabaseConfig cfg, bool useBigEndian) { 991 Database db = new Database(cfg.Env, 0); 992 db.Config(cfg); 993 db.db.convert(file, useBigEndian ? 4321 : 1234); 994 } 995 996 /// <summary> 997 /// Specifies the type of verification to perform 998 /// </summary> 999 public enum VerifyOperation { 1000 /// <summary> 1001 /// Perform database checks and check sort order 1002 /// </summary> 1003 DEFAULT, 1004 /// <summary> 1005 /// Perform the database checks for btree and duplicate sort order 1006 /// and for hashing 1007 /// </summary> 1008 ORDER_CHECK_ONLY, 1009 /// <summary> 1010 /// Skip the database checks for btree and duplicate sort order and 1011 /// for hashing. 1012 /// </summary> 1013 NO_ORDER_CHECK 1014 }; 1015 /// <summary> 1016 /// Verify the integrity of all databases in the file specified by 1017 /// <paramref name="file"/>. 1018 /// </summary> 1019 /// <overloads> 1020 /// Verify does not perform any locking, even in Berkeley DB 1021 /// environments that are configured with a locking subsystem. As such, 1022 /// it should only be used on files that are not being modified by 1023 /// another thread of control. 1024 /// </overloads> 1025 /// <param name="file"> 1026 /// The physical file in which the databases to be verified are found. 1027 /// </param> 1028 /// <param name="cfg"> 1029 /// Configuration parameters for the databases to be verified. 1030 /// </param> Verify(string file, DatabaseConfig cfg)1031 public static void Verify(string file, DatabaseConfig cfg) { 1032 Verify(file, null, cfg, VerifyOperation.DEFAULT); 1033 } 1034 /// <summary> 1035 /// Verify the integrity of all databases in the file specified by 1036 /// <paramref name="file"/>. 1037 /// </summary> 1038 /// <remarks> 1039 /// <para> 1040 /// Berkeley DB normally verifies that btree keys and duplicate items 1041 /// are correctly sorted, and hash keys are correctly hashed. If the 1042 /// file being verified contains multiple databases using differing 1043 /// sorting or hashing algorithms, some of them must necessarily fail 1044 /// database verification because only one sort order or hash function 1045 /// can be specified in <paramref name="cfg"/>. To verify files with 1046 /// multiple databases having differing sorting orders or hashing 1047 /// functions, first perform verification of the file as a whole by 1048 /// using <see cref="VerifyOperation.NO_ORDER_CHECK"/>, and then 1049 /// individually verify the sort order and hashing function for each 1050 /// database in the file using 1051 /// <see cref="VerifyOperation.ORDER_CHECK_ONLY"/>. 1052 /// </para> 1053 /// </remarks> 1054 /// <param name="file"> 1055 /// The physical file in which the databases to be verified are found. 1056 /// </param> 1057 /// <param name="cfg"> 1058 /// Configuration parameters for the databases to be verified. 1059 /// </param> 1060 /// <param name="op">The extent of verification</param> Verify( string file, DatabaseConfig cfg, VerifyOperation op)1061 public static void Verify( 1062 string file, DatabaseConfig cfg, VerifyOperation op) { 1063 Verify(file, null, cfg, op); 1064 } 1065 /// <summary> 1066 /// Verify the integrity of the database specified by 1067 /// <paramref name="file"/> and <paramref name="database"/>. 1068 /// </summary> 1069 /// <remarks> 1070 /// <para> 1071 /// Berkeley DB normally verifies that btree keys and duplicate items 1072 /// are correctly sorted, and hash keys are correctly hashed. If the 1073 /// file being verified contains multiple databases using differing 1074 /// sorting or hashing algorithms, some of them must necessarily fail 1075 /// database verification because only one sort order or hash function 1076 /// can be specified in <paramref name="cfg"/>. To verify files with 1077 /// multiple databases having differing sorting orders or hashing 1078 /// functions, first perform verification of the file as a whole by 1079 /// using <see cref="VerifyOperation.NO_ORDER_CHECK"/>, and then 1080 /// individually verify the sort order and hashing function for each 1081 /// database in the file using 1082 /// <see cref="VerifyOperation.ORDER_CHECK_ONLY"/>. 1083 /// </para> 1084 /// </remarks> 1085 /// <param name="file"> 1086 /// The physical file in which the databases to be verified are found. 1087 /// </param> 1088 /// <param name="database"> 1089 /// The database in <paramref name="file"/> on which the database checks 1090 /// for btree and duplicate sort order and for hashing are to be 1091 /// performed. A non-null value for database is only allowed with 1092 /// <see cref="VerifyOperation.ORDER_CHECK_ONLY"/>. 1093 /// </param> 1094 /// <param name="cfg"> 1095 /// Configuration parameters for the databases to be verified. 1096 /// </param> 1097 /// <param name="op">The extent of verification</param> Verify(string file, string database, DatabaseConfig cfg, VerifyOperation op)1098 public static void Verify(string file, 1099 string database, DatabaseConfig cfg, VerifyOperation op) { 1100 using (Database db = new Database(cfg.Env, 0)) { 1101 db.Config(cfg); 1102 uint flags; 1103 switch (op) { 1104 case VerifyOperation.NO_ORDER_CHECK: 1105 flags = DbConstants.DB_NOORDERCHK; 1106 break; 1107 case VerifyOperation.ORDER_CHECK_ONLY: 1108 flags = DbConstants.DB_ORDERCHKONLY; 1109 break; 1110 case VerifyOperation.DEFAULT: 1111 default: 1112 flags = 0; 1113 break; 1114 } 1115 db.db.verify(file, database, null, null, flags); 1116 } 1117 } 1118 #endregion Methods 1119 } 1120 } 1121