// Using a DynamicIndexedDBView to read, update and insert records in a database.

// Dynamic IndexedDBView example

// ... classes as in IndexedDBView example  ....

void DynamicIndexedViewExample()
{
 DynamicDBView<ParamObjExample> dynamic_view("DB_EXAMPLE",
	 "INT_VALUE, STRING_VALUE, DOUBLE_VALUE, EXAMPLE_LONG,  EXAMPLE_DATE",
	 "WHERE INT_VALUE BETWEEN (?) AND (?) OR "
	  "STRING_VALUE = (?) OR EXAMPLE_DATE <= (?) ORDER BY EXAMPLE_LONG",
	  BPAExampleObj());

 DynamicIndexedDBView< DynamicDBView<ParamObjExample> >  
	 indexed_view(dynamic_view, 
         "UNIQUE PrimaryIndex; STRING_VALUE;"
         "IndexLongDate; EXAMPLE_LONG, EXAMPLE_DATE",
	 BOUND, USE_ALL_FIELDS, cb_ptr_fun(SetParamsExample));

 // Find the item where the STRING_VALUE matches the string  "Foozle"
 DynamicIndexedDBView< DynamicDBView<ParamObjExample> >::indexed_iterator idxview_it =  indexed_view.find(string("Foozle"));


 // Update the item with the key of "Foozle", to read  "Fizzle" instead
 if (idxview_it != indexed_view.end()) {
  variant_row replacement;
  replacement = *idxview_it;
  replacement["STRING_VALUE"] =   string("Fizzle");
  indexed_view.replace(idxview_it, replacement);
 }

 // Now find a second set of items using AlternateIndex
 // The STL convention for equal_range is to return a pair  consisting of: 
 // 1. an iterator referring to the beginning of the list of found  items
 // 2. an iterator pointing to the end of the list of found items. 
 // We will remove all items in this range.
 const TIMESTAMP_STRUCT date_criteria = {2000, 1, 1, 0, 0, 0, 0};
 long long_criteria = 33;
 DynamicIndexedDBView< DynamicDBView<ParamObjExample> >::indexed_pair 
   pr = indexed_view.equal_range_AK("IndexLongDate", long_criteria, date_criteria);

 idxview_it = pr.first;

 cout << "*** Size before erase calls: " << indexed_view.size() << " ***" << endl; 

 // Remove all rows that matched the criteria in our equal_range_AK lookup 
 while (idxview_it !="pr.second)" { 
   // as iterator is invalidated upon an erase(), use a temporary iterator 
   // to point to DataObj to erase 
   // increment idxview_it before we erase so it will still be valid 
   // when we erase the DataObj 
   DynamicIndexedDBView< DynamicDBView<ParamObjExample> >::indexed_iterator deleteMe="idxview_it;" 
   idxview_it++; 
   indexed_view.erase(deleteMe); 
 } 
 cout << "*** Size after erase calls: " << indexed_view.size() << " ***" << endl; 
 
 // Finally, insert a new item into the container 
 pair<DynamicIndexedDBView< DynamicDBView<ParamObjExample> >::iterator, bool> ins_pr; 
 
 variant_row r(indexed_view.DataObj()); 
 r["INT_VALUE"]=459; 
 r["STRING_VALUE"]=string("Unique String #1"); 
 r["DOUBLE_VALUE"]=3.5; 
 r["EXAMPLE_LONG"]=1; 
 r["EXAMPLE_DATE"]=date_criteria; 
 ins_pr=indexed_view.insert(r);
 cout << "insertion succeded=" <<  (ins_pr.second == true ? " true": " false") << endl; 
}