KeyValuePair <DatabaseEntry, MultipleDatabaseEntry> GetBothMultiple( DatabaseEntry key, DatabaseEntry data, int BufferSize, Transaction txn, LockingInfo info) { KeyValuePair <DatabaseEntry, DatabaseEntry> kvp; int datasz = (int)data.Data.Length; for (; ;) { byte[] udata = new byte[BufferSize]; Array.Copy(data.Data, udata, datasz); data.UserData = udata; data.size = (uint)datasz; try { kvp = Get(key, data, txn, info, DbConstants.DB_MULTIPLE | DbConstants.DB_GET_BOTH); break; } catch (MemoryException) { int sz = (int)data.size; if (sz > BufferSize) { BufferSize = sz; } else { BufferSize *= 2; } } } MultipleDatabaseEntry dbe = new MultipleDatabaseEntry(kvp.Value); return(new KeyValuePair <DatabaseEntry, MultipleDatabaseEntry>( kvp.Key, dbe)); }
/// <summary> /// Retrieve a specific numbered key and all duplicate data items from /// the database. /// </summary> /// <param name="recno"> /// The record number of the record to be retrieved. /// </param> /// <param name="BufferSize"> /// The initial size of the buffer to fill with duplicate data items. If /// the buffer is not large enough, it is automatically resized. /// </param> /// <param name="txn"> /// <paramref name="txn"/> is a Transaction object returned from /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if /// the operation is part of a Berkeley DB Concurrent Data Store group, /// <paramref name="txn"/> is a handle returned from /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null. /// </param> /// <param name="info">The locking behavior to use.</param> /// <exception cref="NotFoundException"> /// A NotFoundException is thrown if <paramref name="recno"/> is not in /// the database. /// </exception> /// <returns> /// A <see cref="KeyValuePair{T,T}"/> whose Key parameter is /// <paramref name="recno"/> and whose Value parameter is the retrieved /// data items. /// </returns> public KeyValuePair <DatabaseEntry, MultipleDatabaseEntry> GetMultiple( uint recno, int BufferSize, Transaction txn, LockingInfo info) { KeyValuePair <DatabaseEntry, DatabaseEntry> kvp; DatabaseEntry key = new DatabaseEntry(); key.Data = BitConverter.GetBytes(recno); DatabaseEntry data = new DatabaseEntry(); for (; ;) { data.UserData = new byte[BufferSize]; try { kvp = Get(key, data, txn, info, DbConstants.DB_MULTIPLE | DbConstants.DB_SET_RECNO); break; } catch (MemoryException) { int sz = (int)data.size; if (sz > BufferSize) { BufferSize = sz; } else { BufferSize *= 2; } } } MultipleDatabaseEntry dbe = new MultipleDatabaseEntry(kvp.Value); return(new KeyValuePair <DatabaseEntry, MultipleDatabaseEntry>( kvp.Key, dbe)); }
/// <summary> /// Send a message on the message channel. The message is sent /// synchronously. The method blocks waiting for a response before /// returning. If a response is not received within the timeout value /// configured for this request, this method returns with an error /// condition. /// </summary> /// <remarks> /// <para> /// To avoid block while waiting for a response from a remote site, /// use <see cref="SendMessage"/> /// </para> /// <para> /// The message sent by this method is received and handled at remote /// sites using a message dispatch callback, which is configured using /// <see cref="DatabaseEnvironment.RepMessageDispatch"/> /// </para> /// </remarks> /// <param name="request"> /// DatabaseEntry objects array. Any flags for the DatabaseEntry objects /// are ignored. /// </param> /// <param name="bufferSize">Size of bulk buffer</param> /// <param name="timeout"> /// The amount of time that may elapse while this method waits for a /// response from the remote site. The timeout value must be specified /// as an unsigned 32-bit number of microseconds, limiting the maximum /// timeout to roughly 71 minutes. A timeout value of 0 indicates that /// the channel's default timeout value should be used. This default is /// configured using <see cref="Timeout"/>. /// </param> /// <returns>Multiple responses from the remote site.</returns> public MultipleDatabaseEntry SendRequest( DatabaseEntry[] request, int bufferSize, uint timeout) { int size = request.Length; IntPtr[] dbts = new IntPtr[size]; for (int i = 0; i < size; i++) { dbts[i] = DBT.getCPtr(DatabaseEntry.getDBT(request[i])).Handle; } DatabaseEntry data = new DatabaseEntry(); data.UserData = new byte[bufferSize]; channel.send_request(dbts, (uint)size, data, timeout, DbConstants.DB_MULTIPLE); MultipleDatabaseEntry response = new MultipleDatabaseEntry(data); return(response); }
/// <summary> /// Protected method to call the key generation function. /// </summary> /// <param name="dbp">Secondary DB Handle</param> /// <param name="keyp">Primary Key</param> /// <param name="datap">Primary Data</param> /// <param name="skeyp">Scondary Key</param> /// <returns>0 on success, !0 on failure</returns> protected static int doAssociate( IntPtr dbp, IntPtr keyp, IntPtr datap, IntPtr skeyp) { DB db = new DB(dbp, false); DBT key = new DBT(keyp, false); DBT data = new DBT(datap, false); DBT skey = new DBT(skeyp, false); IntPtr dataPtr, sdataPtr; int nrecs, dbt_sz; DatabaseEntry s = ((SecondaryDatabase)db.api_internal).KeyGen( DatabaseEntry.fromDBT(key), DatabaseEntry.fromDBT(data)); if (s == null) { return(DbConstants.DB_DONOTINDEX); } if (s is MultipleDatabaseEntry) { MultipleDatabaseEntry mde = (MultipleDatabaseEntry)s; nrecs = mde.nRecs; /* * Allocate an array of nrecs DBT in native memory. The call * returns sizeof(DBT), so that we know where one DBT ends and * the next begins. */ dbt_sz = (int)libdb_csharp.alloc_dbt_arr(null, nrecs, out sdataPtr); /* * We need a managed array to copy each DBT into and then we'll * copy the managed array to the native array we just allocated. * We are not able to copy native -> native. */ byte[] arr = new byte[nrecs * dbt_sz]; IntPtr p; int off = 0; /* Copy each DBT into the array. */ foreach (DatabaseEntry dbt in mde) { /* Allocate room for the data in native memory. */ dataPtr = libdb_csharp.__os_umalloc(null, dbt.size); Marshal.Copy(dbt.Data, 0, dataPtr, (int)dbt.size); dbt.dbt.dataPtr = dataPtr; dbt.flags |= DbConstants.DB_DBT_APPMALLOC; p = DBT.getCPtr(DatabaseEntry.getDBT(dbt)).Handle; Marshal.Copy(p, arr, off, dbt_sz); off += dbt_sz; } Marshal.Copy(arr, 0, sdataPtr, nrecs * dbt_sz); skey.dataPtr = sdataPtr; skey.size = (uint)mde.nRecs; skey.flags = DbConstants.DB_DBT_MULTIPLE | DbConstants.DB_DBT_APPMALLOC; } else { skey.data = s.Data; } return(0); }