Retrieving a range of data from Berkeley DB - berkeley-db

How can I retrieve a range of data such as 10 < key < 20 from Berkeley DB? I couldn't find anything by searching.

I've taken a quick look at http://pybsddb.sourceforge.net/bsddb3.html , and the following idea looks promising: create a DBCursor object, call its .set method to find key 10, then call its .next method until you reach 20.
I don't know the details of the C API, but I'd try the same idea: try to create a cursor, and call functions named like set and next on the cursor.

Maybe this code will help you. It extracts entries with key1<=key<=key2, but in can be modified for your condition. I use first DB_SET_RANGE flag to find key=>key1, and then DB_NEXT flag to get next values and check are they <=key2.
void get(DB *dbp, int key1, int key2){
DBC *curs;
DBT k,v;
int fl;
// Get a cursor
dbp->cursor(dbp, NULL, &curs, 0);
if (!curs) _dberr("can't get a cursor");
// Set DBT for 1st key and value
memset(&v, 0, sizeof(DBT));
memset(&k, 0, sizeof(DBT));
k.data = &key1;
k.size = sizeof(key1);
fl = DB_SET_RANGE; // first key will be >=key1
while (curs->c_get(curs, &k, &v, fl)==0 &&
key2 >= *(int *)k.data){
fl = DB_NEXT;
// use v.data
}
}

Related

How to add any symbols after prefix_?

is there any solution? e.g. I have data in Map with key favorites_ prefix and values _suffix (for example: favorites_jeans, favorites_suit,...,). I want to by dint of loop get that values and set in List, because of it I must give keys of map, right?
I want to know how can I get values of myMap["favorites_*"] (* - after the favorites_ any symbols).
List<String> favoritesStrings = ['favorite_name','favorite_jeans',];
Map<String,dynamic> myMap = {
favoritesStrings[0]:'0',
favoritesStrings[1]:'1',
'someKey':'2',
'anotherKey':'3',
};
favoritesStrings.forEach((favorite)=>print(myMap[favorite]));//prints 0 1
As per what I understood, you want to fetch value from map using "favorites_" + a dynamic value from list as key.
You just have to use String templates and use $ to insert suffix variable to build key dynamically:
List<String> suffixList = ["jeans", "suit", "shirt"];
for(String suffix in suffixList) {
var item = myMap["favorites_$suffix"];
// Do something with item
}
Hope it helps

DocumentDB Change Feed and saving Checkpoint

After reading the documentation, I'm having a hard time conceptualizing the change feed. Let's take the code from the documentation below. The second change feed is picking up the changes from the last time it was run via the checkpoints. Let's say it is being used to create summary data and there was an issue and it needed to be re-run from a prior time. I don't understand the following:
How to specify a particular time the checkpoint should start. I understand I can save the checkpoint dictionary and use that for each run, but how do you get the changes from X time to maybe rerun some summary data
Secondly, let's say we are rerunning some summary data and we save the last checkpoint used for each summarized data so we know where that one left off. How does one know that a record is in or before that checkpoint?
Code that runs from collection beginning and then from last checkpoint:
Dictionary < string, string > checkpoints = await GetChanges(client, collection, new Dictionary < string, string > ());
await client.CreateDocumentAsync(collection, new DeviceReading {
DeviceId = "xsensr-201", MetricType = "Temperature", Unit = "Celsius", MetricValue = 1000
});
await client.CreateDocumentAsync(collection, new DeviceReading {
DeviceId = "xsensr-212", MetricType = "Pressure", Unit = "psi", MetricValue = 1000
});
// Returns only the two documents created above.
checkpoints = await GetChanges(client, collection, checkpoints);
//
private async Task < Dictionary < string, string >> GetChanges(
DocumentClient client,
string collection,
Dictionary < string, string > checkpoints) {
List < PartitionKeyRange > partitionKeyRanges = new List < PartitionKeyRange > ();
FeedResponse < PartitionKeyRange > pkRangesResponse;
do {
pkRangesResponse = await client.ReadPartitionKeyRangeFeedAsync(collection);
partitionKeyRanges.AddRange(pkRangesResponse);
}
while (pkRangesResponse.ResponseContinuation != null);
foreach(PartitionKeyRange pkRange in partitionKeyRanges) {
string continuation = null;
checkpoints.TryGetValue(pkRange.Id, out continuation);
IDocumentQuery < Document > query = client.CreateDocumentChangeFeedQuery(
collection,
new ChangeFeedOptions {
PartitionKeyRangeId = pkRange.Id,
StartFromBeginning = true,
RequestContinuation = continuation,
MaxItemCount = 1
});
while (query.HasMoreResults) {
FeedResponse < DeviceReading > readChangesResponse = query.ExecuteNextAsync < DeviceReading > ().Result;
foreach(DeviceReading changedDocument in readChangesResponse) {
Console.WriteLine(changedDocument.Id);
}
checkpoints[pkRange.Id] = readChangesResponse.ResponseContinuation;
}
}
return checkpoints;
}
DocumentDB supports check-pointing only by the logical timestamp returned by the server. If you would like to retrieve all changes from X minutes ago, you would have to "remember" the logical timestamp corresponding to the clock time (ETag returned for the collection in the REST API, ResponseContinuation in the SDK), then use that to retrieve changes.
Change feed uses logical time in place of clock time because it can be different across various servers/partitions. If you would like to see change feed support based on clock time (with some caveats on skew), please propose/upvote at https://feedback.azure.com/forums/263030-documentdb/.
To save the last checkpoint per partition key/document, you can just save the corresponding version of the batch in which it was last seen (ETag returned for the collection in the REST API, ResponseContinuation in the SDK), like Fred suggested in his answer.
How to specify a particular time the checkpoint should start.
You could try to provide a logical version/ETag (such as 95488) instead of providing a null value as RequestContinuation property of ChangeFeedOptions.

