NetworkedPlanet | TMCore Engine API Guide |
The interface ITopicMapSystem
provides a single method
ITopicMapSystem.ExecuteQuery(string)
through
which an SQL query can be executed against the TMCore system. The method
returns an instance of the
ITMCoreDataReader
interface which gives
read-only access to the results of the query.
The ITMCoreDataReader
interface
extends the standard System.Data.IDataReader interface with the
following additional methods:
ITopic GetTopic(int i);
ITopicName GetTopicName(int i);
IOccurrence GetOccurrence(int i);
IVariant GetVariant(int i);
IAssociation GetAssociation(int i);
IAssociationRole GetAssociationRole(int i);
ITopicMapObject GetTopicMapObject(int i);
Each of the methods listed above take as their single parameter
the zero-based position of the column from which the object's
ObjectID value is to be retrieved. The method then
loads any additional data required from the database and returns an
instance of the appropriate topic map object interface. The method
GetTopicMapObject()
will determine the type of
the object and return an instance of the appropriate dervied interface
(e.g. an IOccurrence
instance if the
identifier is from an occurrence object). If the content of the
specified column is not the object identifier of the requested type of
topic map object, then an InvalidCastException
will be raised.
The GetTopicMapObject()
method uses
additional database queries to determine the type of the object and so
its use should be avoided unless the specified column can contain
identifiers of a mixture of types of object.
As with other IDataReader
s, the
ITMCoreDataReader
must be closed once it
is no longer needed by calling the Close()
method. The TMCore code will create a new connection for each concurrent
ITMCoreDataReader
instance that your
program holds open and unless these readers are closed when not needed,
your application will quickly use up all the available connections
leading to unexpected failures.
The code listing below shows an example of using the
ITopicMapSystem.ExecuteQuery()
method to
retrieve the topic names which contain the string "foo" and have a
particular topic in their scope. Note that the call to the
ITMCoreDataReader.Close()
method is enclosed in
the finally block to ensure that it gets called even if the processing
of a topic name results in an exception being raised.
Example 9.1. Using ITMCoreDataReader
ITopic scopingTopic; ITopicMap tm; // ... set up scopingTopic and tm string query = "select v.name_id from " + "TM_nameValue join TM_nameScope on TM_nameValue.name_id=TM_nameScope.name_id" + "where TM_nameValue.name_value like '%foo%' and TM_nameScope.scoping_topic_id=" + scopingTopic.ObjectID; ITMCoreDataReader dr = tm.TopicMapSystem.ExecuteQuery(query); try { while (dr.Read()) { ITopicName tn = dr.GetTopicName(0); // Do something with the scoped name } } finally { dr.Close(); }
The TopicMapSystem interface also supports executing queries with a set of parameters. This is STRONGLY RECOMMENDED when one or more parameters come from user input as SQL parameter values are properly escaped and checked for SQL injection attacks. There are two overrides of the ExecuteQuery method that support parameters. The method ExecuteQuery(String queryString, IList parameters) takes a list of System.Data.IDataParameter instances (e.g. System.Data.SqlClient.SqlParameter), this method gives you the most control over the parameters you pass at the expense of requiring you to instantiate each parameter object explicitly. The second override is ExecuteQuery(String queryString, Hashtable parameters), which takes a Hashtable of parameter values where the Hashtable key is the parameter name and the value is the parameter value. The parameter type is automatically inferred from the parameter value.
The code samples below show how these two overrides can be used.
Example 9.2. Using ExecuteQuery(string, IList)
string query = "select v.name_id " + "from tm_nameValue join tm_nameScope on tm_nameValue.name_id=tm_nameScope.name_id "+ "where tm_nameValue.name_value like @name and tm_nameScope.scoping_topic_id=@scopingTopic"; ArrayList parameters = new ArrayList(); IDataParameter param = new SqlParameter(); param.Name = "@name"; param.DbType = DbType.String; param.Value = "%foo%"; parameters.add(param); param = new SqlParameter(); param.Name = "@scopingTopic"; param.DbType = DbType.Int32; param.Value = scopingTopic.ID; parameters.add(param); ITMCoreDataReader dr = tm.TopicMapSystem.ExecuteQuery(query, parameters);
Example 9.3. Using ExecuteQuery(string, Hashtable)
string query = "select v.name_id " + "from tm_nameValue join tm_nameScope on tm_nameValue.name_id=tm_nameScope.name_id "+ "where tm_nameValue.name_value like @name and tm_nameScope.scoping_topic_id=@scopingTopic"; Hashtable parameters = new Hashtable(); parameters["@name"] = "%foo%"; parameters["@scopingTopic"] = scopingTopic.ID; ITMCoreDataReader dr = tm.TopicMapSystem.ExecuteQuery(query, parameters);