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