AX NumberSequence: Mark a number as used

How to mark a given number as used in a NumberSequence when this number was not generated by the number sequence?
Let's consider I imported the first 10 records of a custom table and the file already specified its ID from 01 to 10,
then i want to intercept insert() mark the given number as used so that after importing, the first manually created record will assign ID 11.
This would be something like updating the field 'Next' in the NumberSequence.
Update the NumberSequenceTable.NextRec value to the desired value.
Make sure that format is correct.
Example code:
NumberSequenceTable numberSequenceTable;
ttsBegin;
select forUpdate numberSequenceTable
where numberSequenceTable.NumberSequence == 'Acco_1' // as example
;
numberSequenceTable.NextRec = 11;
if (numberSequenceTable.validateField(fieldNum(NumberSequenceTable, NextRec))
&& numberSequenceTable.validateWrite()
)
{
numberSequenceTable.update();
}
else
{
throw error("Validation failed");
}
ttsCommit;

Autofetch behavior with firehose cursor, when SQL_SOPT_SS_CURSOR_OPTIONS option is set to SQL_CO_FIREHOSE_AF

On firehose cursor, when statement attribute SQL_SOPT_SS_CURSOR_OPTIONS is set to SQL_CO_FIREHOSE_AF, and the statement is executed, observed different behavior for autofetch which are mentioned below:
1) When SQLExecute is called first time it does not autofetch.
2) When SQLExecute is called second time on the same stament handle, after closing cursor using SQLFreestmt(hstmt, SQL_CLOSE), it autofetch 1 row with SQLExecute.
So what is the expected behavior, whether it should autofetch or not ? This seems to be bug in SQL Native client drivers.
Also I didn't see documentation for SQL_CO_FIREHOSE_AF but it is listed in sqlncli.h ?
code snippet with comments:
rc = SQLSetStmtAttr(hstmt1, (UWORD) SQL_SOPT_SS_CURSOR_OPTIONS, (SQLPOINTER) SQL_CO_FIREHOSE_AF, 0);
...
rc = SQLSetStmtAttr(hstmt1, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)1, 0);
// Execute first statement
rc = SQLExecute(hstmt1); // it does not autofetch the data.
...
rc = SQLFreeStmt(hstmt1, SQL_CLOSE);
...
rc = SQLSetStmtAttr(hstmt1, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)1, 0);
// Execute first statement
rc = SQLExecute(hstmt1); // it autofetch 1 record.
Thanks,
Mukesh

. The An object with the same key already exists in the ObjectStateManagerObjectStateManager cannot track multiple objects with the same key

I am trying to simply update the entity object and I get this error.. All the googling on the error I did takes me to complex explanations... can anyone put it simply?
I am working of of this simple tutorial
http://aspalliance.com/1919_ASPNET_40_and_the_Entity_Framework_4__Part_2_Perform_CRUD_Operations_Using_the_Entity_Framework_4.5
else
{
//UPDATE
int iFid = Int32.Parse(fid.First().fid.ToString());
oFinancial.fid = iFid;
oFinancial.mainqtr = currentQuarter;
oFinancial.mainyear = currentYear;
oFinancial.qtr = Int32.Parse(currentQuarter);
oFinancial.year = Int32.Parse(currentYear);
oFinancial.updatedate = DateTime.Now;
// ObjectStateEntry ose = null;
// if (!dc.ObjectStateManager.TryGetObjectStateEntry(oFinancial.EntityKey, out ose))
// {
dc.financials.Attach(oFinancial);
// }
dc.ObjectStateManager.ChangeObjectState(oFinancial, System.Data.EntityState.Modified);
}
dc.SaveChanges();
here is what is higher up in the code that I use simple to get me the primary key value.. probably a better way but it works.
var fid = from x in dc.financials
where iPhaseID == x.phaseid &&
strTaskID == x.ftaskid &&
strFundType == x.fundtype &&
iCurrentQuarter == x.qtr &&
iCurrentYear == x.year
select x;
If the oFinancial object came from your dc and you never manually detached it, then there is no reason to call the Attach method or to mess with the ObjectStateManager. As long as the dc knows about the object (which it does unless you detach it), then the ObjectStateManager will keep track of any changes you make and update them accordingly when you call dc.SaveChanges().
EDIT: Here's a refactored version of what you posted, hope it helps:
else {
//UPDATE
// as long as oFinancial was never detatched after you retrieved
// it from the "dc", then you don't have to re-attach it. And
// you should never need to manipulate the primary key, unless it's
// not generated by the database, and you don't already have another
// object in the "dc" with the same primary key value.
int iFid = Int32.Parse(fid.First().fid.ToString());
oFinancial.fid = iFid;
oFinancial.mainqtr = currentQuarter;
oFinancial.mainyear = currentYear;
oFinancial.qtr = Int32.Parse(currentQuarter
oFinancial.year = Int32.Parse(currentYear);
oFinancial.updatedate = DateTime.Now;
}
dc.SaveChanges();
One other thing: if iFid is the primary key, then you shouldn't mess with it as long as this object came from the dc. I believe the problem is that you're resetting the primary key (iFid) to the same value of another object within the dc, and EF4 is barking because you can't have two rows with the same primary key value in a table.

Resources