
Brian Braatz <brianb <at> rmtg.com> writes:
If you would please elaborate. (some of us are "slower" than others :) ).
is the problem getting to the index objects themselves via inherit_linearly?
if you have dynamic data, then I am thinking you also have dynamically applied indices?
Maybe I can elaborate-
consider the following pseudo code:
connection con = db.connect("myserver,root,password,mydatabase");
dynamic_table dt;
// the select "*" means bring me back all the fields from that table // even though I don't know what the fields ARE yet dt = query("select * from person");
// ok so now dt has an UNKNOWN number of columns
dt.add_index( index("first_name"));
// or something along those lines.
in this case, the index is applied dynamically.
so how does that connect with the things you said ?
Let me formulate the problem in the terminology of Boost.MultiIndex --hopefully, the implications for a DB framework scenario will be clear after this. Consider the following perfectly normal code dealing with a static multi_index_container: typedef multi_index_container< element, indexed_by< ordered_unique<identity<element> >, sequenced<>
static_mic_t;
template<typename Index> void reverse_dump(const Index& i) { std::copy( i.rbegin(),i.rend(), std::ostream_iterator<typename Index::value_type>(std::cout)); } int main() { static_mic_t s_mic; ... reverse_dump(s_mic.get<0>()); reverse_dump(s_mic.get<1>()); } What would the equivalent be for the dynamic case? typedef dynamic_multi_index_container< element
dynamic_mic_t; // no indices specified at compile time
int main() { dynamic_mic_t d_mic; // add indices at run time d_mic.add_index<ordered_unique<identity<element> > >(); d_mic.add_index<sequenced<> >(); ... reverse_dump(d_mic.get(0)); // note index number is no longer reverse_dump(d_mic.get(1)); // a template parameter } Now, how are we supposed to define reverse_dump? Clearly it cannot be the same template as in the static case, since the types of the indices are only known at run time. Also, it is not clear what get(), which no longer accepts the index number as a template parameter, should return: now the function locates and provides the index at run time. What we want is some sort of run-time polymorphism, as provided by abstract classes or BIL interfaces. With the second option, we can have something like this: typedef dynamic_multi_index_container< element, // this is the interface indices must conform to when // added at run time IBidirectionalContainer<element>
dynamic_mic_t;
template<typename Element> void reverse_dump(IBidirectionalContainer<Element> i) { std::copy( i.rbegin(),i.rend(), std::ostream_iterator<Element>(std::cout)); } int main() { dynamic_mic_t d_mic; // add indices at run time // This is fine as both ordered and sequenced indices // model IBidirectionalContainer. If we tried to add // a hashed index, which only provides forward iterators, // a compile-time error would be triggered. d_mic.add_index<ordered_unique<identity<element> > >(); d_mic.add_index<sequenced<> >(); ... // OK now, get() returns a IBidirectionalContainer // interface object, providing "virtual" rbegin and // rend memfuns. reverse_dump(d_mic.get(0)); reverse_dump(d_mic.get(1)); } Get the idea? Interfaces provide the necessary virtuality into the run-time polymorphism realm. This concept is sometimes called "type erasure" and pops up recurrently when bridging templates and run-time polymorphism. If I wasn't clear enough please tell me so and I'll try to elaborate. I'll be more than happy to discuss and refine these ideas. IMHO the concepts around a potential multi_index_container sketched here can serve as the basis for a DB run-time data structure, much like for instance IndexedDBView in the DTL does. Best, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo