Delay calling cacheModel.RegisterTriggerStatement until all statements have 
been initialized
--------------------------------------------------------------------------------------------

         Key: IBATISNET-100
         URL: http://issues.apache.org/jira/browse/IBATISNET-100
     Project: iBatis for .NET
        Type: Improvement
  Components: DataMapper  
    Reporter: Ron Grabowski
    Priority: Minor


I've extracted all of my cacheModel and resultMap nodes to a seperate xml files:

 /SqlMaps/CacheModels.xml
 /SqlMaps/ResultMaps.xml
 /SqlMaps/OleDb/...
 /SqlMaps/MySQL/...
 /SqlMaps/SqlServer/...

to avoid duplicating nodes in database specific files. The database specific 
files are a lot cleaner becuase they only contain <statement> nodes.

The current implementation of ConfigureSqlMap() in DomSqlMapBuilder.cs calls 
RegisterTriggerStatement when the cacheModel node is processed. When the 
cacheModel nodes are in a seperate file, its not possible to register a trigger 
statement becuase the xml files that contain those statements haven't been 
processed yet. Delaying the registration of cacheModel to just before the 
cacheModel is attached to the mapped statement makes it possible to declare the 
cacheModel nodes without requiring the statements exist yet. 

One of the benefits to being able to keep a seperate file of cacheModel nodes 
is that you could mark normal sqlMap file as embedded resources while keeping 
the CacheModel.xml file as a resource on the file system. The CacheModels.xml 
file can be tweaked without having to recompile the application. 

To accomplish this, 4 changes need to occur:

1)
Change the SqlMap.xsd file to not require a <statements> node. This allows a 
<sqlMap> node to contain just a <cacheModels> and/or just a <resultMaps> node.

2)
Add a property in ConfigurationScope.cs to keep track of what statements belong 
to a cacheModel:

 public HybridDictionary CacheModelFlushOnExecuteStatements
 {
 get { return _cacheModelFlushOnExecuteStatements; }
 set { _cacheModelFlushOnExecuteStatements = value; }
 }

I wonder if there is a cleaner way of doing this ???

3)
Replace this code in DomSqlMapBuilder.cs:

 IMappedStatement mappedStatement = 
_configScope.SqlMapper.GetMappedStatement(statementName);
 cacheModel.RegisterTriggerStatement(mappedStatement);

with:

 IList statementNames = 
(IList)_configScope.CacheModelFlushOnExecuteStatements[cacheModel.Id];
 if (statementNames == null)
 {
  statementNames = new ArrayList();
 }
 statementNames.Add(statementName);
 _configScope.CacheModelFlushOnExecuteStatements[cacheModel.Id] = 
statementNames;

4)
Change this line in DomSqlMapBuilder.cs:

 mappedStatement.Statement.CacheModel = 
_configScope.SqlMapper.GetCache(mappedStatement.Statement.CacheModelName);

to:

 CacheModel cacheModel = 
_configScope.SqlMapper.GetCache(mappedStatement.Statement.CacheModelName);
 IList statementsToRegister = 
(IList)_configScope.CacheModelFlushOnExecuteStatements[cacheModel.Id];
 if (statementsToRegister != null)
 {
  if (statementsToRegister.Contains(mappedStatement.Name))
  {
  cacheModel.RegisterTriggerStatement(mappedStatement);
  }
  else
  {
  // TODO: alert user
  }
 }
 mappedStatement.Statement.CacheModel = cacheModel;

Do other people think this would be useful? It would certinally make files that 
contain <statement> nodes a lot cleaner and eliminate to duplication of 
<cacheModels> and <resultMaps> node across files.

- Ron

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira

Reply via email to