Few of the challenges of creating a query language lie in writing the parser. The first challenge is that you must have an engine that can prove a query. For this, you can use the engine in sjm.engine , or you can write your own or find one from another source. An interesting project would be to use an engine from a commercial database, although database vendors typically do not make their engines easily accessible.
Once you have an engine, developing a practical query language requires you to engineer a scheme for feeding the engine. First, you must be able to translate a user query into an engine. This requires writing your parser, its associated assemblers, and typically a query builder. You also need query structures for each class in the object model. You can write these by hand, as in the examples in this chapter, or you can explore the automatic approach using Java's reflection capabilities.
In addition to feeding the engine a query, you must develop an approach to feeding the engine facts. For a small object model, you can load all the data from your object model into a single Program object. For a midsize or larger object model, you need to limit the conversion of facts. For example, given the query
chip(1004, ChipName, PricePerBag, Ounces, Oil)
a smart axiom source returns just one chip type, the one whose ID is 1004. An axiom source can also use indexing and caching to reduce the number of facts it creates and feeds to an engine.
Tying a query language to an engine is hard work, but the benefits can make it worthwhile. The primary benefit is that your users can issue ad hoc queries. In a normal object-oriented system, the only way to interrogate an object model is to write a Java method that performs the query. As a developer, you have to foresee what questions your users will have about an object model, something that, history has shown, is not possible. A query language lets users decide, after the system is complete, which questions they have about the object model.