Imported Upstream version 5.3.21
[platform/upstream/libdb.git] / lang / csharp / src / DatabaseEnvironment.cs
1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2009, 2012 Oracle and/or its affiliates.  All rights reserved.
5  *
6  */
7 using System;
8 using System.Collections.Generic;
9 using System.Runtime.InteropServices;
10 using System.Text;
11 using BerkeleyDB.Internal;
12
13 namespace BerkeleyDB {
14     /// <summary>
15     /// A class representing a Berkeley DB database environment - a collection
16     /// including support for some or all of caching, locking, logging and
17     /// transaction subsystems, as well as databases and log files.
18     /// </summary>
19     public class DatabaseEnvironment {
20         internal DB_ENV dbenv;
21         private IBackup backupObj;
22         private ErrorFeedbackDelegate errFeedbackHandler;
23         private EnvironmentFeedbackDelegate feedbackHandler;
24         private ThreadIsAliveDelegate isAliveHandler;
25         private EventNotifyDelegate notifyHandler;
26         private MessageDispatchDelegate messageDispatchHandler;
27         private ReplicationTransportDelegate transportHandler;
28         private SetThreadIDDelegate threadIDHandler;
29         private SetThreadNameDelegate threadNameHandler;
30         private string _pfx;
31         private DBTCopyDelegate CopyDelegate;
32         private BDB_BackupCloseDelegate doBackupCloseRef;
33         private BDB_BackupOpenDelegate doBackupOpenRef;
34         private BDB_BackupWriteDelegate doBackupWriteRef;
35         private BDB_ErrcallDelegate doErrFeedbackRef;
36         private BDB_EnvFeedbackDelegate doFeedbackRef;
37         private BDB_EventNotifyDelegate doNotifyRef;
38         private BDB_IsAliveDelegate doIsAliveRef;
39         private BDB_MessageDispatchDelegate doMessageDispatchRef;
40         private BDB_RepTransportDelegate doRepTransportRef;
41         private BDB_ThreadIDDelegate doThreadIDRef;
42         private BDB_ThreadNameDelegate doThreadNameRef;
43
44         private static long GIGABYTE = (long)(1 << 30);
45
46         #region Callbacks
47         private static int doBackupClose(IntPtr env, string dbname, IntPtr handle) {
48             DB_ENV dbenv = new DB_ENV(env, false);
49             return dbenv.api2_internal.backupObj.Close(dbname);
50         }
51         private static int doBackupOpen(IntPtr env, string dbname, string target, IntPtr handle) {
52             DB_ENV dbenv = new DB_ENV(env, false);
53             return dbenv.api2_internal.backupObj.Open(dbname, target);
54         }
55         private static int doBackupWrite(IntPtr env, uint off_gbytes, uint off_bytes, uint usize, IntPtr buf, IntPtr handle) {
56             int ret, size;
57             long offset = off_gbytes * GIGABYTE + off_bytes;
58             DB_ENV dbenv = new DB_ENV(env, false);
59             if (usize > Int32.MaxValue)
60                 size = Int32.MaxValue;
61             else
62                 size = (int)usize;
63             byte[] data = new byte[size];
64             Marshal.Copy(buf, data, 0, (int)size);
65             ret = dbenv.api2_internal.backupObj.Write(data, offset, (int)size);
66             if (ret == 0 && usize > Int32.MaxValue) {
67                 size = (int)(usize - Int32.MaxValue);
68                 /* 
69                  * There's no need to re-allocate data, it's already as large as
70                  * we could possibly need it to be.  Advance buf beyond what was
71                  * just copied and write the remaining data.
72                  */
73                 buf = new IntPtr(buf.ToInt64() + Int32.MaxValue);
74                 Marshal.Copy(buf, data, 0, (int)size);
75                 ret = dbenv.api2_internal.backupObj.Write(data, offset, (int)size);
76             }
77             return ret;
78         }
79         private static void doNotify(IntPtr env, uint eventcode, byte[] event_info) {
80             DB_ENV dbenv = new DB_ENV(env, false);
81             
82             dbenv.api2_internal.notifyHandler(
83                 (NotificationEvent)eventcode, event_info);
84         }
85         private static void doErrFeedback(IntPtr env, string pfx, string msg) {
86             DB_ENV dbenv = new DB_ENV(env, false);
87             dbenv.api2_internal.errFeedbackHandler(
88                 dbenv.api2_internal._pfx, msg);
89         }
90         private static void doFeedback(IntPtr env, int opcode, int percent) {
91             DB_ENV dbenv = new DB_ENV(env, false);
92             dbenv.api2_internal.feedbackHandler(
93                 (EnvironmentFeedbackEvent)opcode, percent);
94         }
95         private static int doIsAlive(IntPtr env, int pid, uint tid, uint flags) {
96             DB_ENV dbenv = new DB_ENV(env, false);
97             DbThreadID id = new DbThreadID(pid, tid);
98             bool procOnly = (flags == DbConstants.DB_MUTEX_PROCESS_ONLY);
99             return dbenv.api2_internal.isAliveHandler(id, procOnly) ? 1 : 0;
100         }
101         private static void doMessageDispatch(IntPtr env, IntPtr channel,
102             IntPtr requestp, uint nrequest, uint cb_flags) {
103             DB_ENV dbenv = new DB_ENV(env, false);
104             DbChannel dbchannel = new DbChannel(new DB_CHANNEL(channel, false));
105             bool need_response = 
106                 (cb_flags == DbConstants.DB_REPMGR_NEED_RESPONSE);
107             IntPtr[] reqp = new IntPtr[nrequest];
108             Marshal.Copy(requestp, reqp, 0, (int)nrequest);
109             DatabaseEntry[] requests = new DatabaseEntry[nrequest];
110             for (int i = 0; i < nrequest; i++) {
111                 requests[i] = DatabaseEntry.fromDBT(new DBT(reqp[i], false));
112             }
113             dbenv.api2_internal.messageDispatchHandler(
114                 dbchannel, ref requests, out nrequest, need_response);
115         }
116         private static int doRepTransport(IntPtr envp,
117             IntPtr controlp, IntPtr recp, IntPtr lsnp, int envid, uint flags) {
118             DB_ENV dbenv = new DB_ENV(envp, false);
119             DBT control = new DBT(controlp, false);
120             DBT rec = new DBT(recp, false);
121             DB_LSN tmplsn = new DB_LSN(lsnp, false);
122             LSN dblsn = new LSN(tmplsn.file, tmplsn.offset);
123             return dbenv.api2_internal.transportHandler(
124                 DatabaseEntry.fromDBT(control),
125                 DatabaseEntry.fromDBT(rec), dblsn, envid, flags);
126         }
127         private static void doThreadID(IntPtr env, IntPtr pid, IntPtr tid) {
128             DB_ENV dbenv = new DB_ENV(env, false);
129             DbThreadID id = dbenv.api2_internal.threadIDHandler();
130
131             /* 
132              * Sometimes the library doesn't care about either pid or tid 
133              * (usually tid) and will pass NULL instead of a valid pointer.
134              */
135             if (pid != IntPtr.Zero)
136                 Marshal.WriteInt32(pid, id.processID);
137             if (tid != IntPtr.Zero)
138                 Marshal.WriteInt32(tid, (int)id.threadID);
139         }
140         private static string doThreadName(IntPtr env,
141             int pid, uint tid, ref string buf) {
142             DB_ENV dbenv = new DB_ENV(env, false);
143             DbThreadID id = new DbThreadID(pid, tid);
144             string ret = 
145                 dbenv.api2_internal.threadNameHandler(id);
146             try {
147                 buf = ret;
148             } catch (NullReferenceException) {
149                 /* 
150                  * The library may give us a NULL pointer in buf and there's no
151                  * good way to test for that.  Just ignore the exception if
152                  * we're not able to set buf.
153                  */
154             }
155             return ret;
156         }
157         
158         #endregion Callbacks
159         private DatabaseEnvironment(uint flags) {
160             dbenv = new DB_ENV(flags);
161             initialize();
162         }
163
164         /* Called by Databases with private environments. */
165         internal DatabaseEnvironment(DB_ENV dbenvp) {
166             dbenv = dbenvp;
167             initialize();
168         }
169
170         private void initialize() {
171             dbenv.api2_internal = this;
172             CopyDelegate = new DBTCopyDelegate(DatabaseEntry.dbt_usercopy);
173             dbenv.set_usercopy(CopyDelegate);
174         }
175
176         private void Config(DatabaseEnvironmentConfig cfg) {
177             //Alpha by dbenv function call
178             foreach (string dirname in cfg.DataDirs)
179                 dbenv.add_data_dir(dirname);
180             if (cfg.CreationDir != null)
181                 dbenv.set_create_dir(cfg.CreationDir);
182             if (cfg.encryptionIsSet)
183                 dbenv.set_encrypt(
184                     cfg.EncryptionPassword, (uint)cfg.EncryptAlgorithm);
185             if (cfg.MetadataDir != null)
186                 dbenv.set_metadata_dir(cfg.MetadataDir);
187             if (cfg.ErrorFeedback != null)
188                 ErrorFeedback = cfg.ErrorFeedback;
189             ErrorPrefix = cfg.ErrorPrefix;
190             if (cfg.EventNotify != null)
191                 EventNotify = cfg.EventNotify;
192             if (cfg.Feedback != null)
193                 Feedback = cfg.Feedback;
194             if (cfg.IntermediateDirMode != null)
195                 IntermediateDirMode = cfg.IntermediateDirMode;
196             if (cfg.ThreadIsAlive != null)
197                 ThreadIsAlive = cfg.ThreadIsAlive;
198             if (cfg.threadCntIsSet)
199                 ThreadCount = cfg.ThreadCount;
200             if (cfg.SetThreadID != null)
201                 SetThreadID = cfg.SetThreadID;
202             if (cfg.ThreadName != null)
203                 threadNameHandler = cfg.ThreadName;
204             if (cfg.lckTimeoutIsSet)
205                 LockTimeout = cfg.LockTimeout;
206             if (cfg.txnTimeoutIsSet)
207                 TxnTimeout = cfg.TxnTimeout;
208             if (cfg.TempDir != null)
209                 TempDir = cfg.TempDir;
210             if (cfg.maxTxnsIsSet)
211                 MaxTransactions = cfg.MaxTransactions;
212             if (cfg.txnTimestampIsSet)
213                 TxnTimestamp = cfg.TxnTimestamp;
214             if (cfg.Verbosity != null)
215                 Verbosity = cfg.Verbosity;
216             if (cfg.flags != 0)
217                 dbenv.set_flags(cfg.flags, 1);
218             if (cfg.initThreadCountIsSet)
219                 InitThreadCount = cfg.InitThreadCount;
220             if (cfg.initTxnCountIsSet)
221                 InitTxnCount = cfg.InitTxnCount;
222
223             if (cfg.LockSystemCfg != null) {
224                 if (cfg.LockSystemCfg.Conflicts != null)
225                     LockConflictMatrix = cfg.LockSystemCfg.Conflicts;
226                 if (cfg.LockSystemCfg.DeadlockResolution != null)
227                     DeadlockResolution = cfg.LockSystemCfg.DeadlockResolution;
228                 if (cfg.LockSystemCfg.initLockerCountIsSet)
229                     InitLockerCount = cfg.LockSystemCfg.InitLockerCount;
230                 if (cfg.LockSystemCfg.initLockCountIsSet)
231                     InitLockCount = cfg.LockSystemCfg.InitLockCount;
232                 if (cfg.LockSystemCfg.initLockObjectCountIsSet)
233                     InitLockObjectCount = cfg.LockSystemCfg.InitLockObjectCount;
234                 if (cfg.LockSystemCfg.maxLockersIsSet)
235                     MaxLockers = cfg.LockSystemCfg.MaxLockers;
236                 if (cfg.LockSystemCfg.maxLocksIsSet)
237                     MaxLocks = cfg.LockSystemCfg.MaxLocks;
238                 if (cfg.LockSystemCfg.maxObjectsIsSet)
239                     MaxObjects = cfg.LockSystemCfg.MaxObjects;
240                 if (cfg.LockSystemCfg.partitionsIsSet)
241                     LockPartitions = cfg.LockSystemCfg.Partitions;
242                 if (cfg.LockSystemCfg.tablesizeIsSet)
243                     LockTableSize = cfg.LockSystemCfg.TableSize;
244             }
245
246             if (cfg.LogSystemCfg != null) {
247                 if (cfg.LogSystemCfg.bsizeIsSet)
248                     LogBufferSize = cfg.LogSystemCfg.BufferSize;
249                 if (cfg.LogSystemCfg.Dir != null)
250                     LogDir = cfg.LogSystemCfg.Dir;
251                 if (cfg.LogSystemCfg.initLogIdCountIsSet)
252                     InitLogIdCount = cfg.LogSystemCfg.InitLogIdCount;
253                 if (cfg.LogSystemCfg.modeIsSet)
254                     LogFileMode = cfg.LogSystemCfg.FileMode;
255                 if (cfg.LogSystemCfg.maxSizeIsSet)
256                     MaxLogFileSize = cfg.LogSystemCfg.MaxFileSize;
257                 if (cfg.LogSystemCfg.regionSizeIsSet)
258                     LogRegionSize = cfg.LogSystemCfg.RegionSize;
259                 if (cfg.LogSystemCfg.ConfigFlags != 0)
260                     dbenv.log_set_config(cfg.LogSystemCfg.ConfigFlags, 1);
261             }
262
263             if (cfg.MPoolSystemCfg != null) {
264                 if (cfg.MPoolSystemCfg.CacheSize != null)
265                     CacheSize = cfg.MPoolSystemCfg.CacheSize;
266                 if (cfg.MPoolSystemCfg.MaxCacheSize != null)
267                     MaxCacheSize = cfg.MPoolSystemCfg.MaxCacheSize;
268                 if (cfg.MPoolSystemCfg.maxOpenFDIsSet)
269                     MaxOpenFiles = cfg.MPoolSystemCfg.MaxOpenFiles;
270                 if (cfg.MPoolSystemCfg.maxSeqWriteIsSet)
271                     SetMaxSequentialWrites(
272                         cfg.MPoolSystemCfg.MaxSequentialWrites,
273                         cfg.MPoolSystemCfg.SequentialWritePause);
274                 if (cfg.MPoolSystemCfg.mmapSizeSet)
275                     MMapSize = cfg.MPoolSystemCfg.MMapSize;
276             }
277
278             if (cfg.MutexSystemCfg != null) {
279                 if (cfg.MutexSystemCfg.alignmentIsSet)
280                     MutexAlignment = cfg.MutexSystemCfg.Alignment;
281                 /*
282                  * Setting max after increment ensures that the value of max
283                  * will win if both max and increment are set.  This is the
284                  * behavior we document in MutexConfig.
285                  */
286                 if (cfg.MutexSystemCfg.incrementIsSet)
287                     MutexIncrement = cfg.MutexSystemCfg.Increment;
288                 if (cfg.MutexSystemCfg.initMutexesIsSet)
289                     InitMutexes = cfg.MutexSystemCfg.InitMutexes;
290                 if (cfg.MutexSystemCfg.maxMutexesIsSet)
291                     MaxMutexes = cfg.MutexSystemCfg.MaxMutexes;
292                 if (cfg.MutexSystemCfg.numTASIsSet)
293                     NumTestAndSetSpins = cfg.MutexSystemCfg.NumTestAndSetSpins;
294             }
295
296             if (cfg.RepSystemCfg != null) {
297                 if (cfg.RepSystemCfg.ackTimeoutIsSet)
298                     RepAckTimeout = cfg.RepSystemCfg.AckTimeout;
299                 if (cfg.RepSystemCfg.BulkTransfer)
300                     RepBulkTransfer = true;
301                 if (cfg.RepSystemCfg.checkpointDelayIsSet)
302                     RepCheckpointDelay = cfg.RepSystemCfg.CheckpointDelay;
303                 if (cfg.RepSystemCfg.clockskewIsSet)
304                     RepSetClockskew(cfg.RepSystemCfg.ClockskewFast,
305                         cfg.RepSystemCfg.ClockskewSlow);
306                 if (cfg.RepSystemCfg.connectionRetryIsSet)
307                     RepConnectionRetry = cfg.RepSystemCfg.ConnectionRetry;
308                 if (cfg.RepSystemCfg.DelayClientSync)
309                     RepDelayClientSync = true;
310                 if (cfg.RepSystemCfg.electionRetryIsSet)
311                     RepElectionRetry = cfg.RepSystemCfg.ElectionRetry;
312                 if (cfg.RepSystemCfg.electionTimeoutIsSet)
313                     RepElectionTimeout = cfg.RepSystemCfg.ElectionTimeout;
314                 if (cfg.RepSystemCfg.fullElectionTimeoutIsSet)
315                     RepFullElectionTimeout =
316                         cfg.RepSystemCfg.FullElectionTimeout;
317                 if (cfg.RepSystemCfg.heartbeatMonitorIsSet)
318                     RepHeartbeatMonitor = cfg.RepSystemCfg.HeartbeatMonitor;
319                 if (cfg.RepSystemCfg.heartbeatSendIsSet)
320                     RepHeartbeatSend = cfg.RepSystemCfg.HeartbeatSend;
321                 if (cfg.RepSystemCfg.InMemory)
322                     dbenv.rep_set_config(DbConstants.DB_REP_CONF_INMEM, 1);
323                 if (cfg.RepSystemCfg.leaseTimeoutIsSet)
324                     RepLeaseTimeout = cfg.RepSystemCfg.LeaseTimeout;
325                 if (!cfg.RepSystemCfg.AutoInit)
326                     RepAutoInit = false;
327                 if (cfg.RepSystemCfg.NoBlocking)
328                     RepNoBlocking = true;
329                 if (cfg.RepSystemCfg.nsitesIsSet)
330                     RepNSites = cfg.RepSystemCfg.NSites;
331                 for (int i = 0; i < cfg.RepSystemCfg.RepmgrSitesConfig.Count; i++)
332                     RepMgrSiteConfig(cfg.RepSystemCfg.RepmgrSitesConfig[i]);
333                 if (cfg.RepSystemCfg.priorityIsSet)
334                     RepPriority = cfg.RepSystemCfg.Priority;
335                 if (cfg.RepSystemCfg.RepMgrAckPolicy != null)
336                     RepMgrAckPolicy = cfg.RepSystemCfg.RepMgrAckPolicy;
337                 if (cfg.RepSystemCfg.retransmissionRequestIsSet)
338                     RepSetRetransmissionRequest(
339                         cfg.RepSystemCfg.RetransmissionRequestMin,
340                         cfg.RepSystemCfg.RetransmissionRequestMax);
341                 if (cfg.RepSystemCfg.Strict2Site)
342                     RepStrict2Site = true;
343                 if (cfg.RepSystemCfg.transmitLimitIsSet)
344                     RepSetTransmitLimit(
345                         cfg.RepSystemCfg.TransmitLimitGBytes,
346                         cfg.RepSystemCfg.TransmitLimitBytes);
347                 if (cfg.RepSystemCfg.UseMasterLeases)
348                     RepUseMasterLeases = true;
349                 if (!cfg.RepSystemCfg.Elections)
350                     RepMgrRunElections = false;
351             }
352
353         }
354
355         #region Properties
356         /// <summary>
357         /// If true, database operations for which no explicit transaction
358         /// handle was specified, and which modify databases in the database
359         /// environment, will be automatically enclosed within a transaction.
360         /// </summary>
361         public bool AutoCommit {
362             get {
363                 uint flags = 0;
364                 dbenv.get_flags(ref flags);
365                 return (flags & DbConstants.DB_AUTO_COMMIT) != 0;
366             }
367             set {
368                 dbenv.set_flags(DbConstants.DB_AUTO_COMMIT, value ? 1 : 0);
369             }
370         }
371         
372         /// <summary>
373         /// The size of the buffer, in bytes, to read from the database during a
374         /// hot backup.
375         /// </summary>
376         public uint BackupBufferSize {
377             get {
378                 uint ret = 0;
379                 dbenv.get_backup_config(DbConstants.DB_BACKUP_SIZE, ref ret);
380                 return ret;
381             }
382             set {
383                 dbenv.set_backup_config(DbConstants.DB_BACKUP_SIZE, value);
384             }
385         }
386         /// <summary>
387         /// Sets the <see cref="IBackup"/> interface to be used when performing
388         /// hot backups.
389         /// <para>
390         /// This interface is used to override the default behavior used by the 
391         /// <see cref="DatabaseEnvironment.Backup"/> and 
392         /// <see cref="DatabaseEnvironment.BackupDatabase"/> methods. 
393         /// </para>
394         /// </summary>
395         public IBackup BackupHandler {
396             get { return backupObj; }
397             set {
398                 if (value == null) {
399                     dbenv.set_backup_callbacks(null, null, null);
400                 } else if (backupObj == null) {
401                     if (doBackupCloseRef == null)
402                         doBackupCloseRef = 
403                             new BDB_BackupCloseDelegate(doBackupClose);
404                     if (doBackupOpenRef == null)
405                         doBackupOpenRef = 
406                             new BDB_BackupOpenDelegate(doBackupOpen);
407                     if (doBackupWriteRef == null)
408                         doBackupWriteRef = 
409                             new BDB_BackupWriteDelegate(doBackupWrite);
410                     dbenv.set_backup_callbacks(
411                         doBackupOpenRef, doBackupWriteRef, doBackupCloseRef);
412                 }
413
414                 backupObj = value;
415             }
416         }
417         /// <summary>
418         /// The number of pages to read before pausing during the hot backup.
419         /// <para>
420         /// Increasing this value increases the amount of I/O the backup process
421         /// performs for any given time interval. If your application is already
422         /// heavily I/O bound, setting this value to a lower number may help to 
423         /// improve your overall data throughput by reducing the I/O demands
424         /// placed on your system. By default, all pages are read without a 
425         /// pause.
426         /// </para>
427         /// </summary>
428         public uint BackupReadCount {
429             get {
430                 uint ret = 0;
431                 dbenv.get_backup_config(DbConstants.DB_BACKUP_READ_COUNT, ref ret);
432                 return ret;
433             }
434             set {
435                 dbenv.set_backup_config(DbConstants.DB_BACKUP_READ_COUNT, value);
436             }
437         }
438         /// <summary>
439         /// The number of microseconds to sleep between batches of reads during
440         /// a hot backup.
441         /// <para>
442         /// Increasing this value decreases the amount of I/O the backup process
443         /// performs for any given time interval. If your application is already
444         /// heavily I/O bound, setting this value to a higher number may help to
445         /// improve your overall data throughput by reducing the I/O demands 
446         /// placed on your system. 
447         /// </para>
448         /// </summary>
449         public uint BackupReadSleepDuration {
450             get {
451                 uint ret = 0;
452                 dbenv.get_backup_config(DbConstants.DB_BACKUP_READ_SLEEP, ref ret);
453                 return ret;
454             }
455             set {
456                 dbenv.set_backup_config(DbConstants.DB_BACKUP_READ_SLEEP, value);
457             }
458         }
459         /// <summary>
460         /// If true, direct I/O is used when writing pages to the disk during a 
461         /// hot backup.
462         /// <para>
463         /// For some environments, direct I/O can provide faster write 
464         /// throughput, but usually it is slower because the OS buffer pool 
465         /// offers asynchronous activity. 
466         /// </para>
467         /// </summary>
468         public bool BackupWriteDirect {
469             get {
470                 uint ret = 0;
471                 dbenv.get_backup_config(DbConstants.DB_BACKUP_WRITE_DIRECT, ref ret);
472                 return ret != 0;
473             }
474             set {
475                 dbenv.set_backup_config(DbConstants.DB_BACKUP_WRITE_DIRECT, (uint)(value ? 1 : 0));
476             }
477         }
478         
479         /// <summary>
480         /// The size of the shared memory buffer pool -- that is, the cache.
481         /// </summary>
482         /// <remarks>
483         /// <para>
484         /// The cache should be the size of the normal working data set of the
485         /// application, with some small amount of additional memory for unusual
486         /// situations. (Note: the working set is not the same as the number of
487         /// pages accessed simultaneously, and is usually much larger.)
488         /// </para>
489         /// <para>
490         /// The default cache size is 256KB, and may not be specified as less
491         /// than 20KB. Any cache size less than 500MB is automatically increased
492         /// by 25% to account for buffer pool overhead; cache sizes larger than
493         /// 500MB are used as specified. The maximum size of a single cache is
494         /// 4GB on 32-bit systems and 10TB on 64-bit systems. (All sizes are in
495         /// powers-of-two, that is, 256KB is 2^18 not 256,000.) For information
496         /// on tuning the Berkeley DB cache size, see Selecting a cache size in
497         /// the Programmer's Reference Guide.
498         /// </para>
499         /// </remarks>
500         public CacheInfo CacheSize {
501             get {
502                 uint gb = 0;
503                 uint b = 0;
504                 int n = 0;
505                 dbenv.get_cachesize(ref gb, ref b, ref n);
506                 return new CacheInfo(gb, b, n);
507             }
508             set {
509                 if (value != null)
510                 dbenv.set_cachesize(
511                     value.Gigabytes, value.Bytes, value.NCaches);
512             }
513         }
514         /// <summary>
515         /// If true, Berkeley DB Concurrent Data Store applications will perform
516         /// locking on an environment-wide basis rather than on a per-database
517         /// basis. 
518         /// </summary>
519         public bool CDB_ALLDB {
520             get {
521                 uint flags = 0;
522                 dbenv.get_flags(ref flags);
523                 return (flags & DbConstants.DB_CDB_ALLDB) != 0;
524             }
525         }
526         /// <summary>
527         /// If true, Berkeley DB subsystems will create any underlying files, as
528         /// necessary.
529         /// </summary>
530         public bool Create { 
531             get {
532                 uint flags = 0;
533                 dbenv.get_open_flags(ref flags);
534                 return (flags & DbConstants.DB_CREATE) != 0;
535             } 
536         }
537         /// <summary>
538         /// The array of directories where database files are stored.
539         /// </summary>
540         public List<string> DataDirs { get { return dbenv.get_data_dirs(); } }
541
542         /// <summary>
543         /// The deadlock detector configuration, specifying what lock request(s)
544         /// should be rejected. As transactions acquire locks on behalf of a
545         /// single locker ID, rejecting a lock request associated with a
546         /// transaction normally requires the transaction be aborted.
547         /// </summary>
548         public DeadlockPolicy DeadlockResolution {
549             get {
550                 uint mode = 0;
551                 dbenv.get_lk_detect(ref mode);
552                 return DeadlockPolicy.fromPolicy(mode);
553             }
554             set {
555                 if (value != null)
556                     dbenv.set_lk_detect(value.policy);
557                 else
558                     dbenv.set_lk_detect(DeadlockPolicy.DEFAULT.policy);
559             }
560         }
561         /// <summary>
562         /// The algorithm used by the Berkeley DB library to perform encryption
563         /// and decryption. 
564         /// </summary>
565         public EncryptionAlgorithm EncryptAlgorithm {
566             get {
567                 uint flags = 0;
568                 dbenv.get_encrypt_flags(ref flags);
569                 return (EncryptionAlgorithm)Enum.ToObject(
570                     typeof(EncryptionAlgorithm), flags);
571             }
572         }
573         /// <summary>
574         /// The mechanism for reporting detailed error messages to the
575         /// application.
576         /// </summary>
577         /// <remarks>
578         /// <para>
579         /// When an error occurs in the Berkeley DB library, a
580         /// <see cref="DatabaseException"/>, or subclass of DatabaseException,
581         /// is thrown. In some cases, however, the exception may be insufficient
582         /// to completely describe the cause of the error, especially during
583         /// initial application debugging.
584         /// </para>
585                 /// <para>
586         /// In some cases, when an error occurs, Berkeley DB will call the given
587         /// delegate with additional error information. It is up to the delegate
588         /// to display the error message in an appropriate manner.
589         /// </para>
590                 /// <para>
591         /// Setting ErrorFeedback to NULL unconfigures the callback interface.
592         /// </para>
593                 /// <para>
594         /// This error-logging enhancement does not slow performance or
595         /// significantly increase application size, and may be run during
596         /// normal operation as well as during application debugging.
597         /// </para>
598                 /// </remarks>
599         public ErrorFeedbackDelegate ErrorFeedback {
600             get { return errFeedbackHandler; }
601             set {
602                 if (value == null)
603                     dbenv.set_errcall(null);
604                 else if (errFeedbackHandler == null) {
605                     if (doErrFeedbackRef == null)
606                         doErrFeedbackRef = new BDB_ErrcallDelegate(doErrFeedback);
607                     dbenv.set_errcall(doErrFeedbackRef);
608                 }
609                 errFeedbackHandler = value;
610             }
611         }
612         /// <summary>
613         /// The prefix string that appears before error messages issued by
614         /// Berkeley DB.
615         /// </summary>
616         /// <remarks>
617         /// <para>
618         /// For databases opened inside of a DatabaseEnvironment, setting
619         /// ErrorPrefix affects the entire environment and is equivalent to
620         /// setting <see cref="DatabaseEnvironment.ErrorPrefix"/>.
621         /// </para>
622                 /// <para>
623         /// Setting ErrorPrefix configures operations performed using the
624         /// specified object, not all operations performed on the underlying
625         /// database. 
626         /// </para>
627         /// </remarks>
628         public string ErrorPrefix {
629             get { return _pfx; }
630             set { _pfx = value; }
631         }
632
633         /// <summary>
634         /// A delegate which is called to notify the process of specific
635         /// Berkeley DB events. 
636         /// </summary>
637         public EventNotifyDelegate EventNotify {
638             get { return notifyHandler; }
639             set {
640                 if (value == null)
641                     dbenv.set_event_notify(null);
642                 else if (notifyHandler == null) {
643                     if (doNotifyRef == null)
644                         doNotifyRef = new BDB_EventNotifyDelegate(doNotify);
645                     dbenv.set_event_notify(doNotifyRef);
646                 }
647
648                 notifyHandler = value;
649             }
650         }
651         /// <summary>
652         /// Monitor progress within long running operations.
653         /// </summary>
654         /// <remarks>
655         /// <para>
656         /// Some operations performed by the Berkeley DB library can take
657         /// non-trivial amounts of time. The Feedback delegate can be used by
658         /// applications to monitor progress within these operations. When an
659         /// operation is likely to take a long time, Berkeley DB will call the
660         /// specified delegate with progress information.
661         /// </para>
662         /// <para>
663         /// It is up to the delegate to display this information in an
664         /// appropriate manner. 
665         /// </para>
666         /// </remarks>
667         public EnvironmentFeedbackDelegate Feedback {
668             get { return feedbackHandler; }
669             set {
670                 if (value == null)
671                     dbenv.set_feedback(null);
672                 else if (feedbackHandler == null) {
673                     if (doFeedbackRef == null)
674                         doFeedbackRef = new BDB_EnvFeedbackDelegate(doFeedback);
675                     dbenv.set_feedback(doFeedbackRef);
676                 }
677                 feedbackHandler = value;
678             }
679         }
680         /// <summary>
681         /// If true, flush database writes to the backing disk before returning
682         /// from the write system call, rather than flushing database writes
683         /// explicitly in a separate system call, as necessary.
684         /// </summary>
685         /// <remarks>
686         /// This flag may result in inaccurate file modification times and other
687         /// file-level information for Berkeley DB database files. This flag
688         /// will almost certainly result in a performance decrease on most
689         /// systems.
690         /// </remarks>
691         public bool ForceFlush {
692             get {
693                 uint flags = 0;
694                 dbenv.get_flags(ref flags);
695                 return (flags & DbConstants.DB_DSYNC_DB) != 0;
696             }
697             set {
698                 dbenv.set_flags(DbConstants.DB_DSYNC_DB, value ? 1 : 0);
699             }
700         }
701         /// <summary>
702         /// If true, the object is free-threaded; that is, concurrently usable
703         /// by multiple threads in the address space.
704         /// </summary>
705         public bool FreeThreaded { 
706             get {
707                 uint flags = 0;
708                 dbenv.get_open_flags(ref flags);
709                 return (flags & DbConstants.DB_THREAD) != 0;
710             }
711         }
712         /// <summary>
713         /// The database environment home directory.
714         /// </summary>
715         public string Home {
716             get {
717                 string dir = "";
718                 dbenv.get_home(out dir);
719                 return dir;
720             }
721         }
722         /// <summary>
723         /// Whether there is any hot backup in progress.
724         /// </summary>
725         public bool HotbackupInProgress {
726             get {
727                 uint flags = 0;
728                 dbenv.get_flags(ref flags);
729                 return (flags & DbConstants.DB_HOTBACKUP_IN_PROGRESS) != 0;
730             }
731             set {
732                 dbenv.set_flags(
733                     DbConstants.DB_HOTBACKUP_IN_PROGRESS, value ? 1 : 0);
734             }
735         }
736         /// <summary>
737         /// The number of locks allocated when the environment is created
738         /// </summary>
739         public uint InitLockCount {
740             get {
741                 uint ret = 0;
742                 dbenv.get_memory_init(DbConstants.DB_MEM_LOCK, ref ret);
743                 return ret;
744             }
745             private set {
746                 dbenv.set_memory_init(DbConstants.DB_MEM_LOCK, value);
747             }
748         }
749         /// <summary>
750         /// The number of lock objects allocated when the environment is created
751         /// </summary>
752         public uint InitLockObjectCount {
753             get {
754                 uint ret = 0;
755                 dbenv.get_memory_init(DbConstants.DB_MEM_LOCKOBJECT, ref ret);
756                 return ret;
757             }
758             private set {
759                 dbenv.set_memory_init(DbConstants.DB_MEM_LOCKOBJECT, value);
760             }
761         }
762         /// <summary>
763         /// The number of lockers allocated when the environment is created
764         /// </summary>
765         public uint InitLockerCount {
766             get {
767                 uint ret = 0;
768                 dbenv.get_memory_init(DbConstants.DB_MEM_LOCKER, ref ret);
769                 return ret;
770             }
771             private set {
772                 dbenv.set_memory_init(DbConstants.DB_MEM_LOCKER, value);
773             }
774         }
775         /// <summary>
776         /// The number of log identifier objects allocated when the
777         /// environment is created
778         /// </summary>
779         public uint InitLogIdCount {
780             get {
781                 uint ret = 0;
782                 dbenv.get_memory_init(DbConstants.DB_MEM_LOGID, ref ret);
783                 return ret;
784             }
785             private set {
786                 dbenv.set_memory_init(DbConstants.DB_MEM_LOGID, value);
787             }
788         }
789         /// <summary>
790         /// The number of thread objects allocated when the environment is
791         /// created
792         /// </summary>
793         public uint InitThreadCount {
794             get {
795                 uint ret = 0;
796                 dbenv.get_memory_init(DbConstants.DB_MEM_THREAD, ref ret);
797                 return ret;
798             }
799             private set {
800                 dbenv.set_memory_init(DbConstants.DB_MEM_THREAD, value);
801             }
802         }
803         /// <summary>
804         /// The number of transaction objects allocated when the environment is
805         /// created
806         /// </summary>
807         public uint InitTxnCount {
808             get {
809                 uint ret = 0;
810                 dbenv.get_memory_init(DbConstants.DB_MEM_TRANSACTION, ref ret);
811                 return ret;
812             }
813             private set {
814                 dbenv.set_memory_init(DbConstants.DB_MEM_TRANSACTION, value);
815             }
816         }
817         /// <summary>
818         /// The initial number of mutexes allocated
819         /// </summary>
820         public uint InitMutexes {
821             get {
822                 uint ret = 0;
823                 dbenv.mutex_get_init(ref ret);
824                 return ret;
825             }
826             private set {
827                 dbenv.mutex_set_init(value);
828             }
829         }
830         /// <summary>
831         /// If true, Berkeley DB will page-fault shared regions into memory when
832         /// initially creating or joining a Berkeley DB environment.
833         /// </summary>
834         /// <remarks>
835         /// <para>
836         /// In some applications, the expense of page-faulting the underlying
837         /// shared memory regions can affect performance. (For example, if the
838         /// page-fault occurs while holding a lock, other lock requests can
839         /// convoy, and overall throughput may decrease.)
840         /// </para>
841         /// <para>
842         /// In addition to page-faulting, Berkeley DB will write the shared
843         /// regions when creating an environment, forcing the underlying virtual
844         /// memory and filesystems to instantiate both the necessary memory and
845         /// the necessary disk space. This can also avoid out-of-disk space
846         /// failures later on.
847         /// </para>
848         /// </remarks>
849         public bool InitRegions {
850             get {
851                 uint flags = 0;
852                 dbenv.get_flags(ref flags);
853                 return (flags & DbConstants.DB_REGION_INIT) != 0;
854             }
855             set {
856                 dbenv.set_flags(DbConstants.DB_REGION_INIT, value ? 1 : 0);
857             }
858         }
859         /// <summary>
860         /// The intermediate directory permissions. 
861         /// </summary>
862         public string IntermediateDirMode {
863             get {
864                 string ret;
865                 dbenv.get_intermediate_dir_mode(out ret);
866                 return ret;
867             }
868             private set {
869                 dbenv.set_intermediate_dir_mode(value);
870             }
871         }
872         
873         /// <summary>
874         /// The current lock conflicts array.
875         /// </summary>
876         public byte[,] LockConflictMatrix {
877             get {
878                 int sz = 0;
879                 dbenv.get_lk_conflicts_nmodes(ref sz);
880                 byte [,] ret = new byte[sz, sz];
881                 dbenv.get_lk_conflicts(ret);
882                 return ret;
883             }
884             private set {
885                 // Matrix dimensions checked in LockingConfig.
886                 dbenv.set_lk_conflicts(value, (int)Math.Sqrt(value.Length));
887             }
888         }
889         /// <summary>
890         /// If true, lock shared Berkeley DB environment files and memory-mapped
891         /// databases into memory.
892         /// </summary>
893         public bool Lockdown { 
894             get {
895                 uint flags = 0;
896                 dbenv.get_open_flags(ref flags);
897                 return (flags & DbConstants.DB_LOCKDOWN) != 0;
898             }
899         }
900         /// <summary>
901         /// The size of the lock table in the Berkeley DB environment.
902         /// </summary>
903         public uint LockTableSize {
904             get {
905                 uint ret = 0;
906                 dbenv.get_lk_tablesize(ref ret);
907                 return ret;
908             }
909             private set {
910                 dbenv.set_lk_tablesize(value);
911             }
912         }
913         /// <summary>
914         /// The number of lock table partitions used in the Berkeley DB
915         /// environment.
916         /// </summary>
917         public uint LockPartitions {
918             get {
919                 uint ret = 0;
920                 dbenv.get_lk_partitions(ref ret);
921                 return ret;
922             }
923             private set {
924                 dbenv.set_lk_partitions(value);
925             }
926         }
927         /// <summary>
928         /// A value, in microseconds, representing lock timeouts.
929         /// </summary>
930         /// <remarks>
931         /// <para>
932         /// All timeouts are checked whenever a thread of control blocks on a
933         /// lock or when deadlock detection is performed. As timeouts are only
934         /// checked when the lock request first blocks or when deadlock
935         /// detection is performed, the accuracy of the timeout depends on how
936         /// often deadlock detection is performed.
937         /// </para>
938         /// <para>
939         /// Timeout values specified for the database environment may be
940         /// overridden on a per-transaction basis, see
941         /// <see cref="Transaction.SetLockTimeout"/>.
942         /// </para>
943         /// </remarks>
944         public uint LockTimeout {
945             get {
946                 uint timeout = 0;
947                 dbenv.get_timeout(ref timeout, DbConstants.DB_SET_LOCK_TIMEOUT);
948                 return timeout;
949             }
950             set {
951                 dbenv.set_timeout(value, DbConstants.DB_SET_LOCK_TIMEOUT);
952             }
953         }
954         /// <summary>
955         /// The size of the in-memory log buffer, in bytes
956         /// </summary>
957         public uint LogBufferSize {
958             get {
959                 uint ret = 0;
960                 dbenv.get_lg_bsize(ref ret);
961                 return ret;
962             }
963             private set {
964                 dbenv.set_lg_bsize(value);
965             }
966         }
967         /// <summary>
968         /// The path of a directory to be used as the location of logging files.
969         /// Log files created by the Log Manager subsystem will be created in
970         /// this directory. 
971         /// </summary>
972         public string LogDir {
973             get {
974                 string ret;
975                 dbenv.get_lg_dir(out ret);
976                 return ret;
977             }
978             private set {
979                 dbenv.set_lg_dir(value);
980             }
981         }
982         /// <summary>
983         /// The absolute file mode for created log files. This property is only
984         /// useful for the rare Berkeley DB application that does not control
985         /// its umask value.
986         /// </summary>
987         /// <remarks>
988         /// Normally, if Berkeley DB applications set their umask appropriately,
989         /// all processes in the application suite will have read permission on
990         /// the log files created by any process in the application suite.
991         /// However, if the Berkeley DB application is a library, a process
992         /// using the library might set its umask to a value preventing other
993         /// processes in the application suite from reading the log files it
994         /// creates. In this rare case, this property can be used to set the
995         /// mode of created log files to an absolute value.
996         /// </remarks>
997         public int LogFileMode {
998             get {
999                 int ret = 0;
1000                 dbenv.get_lg_filemode(ref ret);
1001                 return ret;
1002             }
1003             set {
1004                 dbenv.set_lg_filemode(value);
1005             }
1006         }
1007         /// <summary>
1008         /// If true, system buffering is turned off for Berkeley DB log files to
1009         /// avoid double caching. 
1010         /// </summary>
1011         public bool LogNoBuffer {
1012             get {
1013                 int onoff = 0;
1014                 dbenv.log_get_config(DbConstants.DB_LOG_DIRECT, ref onoff);
1015                 return (onoff != 0);
1016             }
1017             set {
1018                 dbenv.log_set_config(DbConstants.DB_LOG_DIRECT, value ? 1 : 0);
1019             }
1020         }
1021         /// <summary>
1022         /// If true, Berkeley DB will flush log writes to the backing disk
1023         /// before returning from the write system call, rather than flushing
1024         /// log writes explicitly in a separate system call, as necessary.
1025         /// </summary>
1026         public bool LogForceSync {
1027             get{
1028                 int onoff = 0;
1029                 dbenv.log_get_config(DbConstants.DB_LOG_DSYNC, ref onoff);
1030                 return (onoff != 0);
1031             }
1032             set {
1033                 dbenv.log_set_config(DbConstants.DB_LOG_DSYNC, value ? 1 : 0);
1034             }
1035         }
1036         /// <summary>
1037         /// If true, Berkeley DB will automatically remove log files that are no
1038         /// longer needed.
1039         /// </summary>
1040         public bool LogAutoRemove {
1041             get {
1042                 int onoff = 0;
1043                 dbenv.log_get_config(DbConstants.DB_LOG_AUTO_REMOVE, ref onoff);
1044                 return (onoff != 0);
1045             }
1046             set {
1047                 dbenv.log_set_config(
1048                     DbConstants.DB_LOG_AUTO_REMOVE, value ? 1 : 0);
1049             }
1050         }
1051         /// <summary>
1052         /// If true, transaction logs are maintained in memory rather than on
1053         /// disk. This means that transactions exhibit the ACI (atomicity,
1054         /// consistency, and isolation) properties, but not D (durability).
1055         /// </summary>
1056         public bool LogInMemory {
1057             get {
1058                 int onoff = 0;
1059                 dbenv.log_get_config(DbConstants.DB_LOG_IN_MEMORY, ref onoff);
1060                 return (onoff != 0);
1061             }
1062         }
1063         /// <summary>
1064         /// If true, all pages of a log file are zeroed when that log file is
1065         /// created.
1066         /// </summary>
1067         public bool LogZeroOnCreate {
1068             get {
1069                 int onoff = 0;
1070                 dbenv.log_get_config(DbConstants.DB_LOG_ZERO, ref onoff);
1071                 return (onoff != 0);
1072             }
1073         }
1074         /// <summary>
1075         /// The size of the underlying logging area of the Berkeley DB
1076         /// environment, in bytes.
1077         /// </summary>
1078         public uint LogRegionSize {
1079             get {
1080                 uint ret = 0;
1081                 dbenv.get_lg_regionmax(ref ret);
1082                 return ret;
1083             }
1084             private set {
1085                 dbenv.set_lg_regionmax(value);
1086             }
1087         }
1088         /// <summary>
1089         /// The maximum cache size
1090         /// </summary>
1091         public CacheInfo MaxCacheSize {
1092             get {
1093                 uint gb = 0;
1094                 uint b = 0;
1095                 dbenv.get_cache_max(ref gb, ref b);
1096                 return new CacheInfo(gb, b, 0);
1097             }
1098             private set {
1099                 dbenv.set_cache_max(value.Gigabytes, value.Bytes);
1100             }
1101         }
1102         /// <summary>
1103         /// The maximum size of a single file in the log, in bytes. Because
1104         /// <see cref="LSN.Offset">LSN Offsets</see> are unsigned four-byte
1105         /// values, the size may not be larger than the maximum unsigned
1106         /// four-byte value.
1107         /// </summary>
1108         /// <remarks>
1109         /// <para>
1110         /// When the logging subsystem is configured for on-disk logging, the
1111         /// default size of a log file is 10MB.
1112         /// </para>
1113         /// <para>
1114         /// When the logging subsystem is configured for in-memory logging, the
1115         /// default size of a log file is 256KB. In addition, the configured log
1116         /// buffer size must be larger than the log file size. (The logging
1117         /// subsystem divides memory configured for in-memory log records into
1118         /// "files", as database environments configured for in-memory log
1119         /// records may exchange log records with other members of a replication
1120         /// group, and those members may be configured to store log records
1121         /// on-disk.) When choosing log buffer and file sizes for in-memory
1122         /// logs, applications should ensure the in-memory log buffer size is
1123         /// large enough that no transaction will ever span the entire buffer,
1124         /// and avoid a state where the in-memory buffer is full and no space
1125         /// can be freed because a transaction that started in the first log
1126         /// "file" is still active.
1127         /// </para>
1128         /// <para>
1129         /// See Log File Limits in the Programmer's Reference Guide for more
1130         /// information.
1131         /// </para>
1132         /// <para>
1133         /// If no size is specified by the application, the size last specified
1134         /// for the database region will be used, or if no database region
1135         /// previously existed, the default will be used.
1136         /// </para>
1137         /// </remarks>
1138         public uint MaxLogFileSize {
1139             get {
1140                 uint ret = 0;
1141                 dbenv.get_lg_max(ref ret);
1142                 return ret;
1143             }
1144             set {
1145                 dbenv.set_lg_max(value);
1146             }
1147         }
1148         /// <summary>
1149         /// The maximum number of locking entities supported by the Berkeley DB
1150         /// environment.
1151         /// </summary>
1152         public uint MaxLockers {
1153             get {
1154                 uint ret = 0;
1155                 dbenv.get_lk_max_lockers(ref ret);
1156                 return ret;
1157             }
1158             private set {
1159                 dbenv.set_lk_max_lockers(value);
1160             }
1161         }
1162         /// <summary>
1163         /// The maximum number of locks supported by the Berkeley DB
1164         /// environment.
1165         /// </summary>
1166         public uint MaxLocks {
1167             get {
1168                 uint ret = 0;
1169                 dbenv.get_lk_max_locks(ref ret);
1170                 return ret;
1171             }
1172             private set {
1173                 dbenv.set_lk_max_locks(value);
1174             }
1175         }
1176         /// <summary>
1177         /// The total number of mutexes allocated
1178         /// </summary>
1179         public uint MaxMutexes {
1180             get {
1181                 uint ret = 0;
1182                 dbenv.mutex_get_max(ref ret);
1183                 return ret;
1184             }
1185             private set {
1186                 dbenv.mutex_set_max(value);
1187             }
1188         }
1189         /// <summary>
1190         /// The maximum number of locked objects
1191         /// </summary>
1192         public uint MaxObjects {
1193             get {
1194                 uint ret = 0;
1195                 dbenv.get_lk_max_objects(ref ret);
1196                 return ret;
1197             }
1198             private set {
1199                 dbenv.set_lk_max_objects(value);
1200             }
1201         }
1202         /// <summary>
1203         /// The number of file descriptors the library will open concurrently
1204         /// when flushing dirty pages from the cache.
1205         /// </summary>
1206         public int MaxOpenFiles {
1207             get {
1208                 int ret = 0;
1209                 dbenv.get_mp_max_openfd(ref ret);
1210                 return ret;
1211             }
1212             set {
1213                 dbenv.set_mp_max_openfd(value);
1214             }
1215         }
1216         /// <summary>
1217         /// The number of sequential write operations scheduled by the library
1218         /// when flushing dirty pages from the cache. 
1219         /// </summary>
1220         public int MaxSequentialWrites {
1221             get {
1222                 int ret = 0;
1223                 uint tmp = 0;
1224                 dbenv.get_mp_max_write(ref ret, ref tmp);
1225                 return ret;
1226             }
1227         }
1228         /// <summary>
1229         /// The number of active transactions supported by the environment. This
1230         /// value bounds the size of the memory allocated for transactions.
1231         /// Child transactions are counted as active until they either commit or
1232         /// abort.
1233         /// </summary>
1234         /// <remarks>
1235         /// <para>
1236         /// Transactions that update multiversion databases are not freed until
1237         /// the last page version that the transaction created is flushed from
1238         /// cache. This means that applications using multi-version concurrency
1239         /// control may need a transaction for each page in cache, in the
1240         /// extreme case.
1241         /// </para>
1242         /// <para>
1243         /// When all of the memory available in the database environment for
1244         /// transactions is in use, calls to <see cref="BeginTransaction"/> will
1245         /// fail (until some active transactions complete). If MaxTransactions
1246         /// is never set, the database environment is configured to support at
1247         /// least 100 active transactions.
1248         /// </para>
1249         /// </remarks>
1250         public uint MaxTransactions {
1251             get {
1252                 uint ret = 0;
1253                 dbenv.get_tx_max(ref ret);
1254                 return ret;
1255             }
1256             set {
1257                 dbenv.set_tx_max(value);
1258             }
1259         }
1260         /// <summary>
1261         /// The path of directory to store the persistent metadata.
1262         /// </summary>
1263         /// <remarks>
1264         /// <para>
1265         /// By default, metadata is stored in the environment home directory.
1266         /// See Berkeley DB File Naming in the Programmer's Reference Guide for
1267         /// more information.
1268         /// </para>
1269         /// <para>
1270         /// When used in a replicated application, the metadata directory must
1271         /// be the same location for all sites within a replication group.
1272         /// </para> 
1273         /// </remarks>
1274         public string MetadataDir {
1275             get {
1276                 string mddir;
1277                 dbenv.get_metadata_dir(out mddir);
1278                 return mddir;
1279             }
1280         }
1281         /// <summary>
1282         /// The maximum file size, in bytes, for a file to be mapped into the
1283         /// process address space. If no value is specified, it defaults to
1284         /// 10MB. 
1285         /// </summary>
1286         /// <remarks>
1287         /// Files that are opened read-only in the cache (and that satisfy a few
1288         /// other criteria) are, by default, mapped into the process address
1289         /// space instead of being copied into the local cache. This can result
1290         /// in better-than-usual performance because available virtual memory is
1291         /// normally much larger than the local cache, and page faults are
1292         /// faster than page copying on many systems. However, it can cause
1293         /// resource starvation in the presence of limited virtual memory, and
1294         /// it can result in immense process sizes in the presence of large
1295         /// databases.
1296         /// </remarks>
1297         public uint MMapSize {
1298             get {
1299                 uint ret = 0;
1300                 dbenv.get_mp_mmapsize(ref ret);
1301                 return ret;
1302             }
1303             set {
1304                 dbenv.set_mp_mmapsize(value);
1305             }
1306         }
1307         /// <summary>
1308         /// The mutex alignment, in bytes.
1309         /// </summary>
1310         public uint MutexAlignment {
1311             get {
1312                 uint ret = 0;
1313                 dbenv.mutex_get_align(ref ret);
1314                 return ret;
1315             }
1316             private set {
1317                 dbenv.mutex_set_align(value);
1318             }
1319         }
1320         /// <summary>
1321         /// The number of additional mutexes allocated.
1322         /// </summary>
1323         public uint MutexIncrement {
1324             get {
1325                 uint ret = 0;
1326                 dbenv.mutex_get_increment(ref ret);
1327                 return ret;
1328             }
1329             private set {
1330                 dbenv.mutex_set_increment(value);
1331             }
1332         }
1333         /// <summary>
1334         /// If true, turn off system buffering of Berkeley DB database files to
1335         /// avoid double caching. 
1336         /// </summary>
1337         public bool NoBuffer {
1338             get {
1339                 uint flags = 0;
1340                 dbenv.get_flags(ref flags);
1341                 return (flags & DbConstants.DB_DIRECT_DB) != 0;
1342             }
1343             set {
1344                 dbenv.set_flags(DbConstants.DB_DIRECT_DB, value ? 1 : 0);
1345             }
1346         }
1347         /// <summary>
1348         /// If true, Berkeley DB will grant all requested mutual exclusion
1349         /// mutexes and database locks without regard for their actual
1350         /// availability. This functionality should never be used for purposes
1351         /// other than debugging. 
1352         /// </summary>
1353         public bool NoLocking {
1354             get {
1355                 uint flags = 0;
1356                 dbenv.get_flags(ref flags);
1357                 return (flags & DbConstants.DB_NOLOCKING) != 0;
1358             }
1359             set {
1360                 dbenv.set_flags(DbConstants.DB_NOLOCKING, value ? 1 : 0);
1361             }
1362         }
1363         /// <summary>
1364         /// If true, Berkeley DB will copy read-only database files into the
1365         /// local cache instead of potentially mapping them into process memory.
1366         /// </summary>
1367         /// <seealso cref="MMapSize"/>
1368         public bool NoMMap {
1369             get {
1370                 uint flags = 0;
1371                 dbenv.get_flags(ref flags);
1372                 return (flags & DbConstants.DB_NOMMAP) != 0;
1373             }
1374             set {
1375                 dbenv.set_flags(DbConstants.DB_NOMMAP, value ? 1 : 0);
1376             }
1377         }
1378         /// <summary>
1379         /// If true, Berkeley DB will ignore any panic state in the database
1380         /// environment. (Database environments in a panic state normally refuse
1381         /// all attempts to call Berkeley DB functions, throwing 
1382         /// <see cref="RunRecoveryException"/>.) This functionality should never
1383         /// be used for purposes other than debugging.
1384         /// </summary>
1385         public bool NoPanic {
1386             get {
1387                 uint flags = 0;
1388                 dbenv.get_flags(ref flags);
1389                 return (flags & DbConstants.DB_NOPANIC) != 0;
1390             }
1391             set {
1392                 dbenv.set_flags(DbConstants.DB_NOPANIC, value ? 1 : 0);
1393             }
1394         }
1395         /// <summary>
1396         /// The number of times that test-and-set mutexes should spin without
1397         /// blocking. The value defaults to 1 on uniprocessor systems and to 50
1398         /// times the number of processors on multiprocessor systems. 
1399         /// </summary>
1400         public uint NumTestAndSetSpins {
1401             get {
1402                 uint ret = 0;
1403                 dbenv.mutex_get_tas_spins(ref ret);
1404                 return ret;
1405             }
1406             set {
1407                 dbenv.mutex_set_tas_spins(value);
1408             }
1409         }
1410         /// <summary>
1411         /// If true, overwrite files stored in encrypted formats before deleting
1412         /// them.
1413         /// </summary>
1414         /// <remarks>
1415         /// Berkeley DB overwrites files using alternating 0xff, 0x00 and 0xff
1416         /// byte patterns. For file overwriting to be effective, the underlying
1417         /// file must be stored on a fixed-block filesystem. Systems with
1418         /// journaling or logging filesystems will require operating system
1419         /// support and probably modification of the Berkeley DB sources.
1420         /// </remarks>
1421         public bool Overwrite {
1422             get {
1423                 uint flags = 0;
1424                 dbenv.get_flags(ref flags);
1425                 return (flags & DbConstants.DB_OVERWRITE) != 0;
1426             }
1427             set {
1428                 dbenv.set_flags(DbConstants.DB_OVERWRITE, value ? 1 : 0);
1429             }
1430         }
1431         /// <summary>
1432         /// If true, allocate region memory from the heap instead of from memory
1433         /// backed by the filesystem or system shared memory. 
1434         /// </summary>
1435         public bool Private { 
1436             get {
1437                 uint flags = 0;
1438                 dbenv.get_open_flags(ref flags);
1439                 return (flags & DbConstants.DB_PRIVATE) != 0;
1440             }
1441         }
1442         /// <summary>
1443         /// The gigabytes component of the byte-count limit on the amount of
1444         /// memory to be used by shared structures in the main environment
1445         /// region. These are the structures other than mutexes and the page
1446         /// cache (memory pool).
1447         /// </summary>
1448         /// <returns>The maximum number of gigabytes used by the main region.
1449         /// </returns>
1450         public uint RegionMemoryLimitGBytes {
1451             get {
1452                 uint gb = 0;
1453                 uint b = 0;
1454                 dbenv.get_memory_max(ref gb, ref b);
1455                 return gb;
1456             }
1457         }
1458         /// <summary>
1459         /// The bytes component of the byte-count limit on the amount of
1460         /// memory to be used by shared structures in the main environment
1461         /// region. These are the structures other than mutexes and the page
1462         /// cache (memory pool).
1463         /// </summary>
1464         /// <returns>The maximum number of bytes used by the main region.
1465         /// </returns>
1466         public uint RegionMemoryLimitBytes {
1467             get {
1468                 uint gb = 0;
1469                 uint b = 0;
1470                 dbenv.get_memory_max(ref gb, ref b);
1471                 return b;
1472             }
1473         }
1474         /// <summary>
1475         /// The amount of memory to be used by shared structures in the main
1476         /// environment region. These are structures other than mutexes and
1477         /// the page cache (memory pool).
1478         /// </summary>
1479         /// <param name="GBytes">
1480         /// The number of gigabytes to allocate for the main memory region.
1481         /// The gigabytes allocated will be added to the bytes input.
1482         /// </param>
1483         /// <param name="Bytes">
1484         /// The number of gigabytes to allocate for the main memory region.
1485         /// The bytes allocated will be added to the gigabytes input.
1486         /// </param>
1487         public void RegionSetMemoryLimit(uint GBytes, uint Bytes) {
1488             dbenv.set_memory_max(GBytes, Bytes);
1489         }
1490         /// <summary>
1491         /// If true, Berkeley DB will have checked to see if recovery needed to
1492         /// be performed before opening the database environment.
1493         /// </summary>
1494         public bool Register { 
1495             get {
1496                 uint flags = 0;
1497                 dbenv.get_open_flags(ref flags);
1498                 return (flags & DbConstants.DB_REGISTER) != 0;
1499             }
1500         }
1501         /// <summary>
1502         /// The amount of time the replication manager's transport function
1503         /// waits to collect enough acknowledgments from replication group
1504         /// clients, before giving up and returning a failure indication. The
1505         /// default wait time is 1 second.
1506         /// </summary>
1507         public uint RepAckTimeout {
1508             get { return getRepTimeout(DbConstants.DB_REP_ACK_TIMEOUT); }
1509             set { 
1510                 dbenv.rep_set_timeout(
1511                     DbConstants.DB_REP_ACK_TIMEOUT, value); 
1512             }
1513         }
1514         /// <summary>
1515         /// If true, the replication master sends groups of records to the
1516         /// clients in a single network transfer
1517         /// </summary>
1518         public bool RepBulkTransfer {
1519             get { return getRepConfig(DbConstants.DB_REP_CONF_BULK); }
1520             set { 
1521                 dbenv.rep_set_config(
1522                     DbConstants.DB_REP_CONF_BULK, value ? 1 : 0);
1523             }
1524         }
1525         /// <summary>
1526         /// The amount of time a master site will delay between completing a
1527         /// checkpoint and writing a checkpoint record into the log.
1528         /// </summary>
1529         /// <remarks>
1530         /// This delay allows clients to complete their own checkpoints before
1531         /// the master requires completion of them. The default is 30 seconds.
1532         /// If all databases in the environment, and the environment's
1533         /// transaction log, are configured to reside in memory (never preserved
1534         /// to disk), then, although checkpoints are still necessary, the delay
1535         /// is not useful and should be set to 0.
1536         /// </remarks>
1537         public uint RepCheckpointDelay {
1538             get { return getRepTimeout(DbConstants.DB_REP_CHECKPOINT_DELAY); }
1539             set { 
1540                 dbenv.rep_set_timeout(
1541                     DbConstants.DB_REP_CHECKPOINT_DELAY, value);
1542             }
1543         }
1544         /// <summary>
1545         /// The value, relative to <see cref="RepClockskewSlow"/>, of the
1546         /// fastest clock in the group of sites.
1547         /// </summary>
1548         public uint RepClockskewFast {
1549             get {
1550                 uint fast = 0;
1551                 uint slow = 0;
1552                 dbenv.rep_get_clockskew(ref fast, ref slow);
1553                 return fast;
1554             }
1555         }
1556         /// <summary>
1557         /// The value of the slowest clock in the group of sites.
1558         /// </summary>
1559         public uint RepClockskewSlow {
1560             get {
1561                 uint fast = 0;
1562                 uint slow = 0;
1563                 dbenv.rep_get_clockskew(ref fast, ref slow);
1564                 return slow;
1565             }
1566         }
1567         /// <summary>
1568         /// Set the clock skew ratio among replication group members based on
1569         /// the fastest and slowest measurements among the group for use with
1570         /// master leases.
1571         /// </summary>
1572         /// <remarks>
1573         /// <para>
1574         /// Calling this method is optional, the default values for clock skew
1575         /// assume no skew. The user must also configure leases via
1576         /// <see cref="RepUseMasterLeases"/>. Additionally, the user must also
1577         /// set the master lease timeout via <see cref="RepLeaseTimeout"/> and
1578         /// the number of sites in the replication group via
1579         /// <see cref="RepNSites"/>. These settings may be configured in any
1580         /// order. For a description of the clock skew values, see Clock skew 
1581         /// in the Berkeley DB Programmer's Reference Guide. For a description
1582         /// of master leases, see Master leases in the Berkeley DB Programmer's
1583         /// Reference Guide.
1584         /// </para>
1585         /// <para>
1586         /// These arguments can be used to express either raw measurements of a
1587         /// clock timing experiment or a percentage across machines. For
1588         /// instance a group of sites have a 2% variance, then
1589         /// <paramref name="fast"/> should be set to 102, and
1590         /// <paramref name="slow"/> should be set to 100. Or, for a 0.03%
1591         /// difference, you can use 10003 and 10000 respectively.
1592         /// </para>
1593         /// </remarks>
1594         /// <param name="fast">
1595         /// The value, relative to <paramref name="slow"/>, of the fastest clock
1596         /// in the group of sites.
1597         /// </param>
1598         /// <param name="slow">
1599         /// The value of the slowest clock in the group of sites.
1600         /// </param>
1601         public void RepSetClockskew(uint fast, uint slow) {
1602             dbenv.rep_set_clockskew(fast, slow);
1603         }
1604         /// <summary>
1605         /// The amount of time the replication manager will wait before trying
1606         /// to re-establish a connection to another site after a communication
1607         /// failure. The default wait time is 30 seconds.
1608         /// </summary>
1609         public uint RepConnectionRetry {
1610             get { return getRepTimeout(DbConstants.DB_REP_CONNECTION_RETRY); }
1611             set { 
1612                 dbenv.rep_set_timeout(
1613                     DbConstants.DB_REP_CONNECTION_RETRY, value);
1614             }
1615         }
1616         /// <summary>
1617         /// If true, the client should delay synchronizing to a newly declared
1618         /// master (defaults to false). Clients configured in this way will remain
1619         /// unsynchronized until the application calls <see cref="RepSync"/>. 
1620         /// </summary>
1621         public bool RepDelayClientSync {
1622             get { return getRepConfig(DbConstants.DB_REP_CONF_DELAYCLIENT); }
1623             set { 
1624                 dbenv.rep_set_config(
1625                     DbConstants.DB_REP_CONF_DELAYCLIENT, value ? 1 : 0);
1626             }
1627         }
1628         /// <summary>
1629         /// Configure the amount of time the replication manager will wait
1630         /// before retrying a failed election. The default wait time is 10
1631         /// seconds. 
1632         /// </summary>
1633         public uint RepElectionRetry {
1634             get { return getRepTimeout(DbConstants.DB_REP_ELECTION_RETRY); }
1635             set { 
1636                 dbenv.rep_set_timeout(DbConstants.DB_REP_ELECTION_RETRY, value);
1637             }
1638         }
1639         /// <summary>
1640         /// The timeout period for an election. The default timeout is 2
1641         /// seconds.
1642         /// </summary>
1643         public uint RepElectionTimeout {
1644             get { return getRepTimeout(DbConstants.DB_REP_ELECTION_TIMEOUT); }
1645             set { 
1646                 dbenv.rep_set_timeout(
1647                     DbConstants.DB_REP_ELECTION_TIMEOUT, value);
1648             }
1649         }
1650         /// <summary>
1651         /// An optional configuration timeout period to wait for full election
1652         /// participation the first time the replication group finds a master.
1653         /// By default this option is turned off and normal election timeouts
1654         /// are used. (See the Elections section in the Berkeley DB Reference
1655         /// Guide for more information.) 
1656         /// </summary>
1657         public uint RepFullElectionTimeout {
1658             get { 
1659                 return getRepTimeout(
1660                     DbConstants.DB_REP_FULL_ELECTION_TIMEOUT);
1661             }
1662             set { 
1663                 dbenv.rep_set_timeout(
1664                     DbConstants.DB_REP_FULL_ELECTION_TIMEOUT, value);
1665             }
1666         }
1667         /// <summary>
1668         /// The amount of time the replication manager, running at a client
1669         /// site, waits for some message activity on the connection from the
1670         /// master (heartbeats or other messages) before concluding that the
1671         /// connection has been lost. When 0 (the default), no monitoring is
1672         /// performed.
1673         /// </summary>
1674         public uint RepHeartbeatMonitor {
1675             get { return getRepTimeout(DbConstants.DB_REP_HEARTBEAT_MONITOR); }
1676             set { 
1677                 dbenv.rep_set_timeout(
1678                     DbConstants.DB_REP_HEARTBEAT_MONITOR, value);
1679             }
1680         }
1681         /// <summary>
1682         /// The frequency at which the replication manager, running at a master
1683         /// site, broadcasts a heartbeat message in an otherwise idle system.
1684         /// When 0 (the default), no heartbeat messages will be sent. 
1685         /// </summary>
1686         public uint RepHeartbeatSend {
1687             get { return getRepTimeout(DbConstants.DB_REP_HEARTBEAT_SEND); }
1688             set { 
1689                 dbenv.rep_set_timeout(DbConstants.DB_REP_HEARTBEAT_SEND, value);
1690             }
1691         }
1692         /// <summary>
1693         /// If true, replication only stores the internal information in-memory
1694         /// and cannot keep persistent state across a site crash or reboot. By
1695         /// default, it is false and replication creates files in the
1696         /// environment home directory to preserve the internal information.
1697         /// </summary>
1698         public bool RepInMemory {
1699             get { return getRepConfig(DbConstants.DB_REP_CONF_INMEM); }
1700         }
1701         /// <summary>
1702         /// The amount of time a client grants its master lease to a master.
1703         /// When using master leases all sites in a replication group must use
1704         /// the same lease timeout value. There is no default value. If leases
1705         /// are desired, this method must be called prior to calling
1706         /// <see cref="RepStartClient"/> or <see cref="RepStartMaster"/>.
1707         /// </summary>
1708         public uint RepLeaseTimeout {
1709             get { return getRepTimeout(DbConstants.DB_REP_LEASE_TIMEOUT); }
1710             set { 
1711                 dbenv.rep_set_timeout(DbConstants.DB_REP_LEASE_TIMEOUT, value);
1712             }
1713         }
1714         /// <summary>
1715         /// Set the message dispatch function. It is responsible for receiving
1716         /// messages sent from remote sites using either 
1717         /// <see cref="DbChannel.SendMessage"/> or <see cref="DbChannel.SendRequest"/>.
1718         /// If the message received by this function was sent using 
1719         /// <see cref="DbChannel.SendMessage"/>, then no response is required.
1720         /// If the message was sent using <see cref="DbChannel.SendRequest"/>,
1721         /// then this function must send a response using 
1722         /// <see cref="DbChannel.SendMessage"/>.
1723         /// </summary>
1724         /// <remarks>
1725         /// It should be called before the Replication Manager has been started. 
1726         /// </remarks>
1727         public MessageDispatchDelegate RepMessageDispatch {
1728             get { return messageDispatchHandler; }
1729             set {
1730                 if (value == null)
1731                     dbenv.repmgr_msg_dispatch(null, 0);
1732                 else if (messageDispatchHandler == null) {
1733                     if (doMessageDispatchRef == null)
1734                         doMessageDispatchRef = new BDB_MessageDispatchDelegate(
1735                             doMessageDispatch);
1736                     dbenv.repmgr_msg_dispatch(doMessageDispatchRef, 0);
1737                 }
1738                 messageDispatchHandler = value;
1739             }
1740         }
1741         /// <summary>
1742         /// Specify how master and client sites will handle acknowledgment of
1743         /// replication messages which are necessary for "permanent" records.
1744         /// The current implementation requires all sites in a replication group
1745         /// configure the same acknowledgement policy. 
1746         /// </summary>
1747         /// <seealso cref="RepAckTimeout"/>
1748         public AckPolicy RepMgrAckPolicy {
1749             get {
1750                 int policy = 0;
1751                 dbenv.repmgr_get_ack_policy(ref policy);
1752                 return AckPolicy.fromInt(policy);
1753             }
1754             set { dbenv.repmgr_set_ack_policy(value.Policy); }
1755         }
1756         /// <summary>
1757         /// Create DbChannel with given eid.
1758         /// </summary>
1759         /// <param name="eid">
1760         /// Environment id. If the eid is <see cref="EnvironmentID.EID_MASTER"/>,
1761         /// create channel sending to master site only.
1762         /// </param>
1763         public DbChannel RepMgrChannel(int eid) {
1764             DB_CHANNEL dbChannel;
1765             dbChannel = dbenv.repmgr_channel(eid, 0);
1766             return new DbChannel(dbChannel);
1767         }
1768         /// <summary>
1769         /// If true, Replication Manager automatically runs elections to
1770         /// choose a new master when the old master appears to
1771         /// have become disconnected (defaults to true).
1772         /// </summary>
1773         public bool RepMgrRunElections {
1774             get { return getRepConfig(DbConstants.DB_REPMGR_CONF_ELECTIONS); }
1775             set { 
1776                 dbenv.rep_set_config(
1777                     DbConstants.DB_REPMGR_CONF_ELECTIONS, value ? 1 : 0);
1778             }
1779         }
1780         /// <summary>
1781         /// The local site of the replication manager. Returns null if the
1782         /// local site has not been configured.
1783         /// </summary>
1784         public DbSite RepMgrLocalSite {
1785             get {
1786                 DB_SITE site;
1787                 try {
1788                     site = dbenv.repmgr_local_site();
1789                 } catch (NotFoundException) {
1790                     // Local site wasn't set.
1791                     return null;
1792                 }
1793                 return new DbSite(site);
1794             }
1795         }
1796         /// <summary>
1797         /// The status of the sites currently known by the replication manager. 
1798         /// </summary>
1799         public RepMgrSite[] RepMgrRemoteSites {
1800             get { return dbenv.repmgr_site_list(); }
1801         }
1802         /// <summary>
1803         /// If true, the replication master will automatically re-initialize
1804         /// outdated clients (defaults to true). 
1805         /// </summary>
1806         public bool RepAutoInit {
1807             get { return getRepConfig(DbConstants.DB_REP_CONF_AUTOINIT); }
1808             set {
1809                 dbenv.rep_set_config(
1810                     DbConstants.DB_REP_CONF_AUTOINIT, value ? 1 : 0);
1811             }
1812         }
1813         /// <summary>
1814         /// If true, Berkeley DB method calls that would normally block while
1815         /// clients are in recovery will return errors immediately (defaults to
1816         /// false).
1817         /// </summary>
1818         public bool RepNoBlocking {
1819             get { return getRepConfig(DbConstants.DB_REP_CONF_NOWAIT); }
1820             set { 
1821                 dbenv.rep_set_config(
1822                     DbConstants.DB_REP_CONF_NOWAIT, value ? 1 : 0);
1823             }
1824         }
1825         /// <summary>
1826         /// The total number of sites in the replication group.
1827         /// </summary>
1828         /// <remarks>
1829         /// <para>
1830         /// This setting is typically used by applications which use the
1831         /// Berkeley DB library "replication manager" support. (However, see
1832         /// also <see cref="RepHoldElection"/>, the description of the nsites
1833         /// parameter.)
1834         /// </para>
1835         /// </remarks>
1836         public uint RepNSites {
1837             get {
1838                 uint ret = 0;
1839                 dbenv.rep_get_nsites(ref ret);
1840                 return ret;
1841             }
1842             set { dbenv.rep_set_nsites(value); }
1843         }
1844         /// <summary>
1845         /// The database environment's priority in replication group elections.
1846         /// A special value of 0 indicates that this environment cannot be a
1847         /// replication group master. If not configured, then a default value
1848         /// of 100 is used.
1849         /// </summary>
1850         public uint RepPriority {
1851             get {
1852                 uint ret = 0;
1853                 dbenv.rep_get_priority(ref ret);
1854                 return ret;
1855             }
1856             set { dbenv.rep_set_priority(value); }
1857         }
1858         /// <summary>
1859         /// The minimum number of microseconds a client waits before requesting
1860         /// retransmission.
1861         /// </summary>
1862         public uint RepRetransmissionRequestMin {
1863             get {
1864                 uint min = 0;
1865                 uint max = 0;
1866                 dbenv.rep_get_request(ref min, ref max);
1867                 return min;
1868             }
1869         }
1870         /// <summary>
1871         /// The maximum number of microseconds a client waits before requesting
1872         /// retransmission.
1873         /// </summary>
1874         public uint RepRetransmissionRequestMax {
1875             get {
1876                 uint min = 0;
1877                 uint max = 0;
1878                 dbenv.rep_get_request(ref min, ref max);
1879                 return max;
1880             }
1881         }
1882         /// <summary>
1883         /// Set a threshold for the minimum and maximum time that a client waits
1884         /// before requesting retransmission of a missing message.
1885         /// </summary>
1886         /// <remarks>
1887         /// <para>
1888         /// If the client detects a gap in the sequence of incoming log records
1889         /// or database pages, Berkeley DB will wait for at least
1890         /// <paramref name="min"/> microseconds before requesting retransmission
1891         /// of the missing record. Berkeley DB will double that amount before
1892         /// requesting the same missing record again, and so on, up to a
1893         /// maximum threshold of <paramref name="max"/> microseconds.
1894         /// </para>
1895         /// <para>
1896         /// These values are thresholds only. Since Berkeley DB has no thread
1897         /// available in the library as a timer, the threshold is only checked
1898         /// when a thread enters the Berkeley DB library to process an incoming
1899         /// replication message. Any amount of time may have passed since the
1900         /// last message arrived and Berkeley DB only checks whether the amount
1901         /// of time since a request was made is beyond the threshold value or
1902         /// not.
1903         /// </para>
1904         /// <para>
1905         /// By default the minimum is 40000 and the maximum is 1280000 (1.28
1906         /// seconds). These defaults are fairly arbitrary and the application
1907         /// likely needs to adjust these. The values should be based on expected
1908         /// load and performance characteristics of the master and client host
1909         /// platforms and transport infrastructure as well as round-trip message
1910         /// time.
1911         /// </para></remarks>
1912         /// <param name="min">
1913         /// The minimum number of microseconds a client waits before requesting
1914         /// retransmission.
1915         /// </param>
1916         /// <param name="max">
1917         /// The maximum number of microseconds a client waits before requesting
1918         /// retransmission.
1919         /// </param>
1920         public void RepSetRetransmissionRequest(uint min, uint max) {
1921             dbenv.rep_set_request(min, max);
1922         }
1923         /// <summary>
1924         /// Replication Manager observes the strict "majority" rule in managing
1925         /// elections, even in a group with only 2 sites. This means the client
1926         /// in a 2-site group will be unable to take over as master if the
1927         /// original master fails or becomes disconnected. (See the Elections
1928         /// section in the Berkeley DB Reference Guide for more information.)
1929         /// Both sites in the replication group should have the same value for
1930         /// this parameter.
1931         /// </summary>
1932         public bool RepStrict2Site {
1933             get { 
1934                 return getRepConfig(DbConstants.DB_REPMGR_CONF_2SITE_STRICT);
1935             }
1936             set {
1937                 dbenv.rep_set_config(
1938                     DbConstants.DB_REPMGR_CONF_2SITE_STRICT, value ? 1 : 0);
1939             }
1940         }
1941         /// <summary>
1942         /// The gigabytes component of the byte-count limit on the amount of
1943         /// data that will be transmitted from a site in response to a single
1944         /// message processed by <see cref="RepProcessMessage"/>.
1945         /// </summary>
1946         public uint RepTransmitLimitGBytes {
1947             get {
1948                 uint gb = 0;
1949                 uint b = 0;
1950                 dbenv.rep_get_limit(ref gb, ref b);
1951                 return gb;
1952             }
1953         }
1954         /// <summary>
1955         /// The bytes component of the byte-count limit on the amount of data
1956         /// that will be transmitted from a site in response to a single
1957         /// message processed by <see cref="RepProcessMessage"/>.
1958         /// </summary>
1959         public uint RepTransmitLimitBytes {
1960             get {
1961                 uint gb = 0;
1962                 uint b = 0;
1963                 dbenv.rep_get_limit(ref gb, ref b);
1964                 return b;
1965             }
1966         }
1967         /// <summary>
1968         /// Set a byte-count limit on the amount of data that will be
1969         /// transmitted from a site in response to a single message processed by
1970         /// <see cref="RepProcessMessage"/>. The limit is not a hard limit, and
1971         /// the record that exceeds the limit is the last record to be sent. 
1972         /// </summary>
1973         /// <remarks>
1974         /// <para>
1975         /// Record transmission throttling is turned on by default with a limit
1976         /// of 10MB.
1977         /// </para>
1978         /// <para>
1979         /// If both <paramref name="GBytes"/> and <paramref name="Bytes"/> are
1980         /// zero, then the transmission limit is turned off.
1981         /// </para>
1982         /// </remarks>
1983         /// <param name="GBytes">
1984         /// The number of gigabytes which, when added to
1985         /// <paramref name="Bytes"/>, specifies the maximum number of bytes that
1986         /// will be sent in a single call to <see cref="RepProcessMessage"/>.
1987         /// </param>
1988         /// <param name="Bytes">
1989         /// The number of bytes which, when added to 
1990         /// <paramref name="GBytes"/>, specifies the maximum number of bytes
1991         /// that will be sent in a single call to
1992         /// <see cref="RepProcessMessage"/>.
1993         /// </param>
1994         public void RepSetTransmitLimit(uint GBytes, uint Bytes) {
1995             dbenv.rep_set_limit(GBytes, Bytes);
1996         }
1997         /// <summary>
1998         /// The delegate used to transmit data using the replication
1999         /// application's communication infrastructure.
2000         /// </summary>
2001         public ReplicationTransportDelegate RepTransport { 
2002             get { return transportHandler; }
2003         }
2004         /// <summary>
2005         /// Initialize the communication infrastructure for a database
2006         /// environment participating in a replicated application.
2007         /// </summary>
2008         /// <remarks>
2009         /// RepSetTransport is not called by most replication applications. It
2010         /// should only be called by applications implementing their own network
2011         /// transport layer, explicitly holding replication group elections and
2012         /// handling replication messages outside of the replication manager
2013         /// framework.
2014         /// </remarks>
2015         /// <param name="envid">
2016         /// The local environment's ID. It must be a non-negative integer and
2017         /// uniquely identify this Berkeley DB database environment (see
2018         /// Replication environment IDs in the Programmer's Reference Guide for
2019         /// more information).
2020         /// </param>
2021         /// <param name="transport">
2022         /// The delegate used to transmit data using the replication
2023         /// application's communication infrastructure.
2024         /// </param>
2025         public void RepSetTransport(int envid,
2026             ReplicationTransportDelegate transport) {
2027             if (transport == null)
2028                 dbenv.rep_set_transport(envid, null);
2029             else if (transportHandler == null) {
2030                 if (doRepTransportRef == null)
2031                     doRepTransportRef = new BDB_RepTransportDelegate(doRepTransport);
2032                 dbenv.rep_set_transport(envid, doRepTransportRef);
2033             }                    
2034             transportHandler = transport;
2035         }
2036         /// <summary>
2037         /// If true, master leases will be used for this site (defaults to
2038         /// false). 
2039         /// </summary>
2040         /// <remarks>
2041         /// Configuring this option may result in a 
2042         /// <see cref="LeaseExpiredException"/> when attempting to read entries
2043         /// from a database after the site's master lease has expired.
2044         /// </remarks>
2045         public bool RepUseMasterLeases {
2046             get { return getRepConfig(DbConstants.DB_REP_CONF_LEASE); }
2047             set {
2048                 dbenv.rep_set_config(
2049                     DbConstants.DB_REP_CONF_LEASE, value ? 1 : 0);
2050             }
2051         }
2052         /// <summary>
2053         /// If true, catastrophic recovery was run on this environment before
2054         /// opening it for normal use.
2055         /// </summary>
2056         public bool RunFatalRecovery {
2057             get {
2058                 uint flags = 0;
2059                 dbenv.get_open_flags(ref flags);
2060                 return (flags & DbConstants.DB_RECOVER_FATAL) != 0;
2061             }
2062         }
2063         /// <summary>
2064         /// If true, normal recovery was run on this environment before opening
2065         /// it for normal use.
2066         /// </summary>
2067         public bool RunRecovery {
2068             get {
2069                 uint flags = 0;
2070                 dbenv.get_open_flags(ref flags);
2071                 return (flags & DbConstants.DB_RECOVER) != 0;
2072             }
2073         }
2074         /// <summary>
2075         /// The number of microseconds the thread of control will pause before
2076         /// scheduling further write operations.
2077         /// </summary>
2078         public uint SequentialWritePause {
2079             get {
2080                 int tmp = 0;
2081                 uint ret = 0;
2082                 dbenv.get_mp_max_write(ref tmp, ref ret);
2083                 return ret;
2084             }
2085         }
2086         /// <summary>
2087         /// A delegate that returns a unique identifier pair for the current 
2088         /// thread of control.
2089         /// </summary>
2090         /// <remarks>
2091         /// This delegate supports <see cref="FailCheck"/>. For more
2092         /// information, see Architecting Data Store and Concurrent Data Store
2093         /// applications, and Architecting Transactional Data Store
2094         /// applications, both in the Berkeley DB Programmer's Reference Guide.
2095         /// </remarks>
2096         public SetThreadIDDelegate SetThreadID {
2097             get { return threadIDHandler; }
2098             set {
2099                 if (value == null)
2100                     dbenv.set_thread_id(null);
2101                 else if (threadIDHandler == null) {
2102                     if (doThreadIDRef == null)
2103                         doThreadIDRef = new BDB_ThreadIDDelegate(doThreadID);
2104                     dbenv.set_thread_id(doThreadIDRef);
2105                 }
2106                 threadIDHandler = value;
2107             }
2108         }
2109         /// <summary>
2110         /// A delegate that formats a process ID and thread ID identifier pair. 
2111         /// </summary>
2112         public SetThreadNameDelegate SetThreadName {
2113             get { return threadNameHandler; }
2114             set {
2115                 if (value == null)
2116                     dbenv.set_thread_id_string(null);
2117                 else if (threadNameHandler == null) {
2118                     if (doThreadNameRef == null)
2119                         doThreadNameRef =
2120                             new BDB_ThreadNameDelegate(doThreadName);
2121                     dbenv.set_thread_id_string(doThreadNameRef);
2122                 }
2123                 threadNameHandler = value;
2124             }
2125         }
2126         /// <summary>
2127         /// If true, allocate region memory from system shared memory instead of
2128         /// from heap memory or memory backed by the filesystem. 
2129         /// </summary>
2130         public bool SystemMemory {
2131             get {
2132                 uint flags = 0;
2133                 dbenv.get_open_flags(ref flags);
2134                 return (flags & DbConstants.DB_SYSTEM_MEM) != 0;
2135             }
2136         }
2137         /// <summary>
2138         /// The path of a directory to be used as the location of temporary
2139         /// files.
2140         /// </summary>
2141         /// <remarks>
2142         /// <para>
2143         /// The files created to back in-memory access method databases will be
2144         /// created relative to this path. These temporary files can be quite
2145         /// large, depending on the size of the database.
2146         /// </para>
2147         /// <para>
2148         /// If no directories are specified, the following alternatives are
2149         /// checked in the specified order. The first existing directory path is
2150         /// used for all temporary files.
2151         /// </para>
2152         /// <list type="number">
2153         /// <item>The value of the environment variable TMPDIR.</item>
2154         /// <item>The value of the environment variable TEMP.</item>
2155         /// <item>The value of the environment variable TMP.</item>
2156         /// <item>The value of the environment variable TempFolder.</item>
2157         /// <item>The value returned by the GetTempPath interface.</item>
2158         /// <item>The directory /var/tmp.</item>
2159         /// <item>The directory /usr/tmp.</item>
2160         /// <item>The directory /temp.</item>
2161         /// <item>The directory /tmp.</item>
2162         /// <item>The directory C:/temp.</item>
2163         /// <item>The directory C:/tmp.</item>
2164         /// </list>
2165         /// <para>
2166         /// Environment variables are only checked if
2167         /// <see cref="UseEnvironmentVars"/> is true.
2168         /// </para>
2169         /// </remarks>
2170         public string TempDir {
2171             get {
2172                 string ret;
2173                 dbenv.get_tmp_dir(out ret);
2174                 return ret;
2175             }
2176             set { dbenv.set_tmp_dir(value); }
2177         }
2178         /// <summary>
2179         /// An approximate number of threads in the database environment.
2180         /// </summary>
2181         public uint ThreadCount {
2182             get {
2183                 uint ret = 0;
2184                 dbenv.get_thread_count(ref ret);
2185                 return ret;
2186             }
2187             private set { dbenv.set_thread_count(value); }
2188         }
2189         /// <summary>
2190         /// A delegate that returns if a thread of control (either a true thread
2191         /// or a process) is still running.
2192         /// </summary>
2193         public ThreadIsAliveDelegate ThreadIsAlive {
2194             get { return isAliveHandler; }
2195             set {
2196                 if (value == null)
2197                     dbenv.set_isalive(null);
2198                 else if (isAliveHandler == null) {
2199                     if (doIsAliveRef == null)
2200                         doIsAliveRef = new BDB_IsAliveDelegate(doIsAlive);
2201                     dbenv.set_isalive(doIsAliveRef);
2202                 }
2203                 isAliveHandler = value;
2204             }
2205         }
2206         /// <summary>
2207         /// If true, database calls timing out based on lock or transaction
2208         /// timeout values will throw <see cref="LockNotGrantedException"/>
2209         /// instead of <see cref="DeadlockException"/>.
2210         /// </summary>
2211         /// <remarks>
2212         /// If true, this allows applications to distinguish between operations
2213         /// which have deadlocked and operations which have exceeded their time
2214         /// limits.
2215         /// </remarks>
2216         public bool TimeNotGranted {
2217             get {
2218                 uint flags = 0;
2219                 dbenv.get_flags(ref flags);
2220                 return (flags & DbConstants.DB_TIME_NOTGRANTED) != 0;
2221             }
2222             set {
2223                 dbenv.set_flags(DbConstants.DB_TIME_NOTGRANTED, value ? 1 : 0);
2224             }
2225         }
2226         /// <summary>
2227         /// If true, Berkeley DB will not write or synchronously flush the log
2228         /// on transaction commit.
2229         /// </summary>
2230         /// <remarks>
2231         /// This means that transactions exhibit the ACI (atomicity,
2232         /// consistency, and isolation) properties, but not D (durability); that
2233         /// is, database integrity will be maintained, but if the application or
2234         /// system fails, it is possible some number of the most recently
2235         /// committed transactions may be undone during recovery. The number of
2236         /// transactions at risk is governed by how many log updates can fit
2237         /// into the log buffer, how often the operating system flushes dirty
2238         /// buffers to disk, and how often the log is checkpointed.
2239         /// </remarks>
2240         public bool TxnNoSync {
2241             get {
2242                 uint flags = 0;
2243                 dbenv.get_flags(ref flags);
2244                 return (flags & DbConstants.DB_TXN_NOSYNC) != 0;
2245             }
2246             set { dbenv.set_flags(DbConstants.DB_TXN_NOSYNC, value ? 1 : 0); }
2247         }
2248         /// <summary>
2249         /// If true and a lock is unavailable for any Berkeley DB operation
2250         /// performed in the context of a transaction, cause the operation to 
2251         /// throw <see cref="DeadlockException"/> (or
2252         /// <see cref="LockNotGrantedException"/> if configured with
2253         /// <see cref="TimeNotGranted"/>).
2254         /// </summary>
2255         public bool TxnNoWait {
2256             get {
2257                 uint flags = 0;
2258                 dbenv.get_flags(ref flags);
2259                 return (flags & DbConstants.DB_TXN_NOWAIT) != 0;
2260             }
2261             set { dbenv.set_flags(DbConstants.DB_TXN_NOWAIT, value ? 1 : 0); }
2262         }
2263         /// <summary>
2264         /// If true, all transactions in the environment will be started as if
2265         /// <see cref="TransactionConfig.Snapshot"/> was passed to
2266         /// <see cref="BeginTransaction"/>, and all non-transactional cursors
2267         /// will be opened as if <see cref="CursorConfig.SnapshotIsolation"/>
2268         /// was passed to <see cref="BaseDatabase.Cursor"/>.
2269         /// </summary>
2270         public bool TxnSnapshot {
2271             get {
2272                 uint flags = 0;
2273                 dbenv.get_flags(ref flags);
2274                 return (flags & DbConstants.DB_TXN_SNAPSHOT) != 0;
2275             }
2276             set { dbenv.set_flags(DbConstants.DB_TXN_SNAPSHOT, value ? 1 : 0); }
2277         }
2278         /// <summary>
2279         /// A value, in microseconds, representing transaction timeouts.
2280         /// </summary>
2281         /// <remarks>
2282         /// <para>
2283         /// All timeouts are checked whenever a thread of control blocks on a
2284         /// lock or when deadlock detection is performed. As timeouts are only
2285         /// checked when the lock request first blocks or when deadlock
2286         /// detection is performed, the accuracy of the timeout depends on how
2287         /// often deadlock detection is performed.
2288         /// </para>
2289         /// <para>
2290         /// Timeout values specified for the database environment may be
2291         /// overridden on a per-transaction basis, see
2292         /// <see cref="Transaction.SetTxnTimeout"/>.
2293         /// </para>
2294         /// </remarks>
2295         public uint TxnTimeout {
2296             get {
2297                 uint timeout = 0;
2298                 dbenv.get_timeout(ref timeout, DbConstants.DB_SET_TXN_TIMEOUT);
2299                 return timeout;
2300             }
2301             set {
2302                 dbenv.set_timeout(value, DbConstants.DB_SET_TXN_TIMEOUT);
2303             }
2304         }
2305         /// <summary>
2306         /// The recovery timestamp
2307         /// </summary>
2308         public DateTime TxnTimestamp {
2309             get {
2310                 long secs = 0;
2311                 dbenv.get_tx_timestamp(ref secs);
2312                 DateTime epoch = new DateTime(1970, 1, 1);
2313                 DateTime ret = epoch.AddSeconds(secs);
2314                 return ret;
2315             }
2316             private set {
2317                 if (value != null) {
2318                     TimeSpan ts = value - new DateTime(1970, 1, 1);
2319                     long secs = (long)ts.TotalSeconds;
2320                     dbenv.set_tx_timestamp(ref secs);
2321                 }
2322             }
2323         }
2324         /// <summary>
2325         /// If true, Berkeley DB will write, but will not synchronously flush,
2326         /// the log on transaction commit. 
2327         /// </summary>
2328         /// <remarks>
2329         /// This means that transactions exhibit the ACI (atomicity,
2330         /// consistency, and isolation) properties, but not D (durability); that
2331         /// is, database integrity will be maintained, but if the system fails, 
2332         /// it is possible some number of the most recently committed
2333         /// transactions may be undone during recovery. The number of
2334         /// transactions at risk is governed by how often the system flushes
2335         /// dirty buffers to disk and how often the log is checkpointed.
2336         /// </remarks>
2337         public bool TxnWriteNoSync {
2338             get {
2339                 uint flags = 0;
2340                 dbenv.get_flags(ref flags);
2341                 return (flags & DbConstants.DB_TXN_WRITE_NOSYNC) != 0;
2342             }
2343             set {
2344                 dbenv.set_flags(DbConstants.DB_TXN_WRITE_NOSYNC, value ? 1 : 0);
2345             }
2346         }
2347         /// <summary>
2348         /// If true, all databases in the environment will be opened as if
2349         /// <see cref="DatabaseConfig.UseMVCC"/> was set.
2350         /// </summary>
2351         /// <remarks>
2352         /// This flag will be ignored for queue databases for which MVCC is not
2353         /// supported.
2354         /// </remarks>
2355         public bool UseMVCC {
2356             get {
2357                 uint flags = 0;
2358                 dbenv.get_flags(ref flags);
2359                 return (flags & DbConstants.DB_MULTIVERSION) != 0;
2360             }
2361             set { dbenv.set_flags(DbConstants.DB_MULTIVERSION, value ? 1 : 0); }
2362         }
2363         /// <summary>
2364         /// If true, locking for the Berkeley DB Concurrent Data Store product
2365         /// was initialized.
2366         /// </summary>
2367         public bool UsingCDB {
2368             get {
2369                 uint flags = 0;
2370                 dbenv.get_open_flags(ref flags);
2371                 return (flags & DbConstants.DB_INIT_CDB) != 0;
2372             }
2373         }
2374         /// <summary>
2375         /// If true, the locking subsystem was initialized.
2376         /// </summary>
2377         public bool UsingLocking {
2378             get {
2379                 uint flags = 0;
2380                 dbenv.get_open_flags(ref flags);
2381                 return (flags & DbConstants.DB_INIT_LOCK) != 0;
2382             }
2383         }
2384         /// <summary>
2385         /// If true, the logging subsystem was initialized.
2386         /// </summary>
2387         public bool UsingLogging {
2388             get {
2389                 uint flags = 0;
2390                 dbenv.get_open_flags(ref flags);
2391                 return (flags & DbConstants.DB_INIT_LOG) != 0;
2392             }
2393         }
2394         /// <summary>
2395         /// If true, the shared memory buffer pool subsystem was initialized.
2396         /// </summary>
2397         public bool UsingMPool {
2398             get {
2399                 uint flags = 0;
2400                 dbenv.get_open_flags(ref flags);
2401                 return (flags & DbConstants.DB_INIT_MPOOL) != 0;
2402             }
2403         }
2404         /// <summary>
2405         /// If true, the replication subsystem was initialized.
2406         /// </summary>
2407         public bool UsingReplication {
2408             get {
2409                 uint flags = 0;
2410                 dbenv.get_open_flags(ref flags);
2411                 return (flags & DbConstants.DB_INIT_REP) != 0;
2412             }
2413         }
2414         /// <summary>
2415         /// If true, the transaction subsystem was initialized.
2416         /// </summary>
2417         public bool UsingTxns {
2418             get {
2419                 uint flags = 0;
2420                 dbenv.get_open_flags(ref flags);
2421                 return (flags & DbConstants.DB_INIT_TXN) != 0;
2422             }
2423         }
2424         /// <summary>
2425         /// Specific additional informational and debugging messages in the
2426         /// Berkeley DB message output.
2427         /// </summary>
2428         public VerboseMessages Verbosity {
2429             get {
2430                 uint flags = 0;
2431                 dbenv.get_verbose(ref flags);
2432                 return VerboseMessages.FromFlags(flags);
2433             }
2434             set {
2435                 if (value.MessagesOff != 0)
2436                     dbenv.set_verbose(value.MessagesOff, 0);
2437                 if (value.MessagesOn != 0)
2438                     dbenv.set_verbose(value.MessagesOn, 1);
2439             }
2440         }
2441         /// <summary>
2442         /// If true, Berkeley DB will yield the processor immediately after each
2443         /// page or mutex acquisition.
2444         /// </summary>
2445         /// <remarks>
2446         /// This functionality should never be used for purposes other than
2447         /// stress testing.
2448         /// </remarks>
2449         public bool YieldCPU {
2450             get {
2451                 uint flags = 0;
2452                 dbenv.get_flags(ref flags);
2453                 return (flags & DbConstants.DB_YIELDCPU) != 0;
2454             }
2455             set {
2456                 dbenv.set_flags(DbConstants.DB_YIELDCPU, value ? 1 : 0);
2457             }
2458         }
2459         #endregion Properties
2460
2461         /// <summary>
2462         /// Instantiate a new DatabaseEnvironment object and open the Berkeley
2463         /// DB environment represented by <paramref name="home"/>.
2464         /// </summary>
2465         /// <param name="home">
2466         /// The database environment's home directory.  For more information on
2467         /// home, and filename resolution in general, see Berkeley DB File
2468         /// Naming in the Programmer's Reference Guide.
2469         /// </param>
2470         /// <param name="cfg">The environment's configuration</param>
2471         /// <returns>A new, open DatabaseEnvironment object</returns>
2472         public static DatabaseEnvironment Open(
2473             String home, DatabaseEnvironmentConfig cfg) {
2474             DatabaseEnvironment env = new DatabaseEnvironment(0);
2475             env.Config(cfg);
2476             env.dbenv.open(home, cfg.openFlags, 0);
2477             return env;
2478         }
2479
2480         /// <summary>
2481         /// Destroy a Berkeley DB environment if it is not currently in use.
2482         /// </summary>
2483         /// <overloads>
2484         /// <para>
2485         /// The environment regions, including any backing files, are removed.
2486         /// Any log or database files and the environment directory are not
2487         /// removed.
2488         /// </para>
2489         /// <para>
2490         /// If there are processes that have called <see cref="Open"/> without
2491         /// calling <see cref="Close"/> (that is, there are processes currently
2492         /// using the environment), Remove will fail without further action.
2493         /// </para>
2494         /// <para>
2495         /// Calling Remove should not be necessary for most applications because
2496         /// the Berkeley DB environment is cleaned up as part of normal database
2497         /// recovery procedures. However, applications may want to call Remove
2498         /// as part of application shut down to free up system resources. For
2499         /// example, if <see cref="DatabaseEnvironmentConfig.SystemMemory"/> was
2500         /// specified to <see cref="Open"/>, it may be useful to call Remove in
2501         /// order to release system shared memory segments that have been
2502         /// allocated. Or, on architectures in which mutexes require allocation
2503         /// of underlying system resources, it may be useful to call Remove in
2504         /// order to release those resources. Alternatively, if recovery is not
2505         /// required because no database state is maintained across failures,
2506         /// and no system resources need to be released, it is possible to clean
2507         /// up an environment by simply removing all the Berkeley DB files in
2508         /// the database environment's directories.
2509         /// </para>
2510         /// <para>
2511         /// In multithreaded applications, only a single thread may call Remove.
2512         /// </para>
2513         /// </overloads>
2514         /// <param name="db_home">
2515         /// The database environment to be removed.
2516         /// </param>
2517         public static void Remove(string db_home) {
2518             Remove(db_home, false, false, false);
2519         }
2520         /// <summary>
2521         /// Destroy a Berkeley DB environment if it is not currently in use.
2522         /// </summary>
2523         /// <remarks>
2524         /// <para>
2525         /// Generally, <paramref name="force"/> is specified only when
2526         /// applications were unable to shut down cleanly, and there is a risk
2527         /// that an application may have died holding a Berkeley DB lock.)
2528         /// </para>
2529         /// <para>
2530         /// The result of attempting to forcibly destroy the environment when it
2531         /// is in use is unspecified. Processes using an environment often
2532         /// maintain open file descriptors for shared regions within it. On UNIX
2533         /// systems, the environment removal will usually succeed, and processes
2534         /// that have already joined the region will continue to run in that
2535         /// region without change. However, processes attempting to join the
2536         /// environment will either fail or create new regions. On other systems
2537         /// in which the unlink(2) system call will fail if any process has an
2538         /// open file descriptor for the file (for example Windows/NT), the
2539         /// region removal will fail.
2540         /// </para>
2541         /// </remarks>
2542         /// <param name="db_home">
2543         /// The database environment to be removed.
2544         /// </param>
2545         /// <param name="force">
2546         /// If true, the environment is removed, regardless of any processes
2547         /// that may still using it, and no locks are acquired during this
2548         /// process.
2549         /// </param>
2550         public static void Remove(string db_home, bool force) {
2551             Remove(db_home, force, false, false);
2552         }
2553         private static void Remove(string db_home,
2554             bool force, bool USE_ENVIRON, bool USE_ENVIRON_ROOT) {
2555             DatabaseEnvironment env = new DatabaseEnvironment(0);
2556             uint flags = 0;
2557
2558             flags |= force ? DbConstants.DB_FORCE : 0;
2559             flags |= USE_ENVIRON ? DbConstants.DB_USE_ENVIRON : 0;
2560             flags |= USE_ENVIRON_ROOT ? DbConstants.DB_USE_ENVIRON_ROOT : 0;
2561             env.dbenv.remove(db_home, flags);
2562         }
2563
2564         /// <summary>
2565         /// Perform a hot back up of the open environment.
2566         /// <para>
2567         /// All files used by the environment are backed up, so long as the 
2568         /// normal rules for file placement are followed. For information on how
2569         /// files are normally placed relative to the environment directory, see
2570         /// the "Berkeley DB File Naming" section in the Berkeley DB Reference 
2571         /// Guide.
2572         /// </para>
2573         /// <para>
2574         /// By default, data directories and the log directory specified 
2575         /// relative to the home directory will be recreated relative to the 
2576         /// target directory. If absolute path names are used, then use the 
2577         /// <see cref="BackupOptions.SingleDir"/> method.
2578         /// </para>
2579         /// <para>
2580         /// This method provides the same functionality as the db_hotbackup
2581         /// utility.  However, this method does not perform the housekeeping
2582         /// actions performed by that utility. In particular, you may want to
2583         /// run a checkpoint before calling this method. To run a checkpoint, 
2584         /// use the <see cref="DatabaseEnvironment.Checkpoint"/> method. For 
2585         /// more information on checkpoints, see the "Checkpoint" section in the
2586         /// Berkeley DB Reference Guide.
2587         /// </para>
2588         /// <para>
2589         /// To back up a single database file within the environment, use the
2590         /// <see cref="DatabaseEnvironment.BackupDatabase"/> method.
2591         /// </para>
2592         /// <para>
2593         /// In addition to the configuration options available using the 
2594         /// <see cref="BackupOptions"/> class, additional tuning modifications 
2595         /// can be made using the <see cref="DatabaseEnvironment.BackupReadCount"/>,
2596         /// <see cref="DatabaseEnvironment.BackupReadSleepDuration"/>,
2597         /// <see cref="DatabaseEnvironment.BackupBufferSize"/>, and
2598         /// <see cref="DatabaseEnvironment.BackupWriteDirect"/> properties. 
2599         /// Alternatively, you can write your own custom hot back up facility 
2600         /// using the <see cref="IBackup"/> interface.
2601         /// </para>
2602         /// </summary>
2603         /// <param name="target">Identifies the directory in which the back up 
2604         /// will be placed. Any subdirectories required to contain the back up
2605         /// must be placed relative to this directory. Note that if an 
2606         /// <see cref="IBackup"/> is configured for the environment, then the
2607         /// value specified to this parameter is passed on to the 
2608         /// <see cref="IBackup.Open"/> method.  If this parameter is null, then
2609         /// the target must be specified to the <see cref="IBackup.Open"/>
2610         /// method.
2611         /// <para>
2612         /// This directory, and any required subdirectories, will be created for
2613         /// you if you specify <see cref="CreatePolicy.IF_NEEDED"/> or 
2614         /// <see cref="CreatePolicy.ALWAYS"/> for the 
2615         /// <see cref="BackupOptions.Creation"/> property.
2616         /// </para>
2617         /// </param>
2618         /// <param name="opt">The <see cref="BackupOptions"/> instance used to
2619         /// configure the hot back up.</param>
2620         public void Backup(string target, BackupOptions opt) {
2621             dbenv.backup(target, opt.flags);
2622         }
2623         /// <summary>
2624         /// Perform a hot back up of a single database file contained within the
2625         /// environment.
2626         /// <para>
2627         /// To back up the entire environment, use the 
2628         /// <see cref="DatabaseEnvironment.Backup"/> method.
2629         /// </para>
2630         /// <para>
2631         /// You can make some tuning modifications to the backup process using
2632         /// the <see cref="DatabaseEnvironment.BackupReadCount"/>,
2633         /// <see cref="DatabaseEnvironment.BackupReadSleepDuration"/>,
2634         /// <see cref="DatabaseEnvironment.BackupBufferSize"/>, and
2635         /// <see cref="DatabaseEnvironment.BackupWriteDirect"/> properties. 
2636         /// Alternatively, you can write your own custom hot back up facility 
2637         /// using the <see cref="IBackup"/> interface.
2638         /// </para>
2639         /// </summary>
2640         /// <param name="target">Identifies the directory in which the back up 
2641         /// will be placed.</param>
2642         /// <param name="database">The database file that you want to back up.
2643         /// </param>
2644         /// <param name="must_create">If true, then if the target file exists, 
2645         /// this method throws an exception.</param>
2646         public void BackupDatabase(
2647             string target, string database, bool must_create) {
2648             dbenv.dbbackup(
2649                 database, target, must_create ? DbConstants.DB_EXCL : 0);
2650         }
2651         
2652         /// <summary>
2653         /// Hold an election for the master of a replication group.
2654         /// </summary>
2655         public void RepHoldElection() {
2656             RepHoldElection(0, 0);
2657         }
2658         /// <summary>
2659         /// Hold an election for the master of a replication group.
2660         /// </summary>
2661         /// <param name="nsites">
2662         /// The number of replication sites expected to participate in the
2663         /// election. Once the current site has election information from that
2664         /// many sites, it will short-circuit the election and immediately cast
2665         /// its vote for a new master. If an application is using master leases,
2666         /// then the value must be 0 and <see cref="RepNSites"/> must be used.
2667         /// </param>
2668         public void RepHoldElection(uint nsites) {
2669             RepHoldElection(nsites, 0);
2670         }
2671         /// <summary>
2672         /// Hold an election for the master of a replication group.
2673         /// </summary>
2674         /// <overloads>
2675         /// <para>
2676         /// RepHoldElection is not called by most replication applications. It
2677         /// should only be called by applications implementing their own network
2678         /// transport layer, explicitly holding replication group elections and
2679         /// handling replication messages outside of the replication manager
2680         /// framework.
2681         /// </para>
2682         /// <para>
2683         /// If the election is successful, Berkeley DB will notify the
2684         /// application of the results of the election by means of either the 
2685         /// <see cref="NotificationEvent.REP_ELECTED"/> or 
2686         /// <see cref="NotificationEvent.REP_NEWMASTER"/> events (see 
2687         /// <see cref="EventNotify"/>for more information). The application is
2688         /// responsible for adjusting its relationship to the other database
2689         /// environments in the replication group, including directing all
2690         /// database updates to the newly selected master, in accordance with
2691         /// the results of the election.
2692         /// </para>
2693         /// <para>
2694         /// The thread of control that calls RepHoldElection must not be the
2695         /// thread of control that processes incoming messages; processing the
2696         /// incoming messages is necessary to successfully complete an election.
2697         /// </para>
2698         /// <para>
2699         /// Before calling this method, the <see cref="RepTransport"/> delegate 
2700         /// must already have been configured to send replication messages.
2701         /// </para>
2702         /// </overloads>
2703         /// <param name="nsites">
2704         /// The number of replication sites expected to participate in the
2705         /// election. Once the current site has election information from that
2706         /// many sites, it will short-circuit the election and immediately cast
2707         /// its vote for a new master. This parameter must be no less than
2708         /// <paramref name="nvotes"/>, or 0 if the election should use
2709         /// <see cref="RepNSites"/>. If an application is using master leases,
2710         /// then the value must be 0 and <see cref="RepNSites"/> must be used.
2711         /// </param>
2712         /// <param name="nvotes">
2713         /// The minimum number of replication sites from which the current site
2714         /// must have election information, before the current site will cast a
2715         /// vote for a new master. This parameter must be no greater than
2716         /// <paramref name="nsites"/>, or 0 if the election should use the value
2717         /// ((<paramref name="nsites"/> / 2) + 1).
2718         /// </param>
2719         public void RepHoldElection(uint nsites, uint nvotes) {
2720             dbenv.rep_elect(nsites, nvotes, 0);
2721         }
2722
2723         /// <summary>
2724         /// Configure a site in the replication manager.
2725         /// </summary>
2726         /// <param name="siteConfig">The configuration of a site</param>
2727         public void RepMgrSiteConfig(DbSiteConfig siteConfig) {
2728             DB_SITE dbSite;
2729             dbSite = dbenv.repmgr_site(siteConfig.Host, siteConfig.Port);
2730             if (siteConfig.helperIsSet)
2731                 dbSite.set_config(DbConstants.DB_BOOTSTRAP_HELPER,
2732                     Convert.ToUInt32(siteConfig.Helper));
2733             if (siteConfig.groupCreatorIsSet)
2734                 dbSite.set_config(DbConstants.DB_GROUP_CREATOR,
2735                     Convert.ToUInt32(siteConfig.GroupCreator));
2736             if (siteConfig.legacyIsSet)
2737                 dbSite.set_config(DbConstants.DB_LEGACY,
2738                     Convert.ToUInt32(siteConfig.Legacy));
2739             if (siteConfig.localSiteIsSet)
2740                 dbSite.set_config(DbConstants.DB_LOCAL_SITE,
2741                     Convert.ToUInt32(siteConfig.LocalSite));
2742             if (siteConfig.peerIsSet)
2743                 dbSite.set_config(DbConstants.DB_REPMGR_PEER,
2744                     Convert.ToUInt32(siteConfig.Peer));
2745             dbSite.close();
2746         }
2747
2748         /// <summary>
2749         /// Create DbSite with the given eid. 
2750         /// </summary>
2751         /// <remarks>
2752         /// It is only possible to use this method after env open, because EID
2753         /// values are not established before that time.
2754         /// </remarks>
2755         /// <param name="eid">The environment id</param>
2756         public DbSite RepMgrSite(int eid) {
2757             DB_SITE dbSite;
2758             dbSite = dbenv.repmgr_site_by_eid(eid);
2759             return new DbSite(dbSite);
2760         }
2761
2762         /// <summary>
2763         /// Create DbSite with the given host and port. 
2764         /// </summary>
2765         /// <param name="host">The host address</param>
2766         /// <param name="port">The port</param>
2767         public DbSite RepMgrSite(string host, uint port) {
2768             DB_SITE dbSite;
2769             dbSite = dbenv.repmgr_site(host, port);
2770             return new DbSite(dbSite);
2771         }
2772
2773         /// <summary>
2774         /// Start the replication manager as a client site, and do not call for
2775         /// an election.
2776         /// </summary>
2777         /// <overloads>
2778         /// <para>
2779         /// There are two ways to build Berkeley DB replication applications:
2780         /// the most common approach is to use the Berkeley DB library
2781         /// "replication manager" support, where the Berkeley DB library manages
2782         /// the replication group, including network transport, all replication
2783         /// message processing and acknowledgment, and group elections.
2784         /// Applications using the replication manager support generally make
2785         /// the following calls:
2786         /// </para>
2787         /// <list type="number">
2788         /// <item>
2789         /// Configure the local site in the replication group,
2790         /// <see cref="RepMgrLocalSite"/>.
2791         /// </item>
2792         /// <item>
2793         /// Call <see cref="RepMgrSiteConfig"/> to configure the remote
2794         /// site(s) in the replication group.
2795         /// </item>
2796         /// <item>Configure the message acknowledgment policy
2797         /// (<see cref="RepMgrAckPolicy"/>) which provides the replication group's
2798         /// transactional needs.
2799         /// </item>
2800         /// <item>
2801         /// Configure the local site's election priority,
2802         /// <see cref="RepPriority"/>.
2803         /// </item>
2804         /// <item>
2805         /// Call <see cref="RepMgrStartClient"/> or
2806         /// <see cref="RepMgrStartMaster"/> to start the replication
2807         /// application.
2808         /// </item>
2809         /// </list>
2810         /// <para>
2811         /// For more information on building replication manager applications,
2812         /// please see the Replication Getting Started Guide included in the
2813         /// Berkeley DB documentation.
2814         /// </para>
2815         /// <para>
2816         /// Applications with special needs (for example, applications using
2817         /// network protocols not supported by the Berkeley DB replication
2818         /// manager), must perform additional configuration and call other
2819         /// Berkeley DB replication methods. For more information on building
2820         /// advanced replication applications, please see the Base Replication
2821         /// API section in the Berkeley DB Programmer's Reference Guide for more
2822         /// information.
2823         /// </para>
2824         /// <para>
2825         /// Starting the replication manager consists of opening the TCP/IP
2826         /// listening socket to accept incoming connections, and starting all
2827         /// necessary background threads. When multiple processes share a
2828         /// database environment, only one process can open the listening
2829         /// socket; <see cref="RepMgrStartClient"/> (and
2830         /// <see cref="RepMgrStartMaster"/>) automatically open the socket in
2831         /// the first process to call it, and skips this step in the later calls
2832         /// from other processes.
2833         /// </para>
2834         /// </overloads>
2835         /// <param name="nthreads">
2836         /// Specify the number of threads of control created and dedicated to
2837         /// processing replication messages. In addition to these message
2838         /// processing threads, the replication manager creates and manages a
2839         /// few of its own threads of control.
2840         /// </param>
2841         public void RepMgrStartClient(int nthreads) {
2842             RepMgrStartClient(nthreads, false);
2843         }
2844         /// <summary>
2845         /// Start the replication manager as a client site, and optionally call
2846         /// for an election.
2847         /// </summary>
2848         /// <param name="nthreads">
2849         /// Specify the number of threads of control created and dedicated to
2850         /// processing replication messages. In addition to these message
2851         /// processing threads, the replication manager creates and manages a
2852         /// few of its own threads of control.
2853         /// </param>
2854         /// <param name="holdElection">
2855         /// If true, start as a client, and call for an election if no master is
2856         /// found.
2857         /// </param>
2858         public void RepMgrStartClient(int nthreads, bool holdElection) {
2859             dbenv.repmgr_start(nthreads,
2860                 holdElection ?
2861                 DbConstants.DB_REP_ELECTION : DbConstants.DB_REP_CLIENT);
2862         }
2863         /// <summary>
2864         /// Start the replication manager as a master site, and do not call for
2865         /// an election.
2866         /// </summary>
2867         /// <remarks>
2868         /// <para>
2869         /// There are two ways to build Berkeley DB replication applications:
2870         /// the most common approach is to use the Berkeley DB library
2871         /// "replication manager" support, where the Berkeley DB library manages
2872         /// the replication group, including network transport, all replication
2873         /// message processing and acknowledgment, and group elections.
2874         /// Applications using the replication manager support generally make
2875         /// the following calls:
2876         /// </para>
2877         /// <list type="number">
2878         /// <item>
2879         /// Configure the local site in the replication group,
2880         /// <see cref="RepMgrLocalSite"/>.
2881         /// </item>
2882         /// <item>
2883         /// Call <see cref="RepMgrSiteConfig"/> to configure the remote
2884         /// site(s) in the replication group.
2885         /// </item>
2886         /// <item>Configure the message acknowledgment policy
2887         /// (<see cref="RepMgrAckPolicy"/>) which provides the replication group's
2888         /// transactional needs.
2889         /// </item>
2890         /// <item>
2891         /// Configure the local site's election priority,
2892         /// <see cref="RepPriority"/>.
2893         /// </item>
2894         /// <item>
2895         /// Call <see cref="RepMgrStartClient"/> or
2896         /// <see cref="RepMgrStartMaster"/> to start the replication
2897         /// application.
2898         /// </item>
2899         /// </list>
2900         /// <para>
2901         /// For more information on building replication manager applications,
2902         /// please see the Replication Getting Started Guide included in the
2903         /// Berkeley DB documentation.
2904         /// </para>
2905         /// <para>
2906         /// Applications with special needs (for example, applications using
2907         /// network protocols not supported by the Berkeley DB replication
2908         /// manager), must perform additional configuration and call other
2909         /// Berkeley DB replication methods. For more information on building
2910         /// advanced replication applications, please see the Base Replication
2911         /// API section in the Berkeley DB Programmer's Reference Guide for more
2912         /// information.
2913         /// </para>
2914         /// <para>
2915         /// Starting the replication manager consists of opening the TCP/IP
2916         /// listening socket to accept incoming connections, and starting all
2917         /// necessary background threads. When multiple processes share a
2918         /// database environment, only one process can open the listening
2919         /// socket; <see cref="RepMgrStartMaster"/> (and
2920         /// <see cref="RepMgrStartClient"/>) automatically open the socket in
2921         /// the first process to call it, and skips this step in the later calls
2922         /// from other processes.
2923         /// </para>
2924         /// </remarks>
2925         /// <param name="nthreads">
2926         /// Specify the number of threads of control created and dedicated to
2927         /// processing replication messages. In addition to these message
2928         /// processing threads, the replication manager creates and manages a
2929         /// few of its own threads of control.
2930         /// </param>
2931         public void RepMgrStartMaster(int nthreads) {
2932             dbenv.repmgr_start(nthreads, DbConstants.DB_REP_MASTER);
2933         }
2934         
2935         /// <summary>
2936         /// Process an incoming replication message sent by a member of the
2937         /// replication group to the local database environment. 
2938         /// </summary>
2939         /// <remarks>
2940         /// <para>
2941         /// RepProcessMessage is not called by most replication applications. It
2942         /// should only be called by applications implementing their own network
2943         /// transport layer, explicitly holding replication group elections and
2944         /// handling replication messages outside of the replication manager
2945         /// framework.
2946         /// </para>
2947         /// <para>
2948         /// For implementation reasons, all incoming replication messages must
2949         /// be processed using the same <see cref="DatabaseEnvironment"/>
2950         /// object. It is not required that a single thread of control process
2951         /// all messages, only that all threads of control processing messages
2952         /// use the same object.
2953         /// </para>
2954         /// <para>
2955         /// Before calling this method, the <see cref="RepTransport"/> delegate 
2956         /// must already have been configured to send replication messages.
2957         /// </para>
2958         /// </remarks>
2959         /// <param name="control">
2960         /// A copy of the control parameter specified by Berkeley DB on the
2961         /// sending environment.
2962         /// </param>
2963         /// <param name="rec">
2964         /// A copy of the rec parameter specified by Berkeley DB on the sending
2965         /// environment.
2966         /// </param>
2967         /// <param name="envid">
2968         /// The local identifier that corresponds to the environment that sent
2969         /// the message to be processed (see Replication environment IDs in the
2970         /// Programmer's Reference Guide for more information)..
2971         /// </param>
2972         /// <returns>The result of processing a message</returns>
2973         public RepProcMsgResult RepProcessMessage(
2974             DatabaseEntry control, DatabaseEntry rec, int envid) {
2975             DB_LSN dblsn = new DB_LSN();
2976             int ret = dbenv.rep_process_message(control,
2977                 rec, envid, dblsn);
2978             LSN lsnp = new LSN(dblsn.file, dblsn.offset);
2979             RepProcMsgResult result = new RepProcMsgResult(ret, lsnp);
2980             if (result.Result == RepProcMsgResult.ProcMsgResult.ERROR)
2981                 DatabaseException.ThrowException(ret);
2982             return result;
2983         }
2984         
2985         /// <summary>
2986         /// Configure the database environment as a client in a group of
2987         /// replicated database environments.
2988         /// </summary>
2989         public void RepStartClient() {
2990             RepStartClient(null);
2991         }
2992         /// <summary>
2993         /// Configure the database environment as a client in a group of
2994         /// replicated database environments.
2995         /// </summary>
2996         /// <overloads>
2997         /// <para>
2998         /// RepStartClient is not called by most replication applications. It
2999         /// should only be called by applications implementing their own network
3000         /// transport layer, explicitly holding replication group elections and
3001         /// handling replication messages outside of the replication manager
3002         /// framework.
3003         /// </para>
3004         /// <para>
3005         /// Replication master environments are the only database environments
3006         /// where replicated databases may be modified. Replication client
3007         /// environments are read-only as long as they are clients. Replication
3008         /// client environments may be upgraded to be replication master
3009         /// environments in the case that the current master fails or there is
3010         /// no master present. If master leases are in use, this method cannot
3011         /// be used to appoint a master, and should only be used to configure a
3012         /// database environment as a master as the result of an election.
3013         /// </para>
3014         /// <para>
3015         /// Before calling this method, the <see cref="RepTransport"/> delegate 
3016         /// must already have been configured to send replication messages.
3017         /// </para>
3018         /// </overloads>
3019         /// <param name="cdata">
3020         /// An opaque data item that is sent over the communication
3021         /// infrastructure when the client comes online (see Connecting to a new
3022         /// site in the Programmer's Reference Guide for more information). If
3023         /// no such information is useful, cdata should be null.
3024         /// </param>
3025         public void RepStartClient(DatabaseEntry cdata) {
3026             dbenv.rep_start(
3027                 cdata, DbConstants.DB_REP_CLIENT);
3028         }
3029         /// <summary>
3030         /// Configure the database environment as a master in a group of
3031         /// replicated database environments.
3032         /// </summary>
3033         public void RepStartMaster() {
3034             RepStartMaster(null);
3035         }
3036         /// <summary>
3037         /// Configure the database environment as a master in a group of
3038         /// replicated database environments.
3039         /// </summary>
3040         /// <overloads>
3041         /// <para>
3042         /// RepStartMaster is not called by most replication applications. It
3043         /// should only be called by applications implementing their own network
3044         /// transport layer, explicitly holding replication group elections and
3045         /// handling replication messages outside of the replication manager
3046         /// framework.
3047         /// </para>
3048         /// <para>
3049         /// Replication master environments are the only database environments
3050         /// where replicated databases may be modified. Replication client
3051         /// environments are read-only as long as they are clients. Replication
3052         /// client environments may be upgraded to be replication master
3053         /// environments in the case that the current master fails or there is
3054         /// no master present. If master leases are in use, this method cannot
3055         /// be used to appoint a master, and should only be used to configure a
3056         /// database environment as a master as the result of an election.
3057         /// </para>
3058         /// <para>
3059         /// Before calling this method, the <see cref="RepTransport"/> delegate 
3060         /// must already have been configured to send replication messages.
3061         /// </para>
3062         /// </overloads>
3063         /// <param name="cdata">
3064         /// An opaque data item that is sent over the communication
3065         /// infrastructure when the client comes online (see Connecting to a new
3066         /// site in the Programmer's Reference Guide for more information). If
3067         /// no such information is useful, cdata should be null.
3068         /// </param>
3069         public void RepStartMaster(DatabaseEntry cdata) {
3070             dbenv.rep_start(
3071                 cdata, DbConstants.DB_REP_MASTER);
3072         }
3073
3074         /// <summary>
3075         /// Force master synchronization to begin for this client.
3076         /// </summary>
3077         /// <remarks>
3078         /// <para>
3079         /// This method is the other half of setting
3080         /// <see cref="RepDelayClientSync"/>.
3081         /// </para>
3082         /// <para>
3083         /// If an application has configured delayed master synchronization, the
3084         /// application must synchronize explicitly (otherwise the client will
3085         /// remain out-of-date and will ignore all database changes forwarded
3086         /// from the replication group master). RepSync may be called any time
3087         /// after the client application learns that the new master has been
3088         /// established (by receiving
3089         /// <see cref="NotificationEvent.REP_NEWMASTER"/>).
3090         /// </para>
3091         /// <para>
3092         /// Before calling this method, the <see cref="RepTransport"/> delegate 
3093         /// must already have been configured to send replication messages.
3094         /// </para>
3095         /// </remarks>
3096         public void RepSync() {
3097             dbenv.rep_sync(0);
3098         }
3099
3100         /// <summary>
3101         /// The names of all of the log files that are no longer in use (for
3102         /// example, that are no longer involved in active transactions), and
3103         /// that may safely be archived for catastrophic recovery and then
3104         /// removed from the system.
3105         /// </summary>
3106         /// <remarks>
3107         /// <para>
3108         /// The Berkeley DB interfaces to the database environment logging
3109         /// subsystem (for example, <see cref="Transaction.Abort"/>) may
3110         /// allocate log cursors and have open file descriptors for log files
3111         /// as well. On operating systems where filesystem related system calls
3112         /// (for example, rename and unlink on Windows/NT) can fail if a process
3113         /// has an open file descriptor for the affected file, attempting to
3114         /// move or remove the log files listed by ArchivableLogFiles may fail.
3115         /// All Berkeley DB internal use of log cursors operates on active log
3116         /// files only and furthermore, is short-lived in nature. So, an
3117         /// application seeing such a failure should be restructured to retry
3118         /// the operation until it succeeds. (Although this is not likely to be
3119         /// necessary; it is hard to imagine a reason to move or rename a log
3120         /// file in which transactions are being logged or aborted.)
3121         /// </para>
3122         /// <para>
3123         /// When Replication Manager is in use, log archiving will be performed
3124         /// in a replication group-aware manner such that the log file status of
3125         /// other sites in the group will be considered to determine if a log
3126         /// file could be in use. 
3127         /// </para>
3128         /// <para>
3129         /// See the db_archive utility for more information on database archival
3130         /// procedures.
3131         /// </para>
3132         /// </remarks>
3133         /// <param name="AbsolutePaths">
3134         /// If true, all pathnames are returned as absolute pathnames, instead 
3135         /// of relative to the database home directory.
3136         /// </param>
3137         /// <returns>
3138         /// The names of all of the log files that are no longer in use
3139         /// </returns>
3140         public List<string> ArchivableLogFiles(bool AbsolutePaths) {
3141             uint flags = 0;
3142             flags |= AbsolutePaths ? DbConstants.DB_ARCH_ABS : 0;
3143             return dbenv.log_archive(flags);
3144         }
3145         /// <summary>
3146         /// The database files that need to be archived in order to recover the
3147         /// database from catastrophic failure. If any of the database files
3148         /// have not been accessed during the lifetime of the current log files,
3149         /// they will not included in this list. It is also possible that some
3150         /// of the files referred to by the log have since been deleted from the
3151         /// system. 
3152         /// </summary>
3153         /// <remarks>
3154         /// <para>
3155         /// When Replication Manager is in use, log archiving will be performed
3156         /// in a replication group-aware manner such that the log file status of
3157         /// other sites in the group will be considered to determine if a log
3158         /// file could be in use. 
3159         /// </para>
3160         /// <para>
3161         /// See the db_archive utility for more information on database archival
3162         /// procedures.
3163         /// </para>
3164         /// </remarks>
3165         /// <param name="AbsolutePaths">
3166         /// If true, all pathnames are returned as absolute pathnames, instead 
3167         /// of relative to the database home directory.
3168         /// </param>
3169         /// <returns>
3170         /// The database files that need to be archived in order to recover the
3171         /// database from catastrophic failure.
3172         /// </returns>
3173         public List<string> ArchivableDatabaseFiles(bool AbsolutePaths) {
3174             uint flags = DbConstants.DB_ARCH_DATA;
3175             flags |= AbsolutePaths ? DbConstants.DB_ARCH_ABS : 0;
3176             return dbenv.log_archive(flags);
3177         }
3178         /// <summary>
3179         /// The names of all of the log files
3180         /// </summary>
3181         /// <remarks>
3182         /// <para>
3183         /// The Berkeley DB interfaces to the database environment logging
3184         /// subsystem (for example, <see cref="Transaction.Abort"/>) may
3185         /// allocate log cursors and have open file descriptors for log files
3186         /// as well. On operating systems where filesystem related system calls
3187         /// (for example, rename and unlink on Windows/NT) can fail if a process
3188         /// has an open file descriptor for the affected file, attempting to
3189         /// move or remove the log files listed by LogFiles may fail. All
3190         /// Berkeley DB internal use of log cursors operates on active log files
3191         /// only and furthermore, is short-lived in nature. So, an application
3192         /// seeing such a failure should be restructured to retry the operation
3193         /// until it succeeds. (Although this is not likely to be necessary; it
3194         /// is hard to imagine a reason to move or rename a log file in which
3195         /// transactions are being logged or aborted.)
3196         /// </para>
3197         /// <para>
3198         /// See the db_archive utility for more information on database archival
3199         /// procedures.
3200         /// </para>
3201         /// </remarks>
3202         /// <param name="AbsolutePaths">
3203         /// If true, all pathnames are returned as absolute pathnames, instead 
3204         /// of relative to the database home directory.
3205         /// </param>
3206         /// <returns>
3207         /// All the log filenames, regardless of whether or not they are in use.
3208         /// </returns>
3209         public List<string> LogFiles(bool AbsolutePaths) {
3210             uint flags = DbConstants.DB_ARCH_LOG;
3211             flags |= AbsolutePaths ? DbConstants.DB_ARCH_ABS : 0;
3212             return dbenv.log_archive(flags);
3213         }
3214         /// <summary>
3215         /// Remove log files that are no longer needed. Automatic log file
3216         /// removal is likely to make catastrophic recovery impossible. 
3217         /// </summary>
3218         /// <remarks>
3219         /// <para>
3220         /// When Replication Manager is in use, log archiving will be performed
3221         /// in a replication group-aware manner such that the log file status of
3222         /// other sites in the group will be considered to determine if a log
3223         /// file could be in use. 
3224         /// </para>
3225         /// </remarks>
3226         public void RemoveUnusedLogFiles() {
3227             dbenv.log_archive(DbConstants.DB_ARCH_REMOVE);
3228         }
3229
3230         /// <summary>
3231         /// Allocate a locker ID in an environment configured for Berkeley DB
3232         /// Concurrent Data Store applications.
3233         /// </summary>
3234         /// <remarks>
3235         /// <para>
3236         /// Calling <see cref="Transaction.Commit"/> will discard the allocated
3237         /// locker ID.
3238         /// </para>
3239         /// <para>
3240         /// See Berkeley DB Concurrent Data Store applications in the
3241         /// Programmer's Reference Guide for more information about when this is
3242         /// required.
3243         /// </para>
3244         /// </remarks>
3245         /// <returns>
3246         /// A Transaction object that uniquely identifies the locker ID
3247         /// </returns>
3248         public Transaction BeginCDSGroup() {
3249             return new Transaction(dbenv.cdsgroup_begin());
3250         }
3251
3252         /// <summary>
3253         /// Create a new transaction in the environment, with the default 
3254         /// configuration.
3255         /// </summary>
3256         /// <returns>A new transaction object</returns>
3257         public Transaction BeginTransaction() {
3258             return BeginTransaction(new TransactionConfig(), null);
3259         }
3260         /// <summary>
3261         /// Create a new transaction in the environment.
3262         /// </summary>
3263         /// <param name="cfg">
3264         /// The configuration properties for the transaction
3265         /// </param>
3266         /// <returns>A new transaction object</returns>
3267         public Transaction BeginTransaction(TransactionConfig cfg) {
3268             return BeginTransaction(cfg, null);
3269         }
3270         /// <summary>
3271         /// Create a new transaction in the environment.
3272         /// </summary>
3273         /// <remarks>
3274         /// In the presence of distributed transactions and two-phase commit,
3275         /// only the parental transaction, that is a transaction without a
3276         /// parent specified, should be passed as an parameter to 
3277         /// <see cref="Transaction.Prepare"/>.
3278         /// </remarks>
3279         /// <param name="cfg">
3280         /// The configuration properties for the transaction
3281         /// </param>
3282         /// <param name="parent">
3283         /// If the non-null, the new transaction will be a nested transaction,
3284         /// with <paramref name="parent"/> as the new transaction's parent.
3285         /// Transactions may be nested to any level.
3286         /// </param>
3287         /// <returns>A new transaction object</returns>
3288         public Transaction BeginTransaction(
3289             TransactionConfig cfg, Transaction parent) {
3290             DB_TXN dbtxn = dbenv.txn_begin(
3291                 Transaction.getDB_TXN(parent), cfg.flags);
3292             Transaction txn = new Transaction(dbtxn);
3293             if (cfg.lockTimeoutIsSet)
3294                 txn.SetLockTimeout(cfg.LockTimeout);
3295             if (cfg.nameIsSet)
3296                 txn.Name = cfg.Name;
3297             if (cfg.txnTimeoutIsSet)
3298                 txn.SetTxnTimeout(cfg.TxnTimeout);
3299
3300             return txn;
3301         }
3302
3303         /// <summary>
3304         /// Flush the underlying memory pool, write a checkpoint record to the
3305         /// log, and then flush the log, even if there has been no activity
3306         /// since the last checkpoint.
3307         /// </summary>
3308         public void Checkpoint() {
3309             dbenv.txn_checkpoint(0, 0, DbConstants.DB_FORCE);
3310         }
3311         /// <summary>
3312         /// If there has been any logging activity in the database environment
3313         /// since the last checkpoint, flush the underlying memory pool, write a
3314         /// checkpoint record to the log, and then flush the log.
3315         /// </summary>
3316         /// <param name="kbytesWritten">
3317         /// A checkpoint will be done if more than kbytesWritten kilobytes of
3318         /// log data have been written since the last checkpoint.
3319         /// </param>
3320         /// <param name="minutesElapsed">
3321         /// A checkpoint will be done if more than minutesElapsed minutes have
3322         /// passed since the last checkpoint.
3323         /// </param>
3324         public void Checkpoint(uint kbytesWritten, uint minutesElapsed) {
3325             dbenv.txn_checkpoint(kbytesWritten, minutesElapsed, 0);
3326         }
3327
3328         /// <summary>
3329         /// By closing the Berkeley DB environment you can free allocated resources 
3330         /// and close any open databases along with the underlying subsystems.
3331         /// </summary>
3332         /// <remarks>
3333         /// <para>
3334         /// The object should not be closed while any other handle that refers
3335         /// to it is not yet closed; for example, database environment handles
3336         /// must not be closed while transactions in the environment have 
3337         /// not yet been committed or aborted. 
3338         /// When you close each database handle, by default, the database is not synchronized.
3339                 ///     To synchronize all open databases ensure that the last environment object is closed by the CloseForceSync() method. 
3340                 ///     When the close operation fails, the method returns a non-zero error value for the first instance of such error, 
3341         /// and continues to close the rest of the environment objects.
3342         /// </para>
3343         /// <para>
3344         /// Where the environment was configured with
3345         /// <see cref="DatabaseEnvironmentConfig.UseTxns"/>, calling CloseForceSync
3346         /// aborts any unresolved transactions. Applications should not depend
3347         /// on this behavior for transactions involving Berkeley DB databases;
3348         /// all such transactions should be explicitly resolved. The problem
3349         /// with depending on this semantic is that aborting an unresolved
3350         /// transaction involving database operations requires a database
3351         /// handle. Because the database handles should have been closed before
3352         /// calling CloseForceSync, it will not be possible to abort the 
3353         /// transaction, and recovery will have to be run on the Berkeley DB 
3354         /// environment before further operations are done.
3355         /// </para>
3356         /// <para>
3357         /// In multithreaded applications, only a single thread may call 
3358         /// CloseForceSync.
3359         /// </para>
3360         /// </remarks>
3361         public void Close() {
3362             dbenv.close(0);
3363         }
3364
3365         /// <summary>
3366         /// Close the Berkeley DB environment, freeing any allocated resources,
3367         /// closing any open databases as well as underlying subsystems. 
3368         /// </summary>
3369         /// <remarks>
3370         /// <para>
3371         /// The object should not be closed while any other handle that refers
3372         /// to it is not yet closed; for example, database environment handles
3373         /// must not be closed while transactions in the environment have 
3374         /// not yet been committed or aborted. If there are open database 
3375         /// handles, they are all closed, and each of them will be synced on
3376         /// close. The first error in the close operations, if any, is 
3377         /// returned at last, and the environment close procedures will 
3378         /// carry on anyway.
3379         /// </para>
3380         /// <para>
3381         /// Where the environment was configured with
3382         /// <see cref="DatabaseEnvironmentConfig.UseTxns"/>, calling CloseForceSync
3383         /// aborts any unresolved transactions. Applications should not depend
3384         /// on this behavior for transactions involving Berkeley DB databases;
3385         /// all such transactions should be explicitly resolved. The problem
3386         /// with depending on this semantic is that aborting an unresolved
3387         /// transaction involving database operations requires a database
3388         /// handle. Because the database handles should have been closed before
3389         /// calling CloseForceSync, it will not be possible to abort the 
3390         /// transaction, and recovery will have to be run on the Berkeley DB 
3391         /// environment before further operations are done.
3392         /// </para>
3393         /// <para>
3394         /// In multithreaded applications, only a single thread may call 
3395         /// CloseForceSync.
3396         /// </para>
3397         /// </remarks>
3398         public void CloseForceSync() {
3399                 dbenv.close(DbConstants.DB_FORCESYNC);
3400         }
3401
3402         /// <summary>
3403         /// Run one iteration of the deadlock detector. The deadlock detector
3404         /// traverses the lock table and marks one of the participating lock
3405         /// requesters for rejection in each deadlock it finds.
3406         /// </summary>
3407         /// <param name="atype">Specify which lock request(s) to reject</param>
3408         /// <returns>The number of lock requests that were rejected.</returns>
3409         public uint DetectDeadlocks(DeadlockPolicy atype) {
3410             uint rejectCount = 0;
3411             if (atype == null)
3412                 atype = DeadlockPolicy.DEFAULT;
3413             dbenv.lock_detect(0, atype.policy, ref rejectCount);
3414             return rejectCount;
3415         }
3416
3417         /// <summary>
3418         /// Check for threads of control (either a true thread or a process)
3419         /// that have exited while manipulating Berkeley DB library data
3420         /// structures, while holding a logical database lock, or with an
3421         /// unresolved transaction (that is, a transaction that was never
3422         /// aborted or committed).
3423         /// </summary>
3424         /// <remarks>
3425         /// <para>
3426         /// For more information, see Architecting Data Store and Concurrent
3427         /// Data Store applications, and Architecting Transactional Data Store
3428         /// applications, both in the Berkeley DB Programmer's Reference Guide.
3429         /// </para>
3430         /// <para>
3431         /// FailCheck is based on the <see cref="SetThreadID"/> and
3432         /// <see cref="ThreadIsAlive"/> delegates. Applications calling
3433         /// FailCheck must have already set <see cref="ThreadIsAlive"/>, and
3434         /// must have configured <see cref="ThreadCount"/>.
3435         /// </para>
3436         /// <para>
3437         /// If FailCheck determines a thread of control exited while holding
3438         /// database read locks, it will release those locks. If FailCheck
3439         /// determines a thread of control exited with an unresolved
3440         /// transaction, the transaction will be aborted. In either of these
3441         /// cases, FailCheck will return successfully and the application may
3442         /// continue to use the database environment.
3443         /// </para>
3444         /// <para>
3445         /// In either of these cases, FailCheck will also report the process and
3446         /// thread IDs associated with any released locks or aborted
3447         /// transactions. The information is printed to a specified output
3448         /// channel (see <see cref="Verbosity"/> for more information), or
3449         /// passed to an application delegate (see <see cref="Feedback"/> for
3450         /// more information).
3451         /// </para>
3452         /// <para>
3453         /// If FailCheck determines a thread of control has exited such that
3454         /// database environment recovery is required, it will throw
3455         /// <see cref="RunRecoveryException"/>. In this case, the application
3456         /// should not continue to use the database environment. For a further
3457         /// description as to the actions the application should take when this
3458         /// failure occurs, see Handling failure in Data Store and Concurrent
3459         /// Data Store applications, and Handling failure in Transactional Data
3460         /// Store applications, both in the Berkeley DB Programmer's Reference
3461         /// Guide.
3462         /// </para>
3463         /// </remarks>
3464         public void FailCheck() {
3465             dbenv.failchk(0);
3466         }
3467
3468         /// <summary>
3469         /// This method checks to see if a specified transaction has been replicated from 
3470         /// the master of a replication group. It may be called by applications using either
3471         /// the Base API or the Replication Manager.
3472         /// </summary>
3473         /// <param name="token">
3474         /// The commit token from a transaction previously written at a master
3475         /// site in the replication group.  Commit tokens are retrieved using
3476         /// the <see cref="Transaction.CommitToken"/> method.
3477         /// </param>
3478         /// <param name="timeout">
3479         /// The maximum time to wait for the transaction to arrive by replication, expressed in 
3480         /// microseconds.  To check the status of the transaction without waiting, the timeout 
3481         /// may be specified as 0.
3482         /// </param>
3483         /// <returns>
3484         /// This method returns TransactionAppliedStatus.APPLIED to indicate that the specified 
3485         /// transaction has indeed been applied at the local site. TransactionAppliedStatus.TIMEOUT
3486         /// will be returned if the specified transaction has not yet arrived at the calling site, 
3487         /// but can be expected to arrive soon. TransactionAppliedStatus.NOTFOUND will be returned 
3488         /// if the transaction has not been applied at the local site, and it can be determined that
3489         /// the transaction has been rolled back due to a master takeover, and is therefore never 
3490         /// expected to arrive. TransactionAppliedStatus.EMPTY_TRANSACTION will be return if the specified
3491         /// token was generated by a transaction that did not modify the database environment 
3492         /// (e.g., a read-only transaction).
3493         /// </returns>
3494         public TransactionAppliedStatus IsTransactionApplied(byte[] token, uint timeout)
3495         {
3496             if (token == null)
3497                 throw new ArgumentNullException("The token cannot be null.");
3498             if (token.Length != DbConstants.DB_TXN_TOKEN_SIZE)
3499             {
3500                 throw new ArgumentOutOfRangeException("The token size must be "
3501                     + DbConstants.DB_TXN_TOKEN_SIZE);
3502             }
3503             DB_TXN_TOKEN txn_token = new DB_TXN_TOKEN(token);
3504             int ret = dbenv.is_transaction_applied(txn_token, timeout, 0);
3505             switch (ret)
3506             {
3507                 case 0:
3508                     return TransactionAppliedStatus.APPLIED;
3509                 case DbConstants.DB_TIMEOUT:
3510                     return TransactionAppliedStatus.TIMEOUT;                
3511                 case DbConstants.DB_NOTFOUND:
3512                     return TransactionAppliedStatus.NOTFOUND;
3513                 case DbConstants.DB_KEYEMPTY:
3514                     return TransactionAppliedStatus.EMPTY_TRANSACTION;
3515                 default:
3516                     throw new DatabaseException(ret);
3517             }
3518         }
3519
3520         /// <summary>
3521         /// Map an LSN object to a log filename
3522         /// </summary>
3523         /// <param name="logSeqNum">
3524         /// The DB_LSN structure for which a filename is wanted.
3525         /// </param>
3526         /// <returns>
3527         /// The name of the file containing the record named by
3528         /// <paramref name="logSeqNum"/>.
3529         /// </returns>
3530         public string LogFile(LSN logSeqNum) {
3531             return dbenv.log_file(LSN.getDB_LSN(logSeqNum));
3532         }
3533
3534         /// <summary>
3535         /// Write all log records to disk.
3536         /// </summary>
3537         public void LogFlush() {
3538             LogFlush(null);
3539         }
3540         /// <summary>
3541         /// Write log records to disk.
3542         /// </summary>
3543         /// <param name="logSeqNum">
3544         /// All log records with LSN values less than or equal to
3545         /// <paramref name="logSeqNum"/> are written to disk. If null, all
3546         /// records in the log are flushed.
3547         /// </param>
3548         public void LogFlush(LSN logSeqNum) {
3549             dbenv.log_flush(LSN.getDB_LSN(logSeqNum));
3550         }
3551
3552         /// <summary>
3553         /// Verify log records of this environment.
3554         /// </summary>
3555         /// <param name="config">
3556         /// Log verification configuration object.
3557         /// </param>
3558         public int LogVerify(LogVerifyConfig config) {
3559             String dbfile, dbname, home;
3560             int etime, stime;
3561             uint cachesize;
3562             uint efile, eoffset, sfile, soffset;
3563             int caf, ret, verbose;
3564
3565             caf = ret = verbose = 0;
3566             etime = stime = 0;
3567             home = config.EnvHome;
3568             dbfile = config.DbFile;
3569             dbname = config.DbName;
3570             try {
3571                 etime = (int)config.EndTime.ToFileTimeUtc();
3572                 stime = (int)config.StartTime.ToFileTimeUtc();
3573             } catch (Exception){}
3574
3575             efile = config.EndLsn.LogFileNumber;
3576             eoffset = config.EndLsn.Offset;
3577             sfile = config.StartLsn.LogFileNumber;
3578             soffset = config.StartLsn.Offset;
3579             cachesize = config.CacheSize;
3580             if (config.Verbose)
3581                 verbose = 1;
3582             if (config.ContinueAfterFail)
3583                 caf = 1;
3584             try {
3585                 ret = dbenv.log_verify(home, cachesize, dbfile, dbname, 
3586                     stime, etime, sfile, soffset, efile, eoffset, caf, verbose);
3587             } catch (Exception){}
3588
3589             return (ret);
3590         }
3591
3592         /// <summary>
3593         /// Append a record to the log
3594         /// </summary>
3595         /// <param name="dbt">The record to write to the log.</param>
3596         /// <param name="flush">
3597         /// If true, the log is forced to disk after this record is written,
3598         /// guaranteeing that all records with LSN values less than or equal to
3599         /// the one being "put" are on disk before LogWrite returns.
3600         /// </param>
3601         /// <returns>The LSN of the written record</returns>
3602         public LSN LogWrite(DatabaseEntry dbt, bool flush) {
3603             DB_LSN lsn = new DB_LSN();
3604
3605             dbenv.log_put(lsn,
3606                 dbt, flush ? DbConstants.DB_FLUSH : 0);
3607             return new LSN(lsn.file, lsn.offset);
3608         }
3609
3610         /// <summary>
3611         /// Set the panic state for the database environment. (Database
3612         /// environments in a panic state normally refuse all attempts to call
3613         /// Berkeley DB functions, throwing <see cref="RunRecoveryException"/>.)
3614         /// </summary>
3615         public void Panic() {
3616             dbenv.set_flags(DbConstants.DB_PANIC_ENVIRONMENT, 1);
3617         }
3618
3619         /// <summary>
3620         /// Restore transactions that were prepared, but not yet resolved at the
3621         /// time of the system shut down or crash, to their state prior to the
3622         /// shut down or crash, including any locks previously held.
3623         /// </summary>
3624         /// <remarks>
3625         /// Calls to Recover from different threads of control should not be
3626         /// intermixed in the same environment.
3627         /// </remarks>
3628         /// <param name="count">
3629         /// The maximum number of <see cref="PreparedTransaction"/> objects
3630         /// to return.
3631         /// </param>
3632         /// <param name="resume">
3633         /// If true, continue returning a list of prepared, but not yet resolved
3634         /// transactions, starting where the last call to Recover left off.  If 
3635         /// false, begins a new pass over all prepared, but not yet completed
3636         /// transactions, regardless of whether they have already been returned
3637         /// in previous calls to Recover.
3638         /// </param>
3639         /// <returns>A list of the prepared transactions</returns>
3640         public PreparedTransaction[] Recover(int count, bool resume) {
3641             uint flags = 0;
3642             flags |= resume ? DbConstants.DB_NEXT : DbConstants.DB_FIRST;
3643             
3644             return dbenv.txn_recover(count, flags);
3645         }
3646
3647         /// <summary>
3648         /// Remove the underlying file represented by <paramref name="file"/>,
3649         /// incidentally removing all of the databases it contained.
3650         /// </summary>
3651         /// <param name="file">The physical file to be removed.</param>
3652         /// <param name="autoCommit">
3653         /// If true, enclose RemoveDB within a transaction. If the call
3654         /// succeeds, changes made by the operation will be recoverable. If the
3655         /// call fails, the operation will have made no changes.
3656         /// </param>
3657         public void RemoveDB(string file, bool autoCommit) {
3658             RemoveDB(file, null, autoCommit, null);
3659         }
3660         /// <summary>
3661         /// Remove the database specified by <paramref name="file"/> and
3662         /// <paramref name="database"/>.  If no database is specified, the
3663         /// underlying file represented by <paramref name="file"/> is removed,
3664         /// incidentally removing all of the databases it contained.
3665         /// </summary>
3666         /// <param name="file">
3667         /// The physical file which contains the database(s) to be removed.
3668         /// </param>
3669         /// <param name="database">The database to be removed.</param>
3670         /// <param name="autoCommit">
3671         /// If true, enclose RemoveDB within a transaction. If the call
3672         /// succeeds, changes made by the operation will be recoverable. If the
3673         /// call fails, the operation will have made no changes.
3674         /// </param>
3675         public void RemoveDB(string file, string database, bool autoCommit) {
3676             RemoveDB(file, database, autoCommit, null);
3677         }
3678         /// <summary>
3679         /// Remove the underlying file represented by <paramref name="file"/>,
3680         /// incidentally removing all of the databases it contained.
3681         /// </summary>
3682         /// <param name="file">The physical file to be removed.</param>
3683         /// <param name="autoCommit">
3684         /// If true, enclose RemoveDB within a transaction. If the call
3685         /// succeeds, changes made by the operation will be recoverable. If the
3686         /// call fails, the operation will have made no changes.
3687         /// </param>
3688         /// <param name="txn">
3689         /// If the operation is part of an application-specified transaction,
3690         /// <paramref name="txn"/> is a Transaction object returned from
3691         /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if
3692         /// the operation is part of a Berkeley DB Concurrent Data Store group,
3693         /// <paramref name="txn"/> is a handle returned from
3694         /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null.  If
3695         /// null, but <paramref name="autoCommit"/> or <see cref="AutoCommit"/>
3696         /// is true, the operation will be implicitly transaction protected. 
3697         /// </param>
3698         public void RemoveDB(string file, bool autoCommit, Transaction txn) {
3699             RemoveDB(file, null, autoCommit, txn);
3700         }
3701         /// <summary>
3702         /// Remove the database specified by <paramref name="file"/> and
3703         /// <paramref name="database"/>.  If no database is specified, the
3704         /// underlying file represented by <paramref name="file"/> is removed,
3705         /// incidentally removing all of the databases it contained.
3706         /// </summary>
3707         /// <param name="file">
3708         /// The physical file which contains the database(s) to be removed.
3709         /// </param>
3710         /// <param name="database">The database to be removed.</param>
3711         /// <param name="autoCommit">
3712         /// If true, enclose RemoveDB within a transaction. If the call
3713         /// succeeds, changes made by the operation will be recoverable. If the
3714         /// call fails, the operation will have made no changes.
3715         /// </param>
3716         /// <param name="txn">
3717         /// If the operation is part of an application-specified transaction,
3718         /// <paramref name="txn"/> is a Transaction object returned from
3719         /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if
3720         /// the operation is part of a Berkeley DB Concurrent Data Store group,
3721         /// <paramref name="txn"/> is a handle returned from
3722         /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null.  If
3723         /// null, but <paramref name="autoCommit"/> or <see cref="AutoCommit"/>
3724         /// is true, the operation will be implicitly transaction protected. 
3725         /// </param>
3726         public void RemoveDB(
3727             string file, string database, bool autoCommit, Transaction txn) {
3728             dbenv.dbremove(Transaction.getDB_TXN(txn),
3729                 file, database, autoCommit ? DbConstants.DB_AUTO_COMMIT : 0);
3730         }
3731
3732         /// <summary>
3733         /// Rename the underlying file represented by <paramref name="file"/>
3734         /// using the value supplied to <paramref name="newname"/>, incidentally
3735         /// renaming all of the databases it contained.
3736         /// </summary>
3737         /// <param name="file">The physical file to be renamed.</param>
3738         /// <param name="newname">The new name of the database or file.</param>
3739         /// <param name="autoCommit">
3740         /// If true, enclose RenameDB within a transaction. If the call
3741         /// succeeds, changes made by the operation will be recoverable. If the
3742         /// call fails, the operation will have made no changes.
3743         /// </param>
3744         public void RenameDB(string file, string newname, bool autoCommit) {
3745             RenameDB(file, null, newname, autoCommit, null);
3746         }
3747         /// <summary>
3748         /// Rename the database specified by <paramref name="file"/> and
3749         /// <paramref name="database"/> to <paramref name="newname"/>. If no
3750         /// database is specified, the underlying file represented by
3751         /// <paramref name="file"/> is renamed using the value supplied to
3752         /// <paramref name="newname"/>, incidentally renaming all of the
3753         /// databases it contained.
3754         /// </summary>
3755         /// <param name="file">
3756         /// The physical file which contains the database(s) to be renamed.
3757         /// </param>
3758         /// <param name="database">The database to be renamed.</param>
3759         /// <param name="newname">The new name of the database or file.</param>
3760         /// <param name="autoCommit">
3761         /// If true, enclose RenameDB within a transaction. If the call
3762         /// succeeds, changes made by the operation will be recoverable. If the
3763         /// call fails, the operation will have made no changes.
3764         /// </param>
3765         public void RenameDB(
3766             string file, string database, string newname, bool autoCommit) {
3767             RenameDB(file, database, newname, autoCommit, null);
3768         }
3769         /// <summary>
3770         /// Rename the underlying file represented by <paramref name="file"/>
3771         /// using the value supplied to <paramref name="newname"/>, incidentally
3772         /// renaming all of the databases it contained.
3773         /// </summary>
3774         /// <param name="file">The physical file to be renamed.</param>
3775         /// <param name="newname">The new name of the database or file.</param>
3776         /// <param name="autoCommit">
3777         /// If true, enclose RenameDB within a transaction. If the call
3778         /// succeeds, changes made by the operation will be recoverable. If the
3779         /// call fails, the operation will have made no changes.
3780         /// </param>
3781         /// <param name="txn">
3782         /// If the operation is part of an application-specified transaction,
3783         /// <paramref name="txn"/> is a Transaction object returned from
3784         /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if
3785         /// the operation is part of a Berkeley DB Concurrent Data Store group,
3786         /// <paramref name="txn"/> is a handle returned from
3787         /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null.  If
3788         /// null, but <paramref name="autoCommit"/> or <see cref="AutoCommit"/>
3789         /// is true, the operation will be implicitly transaction protected. 
3790         /// </param>
3791         public void RenameDB(string file,
3792             string newname, bool autoCommit, Transaction txn) {
3793             RenameDB(file, null, newname, autoCommit, txn);
3794         }
3795         /// <summary>
3796         /// Rename the database specified by <paramref name="file"/> and
3797         /// <paramref name="database"/> to <paramref name="newname"/>. If no
3798         /// database is specified, the underlying file represented by
3799         /// <paramref name="file"/> is renamed using the value supplied to
3800         /// <paramref name="newname"/>, incidentally renaming all of the
3801         /// databases it contained.
3802         /// </summary>
3803         /// <param name="file">
3804         /// The physical file which contains the database(s) to be renamed.
3805         /// </param>
3806         /// <param name="database">The database to be renamed.</param>
3807         /// <param name="newname">The new name of the database or file.</param>
3808         /// <param name="autoCommit">
3809         /// If true, enclose RenameDB within a transaction. If the call
3810         /// succeeds, changes made by the operation will be recoverable. If the
3811         /// call fails, the operation will have made no changes.
3812         /// </param>
3813         /// <param name="txn">
3814         /// If the operation is part of an application-specified transaction,
3815         /// <paramref name="txn"/> is a Transaction object returned from
3816         /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if
3817         /// the operation is part of a Berkeley DB Concurrent Data Store group,
3818         /// <paramref name="txn"/> is a handle returned from
3819         /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null.  If
3820         /// null, but <paramref name="autoCommit"/> or <see cref="AutoCommit"/>
3821         /// is true, the operation will be implicitly transaction protected. 
3822         /// </param>
3823         public void RenameDB(string file,
3824             string database, string newname, bool autoCommit, Transaction txn) {
3825             dbenv.dbrename(Transaction.getDB_TXN(txn), file,
3826                 database, newname, autoCommit ? DbConstants.DB_AUTO_COMMIT : 0);
3827         }
3828
3829         /// <summary>
3830         /// Allow database files to be copied, and then the copy used in the
3831         /// same database environment as the original.
3832         /// </summary>
3833         /// <remarks>
3834         /// <para>
3835         /// All databases contain an ID string used to identify the database in
3836         /// the database environment cache. If a physical database file is
3837         /// copied, and used in the same environment as another file with the
3838         /// same ID strings, corruption can occur. ResetFileID creates new ID
3839         /// strings for all of the databases in the physical file.
3840         /// </para>
3841         /// <para>
3842         /// ResetFileID modifies the physical file, in-place. Applications
3843         /// should not reset IDs in files that are currently in use.
3844         /// </para>
3845         /// </remarks>
3846         /// <param name="file">
3847         /// The name of the physical file in which new file IDs are to be created.
3848         /// </param>
3849         /// <param name="encrypted">
3850         /// If true, he file contains encrypted databases.
3851         /// </param>
3852         public void ResetFileID(string file, bool encrypted) {
3853             dbenv.fileid_reset(file, encrypted ? DbConstants.DB_ENCRYPT : 0);
3854         }
3855
3856         /// <summary>
3857         /// Allow database files to be moved from one transactional database
3858         /// environment to another. 
3859         /// </summary>
3860         /// <remarks>
3861         /// <para>
3862         /// Database pages in transactional database environments contain
3863         /// references to the environment's log files (that is, log sequence
3864         /// numbers, or <see cref="LSN"/>s). Copying or moving a database file
3865         /// from one database environment to another, and then modifying it, can
3866         /// result in data corruption if the LSNs are not first cleared.
3867         /// </para>
3868         /// <para>
3869         /// Note that LSNs should be reset before moving or copying the database
3870         /// file into a new database environment, rather than moving or copying
3871         /// the database file and then resetting the LSNs. Berkeley DB has
3872         /// consistency checks that may be triggered if an application calls 
3873         /// ResetLSN on a database in a new environment when the database LSNs
3874         /// still reflect the old environment.
3875         /// </para>
3876         /// <para>
3877         /// The ResetLSN method modifies the physical file, in-place.
3878         /// Applications should not reset LSNs in files that are currently in
3879         /// use.
3880         /// </para>
3881         /// </remarks>
3882         /// <param name="file"></param>
3883         /// <param name="encrypted"></param>
3884         public void ResetLSN(string file, bool encrypted) {
3885             dbenv.lsn_reset(file, encrypted ? DbConstants.DB_ENCRYPT : 0);
3886         }
3887
3888         /// <summary>
3889         /// Limit the number of sequential write operations scheduled by the
3890         /// library when flushing dirty pages from the cache.
3891         /// </summary>
3892         /// <param name="maxWrites">
3893         /// The maximum number of sequential write operations scheduled by the
3894         /// library when flushing dirty pages from the cache, or 0 if there is
3895         /// no limitation on the number of sequential write operations.
3896         /// </param>
3897         /// <param name="pause">
3898         /// The number of microseconds the thread of control should pause before
3899         /// scheduling further write operations. It must be specified as an
3900         /// unsigned 32-bit number of microseconds, limiting the maximum pause
3901         /// to roughly 71 minutes.
3902         /// </param>
3903         public void SetMaxSequentialWrites(int maxWrites, uint pause) {
3904             dbenv.set_mp_max_write(maxWrites, pause);
3905         }
3906
3907         /// <summary>
3908         /// Flush all modified pages in the cache to their backing files. 
3909         /// </summary>
3910         /// <remarks>
3911         /// Pages in the cache that cannot be immediately written back to disk
3912         /// (for example, pages that are currently in use by another thread of
3913         /// control) are waited for and written to disk as soon as it is
3914         /// possible to do so.
3915         /// </remarks>
3916         public void SyncMemPool() {
3917             SyncMemPool(null);
3918         }
3919         /// <summary>
3920         /// Flush modified pages in the cache with log sequence numbers less 
3921         /// than <paramref name="minLSN"/> to their backing files. 
3922         /// </summary>
3923         /// <remarks>
3924         /// Pages in the cache that cannot be immediately written back to disk
3925         /// (for example, pages that are currently in use by another thread of
3926         /// control) are waited for and written to disk as soon as it is
3927         /// possible to do so.
3928         /// </remarks>
3929         /// <param name="minLSN">
3930         /// All modified pages with a log sequence number less than the minLSN
3931         /// parameter are written to disk. If null, all modified pages in the
3932         /// cache are written to disk.
3933         /// </param>
3934         public void SyncMemPool(LSN minLSN) {
3935             dbenv.memp_sync(LSN.getDB_LSN(minLSN));
3936         }
3937
3938         /// <summary>
3939         /// Ensure that a specified percent of the pages in the cache are clean,
3940         /// by writing dirty pages to their backing files. 
3941         /// </summary>
3942         /// <param name="pctClean">
3943         /// The percent of the pages in the cache that should be clean.
3944         /// </param>
3945         /// <returns>
3946         /// The number of pages written to reach the specified percentage is
3947         /// copied.
3948         /// </returns>
3949         public int TrickleCleanMemPool(int pctClean) {
3950             int ret = 0;
3951             dbenv.memp_trickle(pctClean, ref ret);
3952             return ret;
3953         }
3954
3955         /// <summary>
3956         /// Append an informational message to the Berkeley DB database
3957         /// environment log files. 
3958         /// </summary>
3959         /// <overloads>
3960         /// WriteToLog allows applications to include information in the
3961         /// database environment log files, for later review using the
3962         /// db_printlog  utility. This method is intended for debugging and
3963         /// performance tuning.
3964         /// </overloads>
3965         /// <param name="str">The message to append to the log files</param>
3966         public void WriteToLog(string str) {
3967             dbenv.log_printf(null, str);
3968         }
3969         /// <summary>
3970         /// Append an informational message to the Berkeley DB database
3971         /// environment log files. 
3972         /// </summary>
3973         /// <overloads>
3974         /// WriteToLog allows applications to include information in the
3975         /// database environment log files, for later review using the
3976         /// db_printlog  utility. This method is intended for debugging and
3977         /// performance tuning.
3978         /// </overloads>
3979         /// <param name="str">The message to append to the log files</param>
3980         /// <param name="txn">
3981         /// If the operation is part of an application-specified transaction,
3982         /// <paramref name="txn"/> is a Transaction object returned from
3983         /// <see cref="DatabaseEnvironment.BeginTransaction"/>; 
3984         /// otherwise null.
3985         /// </param>
3986         public void WriteToLog(string str, Transaction txn) {
3987             dbenv.log_printf(Transaction.getDB_TXN(txn), str);
3988         }
3989
3990         #region Stats
3991         /// <summary>
3992         /// The locking subsystem statistics
3993         /// </summary>
3994         /// <returns>The locking subsystem statistics</returns>
3995         public LockStats LockingSystemStats() {
3996             return LockingSystemStats(false);
3997         }
3998         /// <summary>
3999         /// The locking subsystem statistics
4000         /// </summary>
4001         /// <param name="clearStats">
4002         /// If true, reset statistics after returning their values.
4003         /// </param>
4004         /// <returns>The locking subsystem statistics</returns>
4005         public LockStats LockingSystemStats(bool clearStats) {
4006             uint flags = 0;
4007             flags |= clearStats ? DbConstants.DB_STAT_CLEAR : 0;
4008             LockStatStruct st = dbenv.lock_stat(flags);
4009             return new LockStats(st);
4010         }
4011         /// <summary>
4012         /// The logging subsystem statistics
4013         /// </summary>
4014         /// <returns>The logging subsystem statistics</returns>
4015         public LogStats LoggingSystemStats() {
4016             return LoggingSystemStats(false);
4017         }
4018         /// <summary>
4019         /// The logging subsystem statistics
4020         /// </summary>
4021         /// <param name="clearStats">
4022         /// If true, reset statistics after returning their values.
4023         /// </param>
4024         /// <returns>The logging subsystem statistics</returns>
4025         public LogStats LoggingSystemStats(bool clearStats) {
4026             uint flags = 0;
4027             flags |= clearStats ? DbConstants.DB_STAT_CLEAR : 0;
4028             LogStatStruct st = dbenv.log_stat(flags);
4029             return new LogStats(st);
4030         }
4031         /// <summary>
4032         /// The memory pool (that is, the buffer cache) subsystem statistics
4033         /// </summary>
4034         /// <returns>The memory pool subsystem statistics</returns>
4035         public MPoolStats MPoolSystemStats() {
4036             return MPoolSystemStats(false);
4037         }
4038         /// <summary>
4039         /// The memory pool (that is, the buffer cache) subsystem statistics
4040         /// </summary>
4041         /// <param name="clearStats">
4042         /// If true, reset statistics after returning their values.
4043         /// </param>
4044         /// <returns>The memory pool subsystem statistics</returns>
4045         public MPoolStats MPoolSystemStats(bool clearStats) {
4046             uint flags = 0;
4047             flags |= clearStats ? DbConstants.DB_STAT_CLEAR : 0;
4048             MempStatStruct st = dbenv.memp_stat(flags);
4049             return new MPoolStats(st);
4050         }
4051         /// <summary>
4052         /// The mutex subsystem statistics
4053         /// </summary>
4054         /// <returns>The mutex subsystem statistics</returns>
4055         public MutexStats MutexSystemStats() {
4056             return MutexSystemStats(false);
4057         }
4058         /// <summary>
4059         /// The mutex subsystem statistics
4060         /// </summary>
4061         /// <param name="clearStats">
4062         /// If true, reset statistics after returning their values.
4063         /// </param>
4064         /// <returns>The mutex subsystem statistics</returns>
4065         public MutexStats MutexSystemStats(bool clearStats) {
4066             uint flags = 0;
4067             flags |= clearStats ? DbConstants.DB_STAT_CLEAR : 0;
4068             MutexStatStruct st = dbenv.mutex_stat(flags);
4069             return new MutexStats(st);
4070         }
4071         /// <summary>
4072         /// The replication manager statistics
4073         /// </summary>
4074         /// <returns>The replication manager statistics</returns>
4075         public RepMgrStats RepMgrSystemStats() {
4076             return RepMgrSystemStats(false);
4077         }
4078         /// <summary>
4079         /// The replication manager statistics
4080         /// </summary>
4081         /// <param name="clearStats">
4082         /// If true, reset statistics after returning their values.
4083         /// </param>
4084         /// <returns>The replication manager statistics</returns>
4085         public RepMgrStats RepMgrSystemStats(bool clearStats) {
4086             uint flags = 0;
4087             flags |= clearStats ? DbConstants.DB_STAT_CLEAR : 0;
4088             RepMgrStatStruct st = dbenv.repmgr_stat(flags);
4089             return new RepMgrStats(st);
4090         }
4091         /// <summary>
4092         /// The replication subsystem statistics
4093         /// </summary>
4094         /// <returns>The replication subsystem statistics</returns>
4095         public ReplicationStats ReplicationSystemStats() {
4096             return ReplicationSystemStats(false);
4097         }
4098         /// <summary>
4099         /// The replication subsystem statistics
4100         /// </summary>
4101         /// <param name="clearStats">
4102         /// If true, reset statistics after returning their values.
4103         /// </param>
4104         /// <returns>The replication subsystem statistics</returns>
4105         public ReplicationStats ReplicationSystemStats(bool clearStats) {
4106             uint flags = 0;
4107             flags |= clearStats ? DbConstants.DB_STAT_CLEAR : 0;
4108             ReplicationStatStruct st = dbenv.rep_stat(flags);
4109             return new ReplicationStats(st);
4110         }
4111         /// <summary>
4112         /// The transaction subsystem statistics
4113         /// </summary>
4114         /// <returns>The transaction subsystem statistics</returns>
4115         public TransactionStats TransactionSystemStats() {
4116             return TransactionSystemStats(false);
4117         }
4118         /// <summary>
4119         /// The transaction subsystem statistics
4120         /// </summary>
4121         /// <param name="clearStats">
4122         /// If true, reset statistics after returning their values.
4123         /// </param>
4124         /// <returns>The transaction subsystem statistics</returns>
4125         public TransactionStats TransactionSystemStats(bool clearStats) {
4126             uint flags = 0;
4127             flags |= clearStats ? DbConstants.DB_STAT_CLEAR : 0;
4128             TxnStatStruct st = dbenv.txn_stat(flags);
4129             return new TransactionStats(st);
4130         }
4131         #endregion Stats
4132
4133         #region Print Stats
4134         /// <summary>
4135         /// Display the locking subsystem statistical information, as described
4136         /// by <see cref="LockStats"/>.
4137         /// </summary>
4138         public void PrintLockingSystemStats() {
4139             PrintLockingSystemStats(false, false, false, false, false, false);
4140         }
4141         /// <summary>
4142         /// Display the locking subsystem statistical information, as described
4143         /// by <see cref="LockStats"/>.
4144         /// </summary>
4145         /// <param name="PrintAll">
4146                 /// If true, display all available information.
4147                 /// </param>
4148         /// <param name="ClearStats">
4149         /// If true, reset statistics after displaying their values.
4150         /// </param>
4151         public void PrintLockingSystemStats(bool PrintAll, bool ClearStats) {
4152             PrintLockingSystemStats(
4153                 PrintAll, ClearStats, false, false, false, false);
4154         }
4155         /// <summary>
4156         /// Display the locking subsystem statistical information, as described
4157         /// by <see cref="LockStats"/>.
4158         /// </summary>
4159         /// <param name="PrintAll">
4160                 /// If true, display all available information.
4161                 /// </param>
4162         /// <param name="ClearStats">
4163         /// If true, reset statistics after displaying their values.
4164         /// </param>
4165         /// <param name="ConflictMatrix">
4166         /// If true, display the lock conflict matrix.
4167         /// </param>
4168         /// <param name="Lockers">
4169         /// If true, Display the lockers within hash chains.
4170         /// </param>
4171         /// <param name="Objects">
4172         /// If true, display the lock objects within hash chains.
4173         /// </param>
4174         /// <param name="Parameters">
4175         /// If true, display the locking subsystem parameters.
4176         /// </param>
4177         public void PrintLockingSystemStats(bool PrintAll, bool ClearStats,
4178             bool ConflictMatrix, bool Lockers, bool Objects, bool Parameters) {
4179             uint flags = 0;
4180             flags |= PrintAll ? DbConstants.DB_STAT_ALL : 0;
4181             flags |= ClearStats ? DbConstants.DB_STAT_CLEAR : 0;
4182             flags |= ConflictMatrix ? DbConstants.DB_STAT_LOCK_CONF : 0;
4183             flags |= Lockers ? DbConstants.DB_STAT_LOCK_LOCKERS : 0;
4184             flags |= Objects ? DbConstants.DB_STAT_LOCK_OBJECTS : 0;
4185             flags |= Parameters ? DbConstants.DB_STAT_LOCK_PARAMS : 0;
4186
4187             dbenv.lock_stat_print(flags);
4188         }
4189
4190         /// <summary>
4191         /// Display the logging subsystem statistical information, as described
4192         /// by <see cref="LogStats"/>.
4193         /// </summary>
4194         public void PrintLoggingSystemStats() {
4195             PrintLoggingSystemStats(false, false);
4196         }
4197         /// <summary>
4198         /// Display the logging subsystem statistical information, as described
4199         /// by <see cref="LogStats"/>.
4200         /// </summary>
4201         /// <param name="PrintAll">
4202                 /// If true, display all available information.
4203                 /// </param>
4204         /// <param name="ClearStats">
4205         /// If true, reset statistics after displaying their values.
4206         /// </param>
4207         public void PrintLoggingSystemStats(bool PrintAll, bool ClearStats) {
4208             uint flags = 0;
4209             flags |= PrintAll ? DbConstants.DB_STAT_ALL : 0;
4210             flags |= ClearStats ? DbConstants.DB_STAT_CLEAR : 0;
4211
4212             dbenv.log_stat_print(flags);
4213         }
4214
4215         /// <summary>
4216         /// Display the memory pool (that is, buffer cache) subsystem
4217         /// statistical information, as described by <see cref="MPoolStats"/>.
4218         /// </summary>
4219         public void PrintMPoolSystemStats() {
4220             PrintMPoolSystemStats(false, false, false);
4221         }
4222         /// <summary>
4223         /// Display the memory pool (that is, buffer cache) subsystem
4224         /// statistical information, as described by <see cref="MPoolStats"/>.
4225         /// </summary>
4226         /// <param name="PrintAll">
4227                 /// If true, display all available information.
4228                 /// </param>
4229         /// <param name="ClearStats">
4230         /// If true, reset statistics after displaying their values.
4231         /// </param>
4232         public void PrintMPoolSystemStats(bool PrintAll, bool ClearStats) {
4233             PrintMPoolSystemStats(PrintAll, ClearStats, false);
4234         }
4235         /// <summary>
4236         /// Display the memory pool (that is, buffer cache) subsystem
4237         /// statistical information, as described by <see cref="MPoolStats"/>.
4238         /// </summary>
4239         /// <param name="PrintAll">
4240         /// If true, display all available information.
4241         /// </param>
4242         /// <param name="ClearStats">
4243         /// If true, reset statistics after displaying their values.
4244         /// </param>
4245         /// <param name="HashChains">
4246         /// If true, display the buffers with hash chains.
4247         /// </param>
4248         public void PrintMPoolSystemStats(
4249             bool PrintAll, bool ClearStats, bool HashChains) {
4250             uint flags = 0;
4251             flags |= PrintAll ? DbConstants.DB_STAT_ALL : 0;
4252             flags |= ClearStats ? DbConstants.DB_STAT_CLEAR : 0;
4253             flags |= HashChains ? DbConstants.DB_STAT_MEMP_HASH : 0;
4254
4255             dbenv.memp_stat_print(flags);
4256         }
4257
4258         /// <summary>
4259         /// Display the mutex subsystem statistical information, as described
4260         /// by <see cref="MutexStats"/>.
4261         /// </summary>
4262         public void PrintMutexSystemStats() {
4263             PrintMutexSystemStats(false, false);
4264         }
4265         /// <summary>
4266         /// Display the mutex subsystem statistical information, as described
4267         /// by <see cref="MutexStats"/>.
4268         /// </summary>
4269         /// <param name="PrintAll">
4270                 /// If true, display all available information.
4271                 /// </param>
4272         /// <param name="ClearStats">
4273         /// If true, reset statistics after displaying their values.
4274         /// </param>
4275         public void PrintMutexSystemStats(bool PrintAll, bool ClearStats) {
4276             uint flags = 0;
4277             flags |= PrintAll ? DbConstants.DB_STAT_ALL : 0;
4278             flags |= ClearStats ? DbConstants.DB_STAT_CLEAR : 0;
4279
4280             dbenv.mutex_stat_print(flags);
4281         }
4282
4283         /// <summary>
4284         /// Display the replication manager statistical information, as
4285         /// described by <see cref="RepMgrStats"/>.
4286         /// </summary>
4287         public void PrintRepMgrSystemStats() {
4288             PrintRepMgrSystemStats(false, false);
4289         }
4290         /// <summary>
4291         /// Display the replication manager statistical information, as
4292         /// described by <see cref="RepMgrStats"/>.
4293         /// </summary>
4294         /// <param name="PrintAll">
4295                 /// If true, display all available information.
4296                 /// </param>
4297         /// <param name="ClearStats">
4298         /// If true, reset statistics after displaying their values.
4299         /// </param>
4300         public void PrintRepMgrSystemStats(bool PrintAll, bool ClearStats) {
4301             uint flags = 0;
4302             flags |= PrintAll ? DbConstants.DB_STAT_ALL : 0;
4303             flags |= ClearStats ? DbConstants.DB_STAT_CLEAR : 0;
4304
4305             dbenv.repmgr_stat_print(flags);
4306         }
4307
4308         /// <summary>
4309         /// Display the replication subsystem statistical information, as
4310         /// described by <see cref="ReplicationStats"/>.
4311         /// </summary>
4312         public void PrintReplicationSystemStats() {
4313             PrintReplicationSystemStats(false, false);
4314         }
4315         /// <summary>
4316         /// Display the replication subsystem statistical information, as
4317         /// described by <see cref="ReplicationStats"/>.
4318         /// </summary>
4319         /// <param name="PrintAll">
4320                 /// If true, display all available information.
4321                 /// </param>
4322         /// <param name="ClearStats">
4323         /// If true, reset statistics after displaying their values.
4324         /// </param>
4325         public void 
4326             PrintReplicationSystemStats(bool PrintAll, bool ClearStats) {
4327             uint flags = 0;
4328             flags |= PrintAll ? DbConstants.DB_STAT_ALL : 0;
4329             flags |= ClearStats ? DbConstants.DB_STAT_CLEAR : 0;
4330
4331             dbenv.rep_stat_print(flags);
4332         }
4333
4334         /// <summary>
4335         /// Display the locking subsystem statistical information, as described
4336         /// by <see cref="LockStats"/>.
4337         /// </summary>
4338         public void PrintStats() {
4339             PrintStats(false, false, false);
4340         }
4341         /// <summary>
4342         /// Display the locking subsystem statistical information, as described
4343         /// by <see cref="LockStats"/>.
4344         /// </summary>
4345         /// <param name="PrintAll">
4346                 /// If true, display all available information.
4347                 /// </param>
4348         /// <param name="ClearStats">
4349         /// If true, reset statistics after displaying their values.
4350         /// </param>
4351         public void PrintStats(bool PrintAll, bool ClearStats) {
4352             PrintStats(PrintAll, ClearStats, false);
4353         }
4354         /// <summary>
4355         /// Display the locking subsystem statistical information, as described
4356         /// by <see cref="LockStats"/>.
4357         /// </summary>
4358         public void PrintSubsystemStats() {
4359             PrintStats(false, false, true);
4360         }
4361         /// <summary>
4362         /// Display the locking subsystem statistical information, as described
4363         /// by <see cref="LockStats"/>.
4364         /// </summary>
4365         /// <param name="PrintAll">
4366                 /// If true, display all available information.
4367                 /// </param>
4368         /// <param name="ClearStats">
4369         /// If true, reset statistics after displaying their values.
4370         /// </param>
4371         public void PrintSubsystemStats(bool PrintAll, bool ClearStats) {
4372             PrintStats(PrintAll, ClearStats, true);
4373         }
4374         /// <summary>
4375         /// Display the locking subsystem statistical information, as described
4376         /// by <see cref="LockStats"/>.
4377         /// </summary>
4378         private void PrintStats(bool all, bool clear, bool subs) {
4379             uint flags = 0;
4380             flags |= all ? DbConstants.DB_STAT_ALL : 0;
4381             flags |= clear ? DbConstants.DB_STAT_CLEAR : 0;
4382             flags |= subs ? DbConstants.DB_STAT_SUBSYSTEM : 0;
4383             dbenv.stat_print(flags);
4384         }
4385
4386         /// <summary>
4387         /// Display the transaction subsystem statistical information, as
4388         /// described by <see cref="TransactionStats"/>.
4389         /// </summary>
4390         public void PrintTransactionSystemStats() {
4391             PrintTransactionSystemStats(false, false);
4392         }
4393         /// <summary>
4394         /// Display the transaction subsystem statistical information, as
4395         /// described by <see cref="TransactionStats"/>.
4396         /// </summary>
4397         /// <param name="PrintAll">
4398                 /// If true, display all available information.
4399                 /// </param>
4400         /// <param name="ClearStats">
4401         /// If true, reset statistics after displaying their values.
4402         /// </param>
4403         public void
4404             PrintTransactionSystemStats(bool PrintAll, bool ClearStats) {
4405             uint flags = 0;
4406             flags |= PrintAll ? DbConstants.DB_STAT_ALL : 0;
4407             flags |= ClearStats ? DbConstants.DB_STAT_CLEAR : 0;
4408
4409             dbenv.txn_stat_print(flags);
4410         }
4411         #endregion Print Stats
4412
4413         private uint getRepTimeout(int which) {
4414             uint ret = 0;
4415             dbenv.rep_get_timeout(which, ref ret);
4416             return ret;
4417         }
4418         private bool getRepConfig(uint which) {
4419             int onoff = 0;
4420             dbenv.rep_get_config(which, ref onoff);
4421             return (onoff != 0);
4422         }
4423
4424         #region Unsupported Subsystem Methods
4425         /// <summary>
4426         /// The Berkeley DB process' environment may be permitted to specify
4427         /// information to be used when naming files; see Berkeley DB File
4428         /// Naming in the Programmer's Reference Guide for more information.
4429         /// </summary>
4430         public bool UseEnvironmentVars {
4431             get {
4432                 uint flags = 0;
4433                 dbenv.get_open_flags(ref flags);
4434                 return (flags & DbConstants.DB_USE_ENVIRON) != 0;
4435             }
4436         }
4437         private bool USE_ENVIRON_ROOT {
4438             get {
4439                 uint flags = 0;
4440                 dbenv.get_open_flags(ref flags);
4441                 return (flags & DbConstants.DB_USE_ENVIRON_ROOT) != 0;
4442             }
4443         }
4444         private uint CreateLockerID() {
4445             uint ret = 0;
4446             dbenv.lock_id(ref ret);
4447             return ret;
4448         }
4449         private void FreeLockerID(uint locker) {
4450             dbenv.lock_id_free(locker);
4451         }
4452
4453         private Lock GetLock(
4454             uint locker, bool wait, DatabaseEntry obj, LockMode mode) {
4455             return new Lock(dbenv.lock_get(locker,
4456                 wait ? 0 : DbConstants.DB_LOCK_NOWAIT,
4457                 obj, LockMode.GetMode(mode)));
4458         }
4459
4460         private Mutex GetMutex(bool SelfBlock, bool SingleProcess) {
4461             uint m = 0;
4462             uint flags = 0;
4463             flags |= SelfBlock ? DbConstants.DB_MUTEX_SELF_BLOCK : 0;
4464             flags |= SingleProcess ? DbConstants.DB_MUTEX_PROCESS_ONLY : 0;
4465             dbenv.mutex_alloc(flags, ref m);
4466             return new Mutex(this, m);
4467         }
4468
4469         private void LockMany(uint locker, bool wait, LockRequest[] vec) {
4470             LockMany(locker, wait, vec, null);
4471         }
4472         private void LockMany(
4473             uint locker, bool wait, LockRequest[] vec, LockRequest failedReq) {
4474             IntPtr[] reqList = new IntPtr[vec.Length];
4475             DB_LOCKREQ[] lst = new DB_LOCKREQ[vec.Length];
4476
4477             for (int i = 0; i < vec.Length; i++) {
4478                 reqList[i] = DB_LOCKREQ.getCPtr(
4479                     LockRequest.get_DB_LOCKREQ(vec[i])).Handle;
4480                 lst[i] = LockRequest.get_DB_LOCKREQ(vec[i]);
4481             }
4482
4483             dbenv.lock_vec(locker, wait ? 0 : DbConstants.DB_TXN_NOWAIT,
4484                 reqList, vec.Length, LockRequest.get_DB_LOCKREQ(failedReq));
4485
4486         }
4487         private void PutLock(Lock lck) {
4488             dbenv.lock_put(Lock.GetDB_LOCK(lck));
4489         }
4490         #endregion
4491     }
4492 }