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