Package org.jboss.ejb.plugins.cmp.jdbc2.schema

Source Code of org.jboss.ejb.plugins.cmp.jdbc2.schema.EntityTable$View

/*      */ package org.jboss.ejb.plugins.cmp.jdbc2.schema;
/*      */
/*      */ import java.sql.Connection;
/*      */ import java.sql.PreparedStatement;
/*      */ import java.sql.ResultSet;
/*      */ import java.sql.SQLException;
/*      */ import java.util.ArrayList;
/*      */ import java.util.HashMap;
/*      */ import java.util.List;
/*      */ import java.util.Map;
/*      */ import javax.ejb.DuplicateKeyException;
/*      */ import javax.ejb.EJBException;
/*      */ import javax.ejb.NoSuchEntityException;
/*      */ import javax.ejb.NoSuchObjectLocalException;
/*      */ import javax.management.MBeanServer;
/*      */ import javax.management.ObjectName;
/*      */ import javax.naming.InitialContext;
/*      */ import javax.naming.NamingException;
/*      */ import javax.sql.DataSource;
/*      */ import javax.transaction.Transaction;
/*      */ import org.jboss.cache.invalidation.InvalidationGroup;
/*      */ import org.jboss.cache.invalidation.InvalidationManagerMBean;
/*      */ import org.jboss.deployment.DeploymentException;
/*      */ import org.jboss.ejb.EntityContainer;
/*      */ import org.jboss.ejb.plugins.cmp.jdbc.JDBCEntityPersistenceStore;
/*      */ import org.jboss.ejb.plugins.cmp.jdbc.JDBCType;
/*      */ import org.jboss.ejb.plugins.cmp.jdbc.JDBCTypeFactory;
/*      */ import org.jboss.ejb.plugins.cmp.jdbc.JDBCUtil;
/*      */ import org.jboss.ejb.plugins.cmp.jdbc.SQLUtil;
/*      */ import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractCMRFieldBridge;
/*      */ import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCEntityMetaData;
/*      */ import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCFunctionMappingMetaData;
/*      */ import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCTypeMappingMetaData;
/*      */ import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCCMPFieldBridge2;
/*      */ import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCEntityBridge2;
/*      */ import org.jboss.logging.Logger;
/*      */ import org.jboss.metadata.CacheInvalidationConfigMetaData;
/*      */ import org.jboss.metadata.ConfigurationMetaData;
/*      */ import org.jboss.metadata.EntityMetaData;
/*      */ import org.jboss.metadata.MetaData;
/*      */ import org.jboss.mx.util.MBeanProxyExt;
/*      */ import org.jboss.mx.util.MBeanServerLocator;
/*      */ import org.jboss.system.Registry;
/*      */ import org.jboss.system.ServiceControllerMBean;
/*      */ import org.w3c.dom.Element;
/*      */
/*      */ public class EntityTable
/*      */   implements Table
/*      */ {
/*      */   private static final byte UNREFERENCED = 0;
/*      */   private static final byte CLEAN = 1;
/*      */   private static final byte DIRTY = 2;
/*      */   private static final byte CREATED = 4;
/*      */   private static final byte DELETED = 8;
/*      */   private static final byte DIRTY_RELATIONS = 16;
/*   83 */   private static final Object NOT_LOADED = new Object();
/*      */   private JDBCEntityBridge2 entity;
/*      */   private String tableName;
/*      */   private int fieldsTotal;
/*      */   private int relationsTotal;
/*      */   private DataSource dataSource;
/*      */   private Schema schema;
/*      */   private int tableId;
/*      */   private boolean dontFlushCreated;
/*      */   private String deleteSql;
/*      */   private String updateSql;
/*      */   private String insertSql;
/*      */   private String selectSql;
/*      */   private String duplicatePkSql;
/*      */   private final CommitStrategy insertStrategy;
/*      */   private final CommitStrategy deleteStrategy;
/*      */   private final CommitStrategy updateStrategy;
/*      */   private Logger log;
/*      */   private Cache cache;
/*      */   private ServiceControllerMBean serviceController;
/*      */   private ObjectName cacheName;
/*      */   private int[] references;
/*      */   private int[] referencedBy;
/*      */   private ForeignKeyConstraint[] fkConstraints;
/*      */   private CacheInvalidator cacheInvalidator;
/* 1817 */   private static final CommitStrategy BATCH_UPDATE = new CommitStrategy()
/*      */   {
/*      */     public void executeUpdate(PreparedStatement ps) throws SQLException
/*      */     {
/* 1821 */       ps.addBatch();
/*      */     }
/*      */
/*      */     public void executeBatch(PreparedStatement ps) throws SQLException
/*      */     {
/* 1826 */       int[] updates = ps.executeBatch();
/* 1827 */       for (int i = 0; i < updates.length; i++)
/*      */       {
/* 1829 */         int status = updates[i];
/* 1830 */         if ((status == 1) || (status == -2))
/*      */           continue;
/* 1832 */         String msg = "Each command in the batch should update exactly 1 row but one of the commands updated " + updates[i] + " rows.";
/*      */
/* 1836 */         throw new EJBException(msg);
/*      */       }
/*      */     }
/* 1817 */   };
/*      */
/* 1842 */   private static final CommitStrategy NON_BATCH_UPDATE = new CommitStrategy()
/*      */   {
/*      */     public void executeUpdate(PreparedStatement ps) throws SQLException
/*      */     {
/* 1846 */       int rows = ps.executeUpdate();
/* 1847 */       if (rows != 1)
/*      */       {
/* 1849 */         throw new EJBException("Expected one updated row but got: " + rows);
/*      */       }
/*      */     }
/*      */
/*      */     public void executeBatch(PreparedStatement ps)
/*      */     {
/*      */     }
/* 1842 */   };
/*      */
/*      */   public EntityTable(JDBCEntityMetaData metadata, JDBCEntityBridge2 entity, Schema schema, int tableId)
/*      */     throws DeploymentException
/*      */   {
/*      */     try
/*      */     {
/*  122 */       InitialContext ic = new InitialContext();
/*  123 */       this.dataSource = ((DataSource)ic.lookup(metadata.getDataSourceName()));
/*      */     }
/*      */     catch (NamingException e)
/*      */     {
/*  127 */       throw new DeploymentException("Filed to lookup: " + metadata.getDataSourceName(), e);
/*      */     }
/*      */
/*  130 */     this.entity = entity;
/*  131 */     this.tableName = SQLUtil.fixTableName(metadata.getDefaultTableName(), this.dataSource);
/*  132 */     this.log = Logger.getLogger(getClass().getName() + "." + this.tableName);
/*      */
/*  134 */     this.schema = schema;
/*  135 */     this.tableId = tableId;
/*      */
/*  137 */     EntityMetaData entityMetaData = (EntityMetaData)entity.getContainer().getBeanMetaData();
/*  138 */     ConfigurationMetaData containerConf = entityMetaData.getContainerConfiguration();
/*  139 */     this.dontFlushCreated = containerConf.isInsertAfterEjbPostCreate();
/*      */
/*  142 */     Element cacheConf = containerConf.getContainerCacheConf();
/*  143 */     Element cachePolicy = cacheConf == null ? null : MetaData.getOptionalChild(cacheConf, "cache-policy-conf");
/*      */     int maxCapacity;
/*      */     int minCapacity;
/*      */     int maxCapacity;
/*  147 */     if (cachePolicy != null)
/*      */     {
/*  149 */       String str = MetaData.getOptionalChildContent(cachePolicy, "min-capacity");
/*  150 */       int minCapacity = str == null ? 1000 : Integer.parseInt(str);
/*  151 */       str = MetaData.getOptionalChildContent(cachePolicy, "max-capacity");
/*  152 */       maxCapacity = str == null ? 10000 : Integer.parseInt(str);
/*      */     }
/*      */     else
/*      */     {
/*  156 */       minCapacity = 1000;
/*  157 */       maxCapacity = 10000;
/*      */     }
/*      */
/*  160 */     Element otherConf = cacheConf == null ? null : MetaData.getOptionalChild(cacheConf, "cache-policy-conf-other");
/*      */     boolean invalidable;
/*      */     int partitionsTotal;
/*      */     Element batchCommitStrategy;
/*      */     boolean invalidable;
/*  165 */     if (otherConf != null)
/*      */     {
/*  167 */       String str = MetaData.getOptionalChildContent(otherConf, "partitions");
/*  168 */       int partitionsTotal = str == null ? 10 : Integer.parseInt(str);
/*  169 */       Element batchCommitStrategy = MetaData.getOptionalChild(otherConf, "batch-commit-strategy");
/*  170 */       invalidable = MetaData.getOptionalChild(otherConf, "invalidable") != null;
/*      */     }
/*      */     else
/*      */     {
/*  174 */       partitionsTotal = 10;
/*  175 */       batchCommitStrategy = null;
/*  176 */       invalidable = false;
/*      */     }
/*      */
/*  179 */     if (cachePolicy != null)
/*      */     {
/*  181 */       this.cache = new PartitionedTableCache(minCapacity, maxCapacity, partitionsTotal);
/*      */
/*  183 */       String periodStr = MetaData.getOptionalChildContent(cachePolicy, "overager-period");
/*  184 */       String maxAgeStr = MetaData.getOptionalChildContent(cachePolicy, "max-bean-age");
/*  185 */       if (((periodStr != null) && (maxAgeStr == null)) || ((maxAgeStr != null) && (periodStr == null)))
/*      */       {
/*  187 */         throw new DeploymentException("Failed to initialize age-out thread for entity " + entity.getEntityName() + ": overager-period or max-bean-age is missing!");
/*      */       }
/*      */
/*  191 */       if ((periodStr != null) && (maxAgeStr != null))
/*      */       {
/*  193 */         long period = Long.parseLong(periodStr);
/*  194 */         long maxAge = Long.parseLong(maxAgeStr);
/*  195 */         ((PartitionedTableCache)this.cache).initOverager(period, maxAge, entity.getEntityName() + " overager");
/*      */
/*  197 */         if (this.log.isTraceEnabled())
/*      */         {
/*  199 */           this.log.trace("initialized age-out thread for " + entity.getEntityName() + ": overager-period=" + period + ", max-bean-age=" + maxAge);
/*      */         }
/*      */
/*      */       }
/*      */
/*  204 */       MBeanServer server = MBeanServerLocator.locateJBoss();
/*  205 */       this.serviceController = ((ServiceControllerMBean)MBeanProxyExt.create(ServiceControllerMBean.class, ServiceControllerMBean.OBJECT_NAME, server));
/*      */       try
/*      */       {
/*  211 */         this.cacheName = new ObjectName("jboss.cmp:service=tablecache,ejbname=" + metadata.getName() + ",table=" + this.tableName);
/*      */
/*  213 */         server.registerMBean(this.cache, this.cacheName);
/*  214 */         this.serviceController.create(this.cacheName);
/*      */       }
/*      */       catch (Exception e)
/*      */       {
/*  218 */         throw new DeploymentException("Failed to register table cache for " + this.tableName, e);
/*      */       }
/*      */     }
/*      */     else
/*      */     {
/*  223 */       this.cache = Cache.NONE;
/*      */     }
/*      */
/*  226 */     if (invalidable)
/*      */     {
/*  228 */       String groupName = entityMetaData.getDistributedCacheInvalidationConfig().getInvalidationGroupName();
/*  229 */       String imName = entityMetaData.getDistributedCacheInvalidationConfig().getInvalidationManagerName();
/*      */
/*  231 */       InvalidationManagerMBean im = (InvalidationManagerMBean)Registry.lookup(imName);
/*  232 */       InvalidationGroup invalidationGroup = im.getInvalidationGroup(groupName);
/*      */
/*  234 */       this.cacheInvalidator = new CacheInvalidator(this.cache, entity.getContainer().getTransactionManager(), invalidationGroup);
/*      */     }
/*      */
/*  237 */     if (batchCommitStrategy == null)
/*      */     {
/*  239 */       this.insertStrategy = NON_BATCH_UPDATE;
/*  240 */       this.deleteStrategy = NON_BATCH_UPDATE;
/*  241 */       this.updateStrategy = NON_BATCH_UPDATE;
/*      */     }
/*      */     else
/*      */     {
/*  245 */       this.log.debug("batch-commit-strategy enabled");
/*  246 */       this.insertStrategy = BATCH_UPDATE;
/*  247 */       this.deleteStrategy = BATCH_UPDATE;
/*  248 */       this.updateStrategy = BATCH_UPDATE;
/*      */     }
/*      */   }
/*      */
/*      */   public void start() throws DeploymentException
/*      */   {
/*  254 */     JDBCAbstractCMRFieldBridge[] cmrFields = this.entity.getCMRFields();
/*  255 */     this.relationsTotal = (cmrFields != null ? cmrFields.length : 0);
/*      */
/*  257 */     JDBCCMPFieldBridge2[] pkFields = (JDBCCMPFieldBridge2[])(JDBCCMPFieldBridge2[])this.entity.getPrimaryKeyFields();
/*  258 */     JDBCCMPFieldBridge2[] tableFields = (JDBCCMPFieldBridge2[])(JDBCCMPFieldBridge2[])this.entity.getTableFields();
/*      */
/*  261 */     this.deleteSql = ("delete from " + this.tableName + " where ");
/*  262 */     this.deleteSql = (this.deleteSql + pkFields[0].getColumnName() + "=?");
/*  263 */     for (int i = 1; i < pkFields.length; i++)
/*      */     {
/*  265 */       this.deleteSql = (this.deleteSql + " and " + pkFields[i].getColumnName() + "=?");
/*      */     }
/*  267 */     this.log.debug("delete sql: " + this.deleteSql);
/*      */
/*  270 */     this.insertSql = ("insert into " + this.tableName + "(");
/*  271 */     this.insertSql += tableFields[0].getColumnName();
/*  272 */     for (int i = 1; i < tableFields.length; i++)
/*      */     {
/*  274 */       this.insertSql = (this.insertSql + ", " + tableFields[i].getColumnName());
/*      */     }
/*  276 */     this.insertSql += ") values (?";
/*  277 */     for (int i = 1; i < tableFields.length; i++)
/*      */     {
/*  279 */       this.insertSql += ", ?";
/*      */     }
/*  281 */     this.insertSql += ")";
/*  282 */     this.log.debug("insert sql: " + this.insertSql);
/*      */
/*  285 */     this.updateSql = ("update " + this.tableName + " set ");
/*  286 */     int setFields = 0;
/*  287 */     for (int i = 0; i < tableFields.length; i++)
/*      */     {
/*  289 */       JDBCCMPFieldBridge2 field = tableFields[i];
/*  290 */       if (field.isPrimaryKeyMember())
/*      */         continue;
/*  292 */       if (setFields++ > 0)
/*      */       {
/*  294 */         this.updateSql += ", ";
/*      */       }
/*  296 */       this.updateSql = (this.updateSql + field.getColumnName() + "=?");
/*      */     }
/*      */
/*  299 */     this.updateSql += " where ";
/*  300 */     this.updateSql = (this.updateSql + pkFields[0].getColumnName() + "=?");
/*  301 */     for (int i = 1; i < pkFields.length; i++)
/*      */     {
/*  303 */       this.updateSql = (this.updateSql + " and " + pkFields[i].getColumnName() + "=?");
/*      */     }
/*      */
/*  306 */     if (this.entity.getVersionField() != null)
/*      */     {
/*  308 */       this.updateSql = (this.updateSql + " and " + this.entity.getVersionField().getColumnName() + "=?");
/*      */     }
/*  310 */     this.log.debug("update sql: " + this.updateSql);
/*      */
/*  313 */     String selectColumns = tableFields[0].getColumnName();
/*  314 */     for (int i = 1; i < tableFields.length; i++)
/*      */     {
/*  316 */       JDBCCMPFieldBridge2 field = tableFields[i];
/*  317 */       selectColumns = selectColumns + ", " + field.getColumnName();
/*      */     }
/*      */
/*  320 */     String whereColumns = pkFields[0].getColumnName() + "=?";
/*  321 */     for (int i = 1; i < pkFields.length; i++)
/*      */     {
/*  323 */       whereColumns = whereColumns + " and " + pkFields[i].getColumnName() + "=?";
/*      */     }
/*      */
/*  326 */     if (this.entity.getMetaData().hasRowLocking())
/*      */     {
/*  328 */       JDBCEntityPersistenceStore manager = this.entity.getManager();
/*  329 */       JDBCTypeFactory typeFactory = manager.getJDBCTypeFactory();
/*  330 */       JDBCTypeMappingMetaData typeMapping = typeFactory.getTypeMapping();
/*  331 */       JDBCFunctionMappingMetaData rowLockingTemplate = typeMapping.getRowLockingTemplate();
/*  332 */       if (rowLockingTemplate == null)
/*      */       {
/*  334 */         throw new DeploymentException("Row locking template is not defined for mapping: " + typeMapping.getName());
/*      */       }
/*      */
/*  337 */       this.selectSql = rowLockingTemplate.getFunctionSql(new Object[] { selectColumns, this.tableName, whereColumns, null }, new StringBuffer()).toString();
/*      */     }
/*      */     else
/*      */     {
/*  342 */       this.selectSql = "select ";
/*  343 */       this.selectSql += selectColumns;
/*  344 */       this.selectSql = (this.selectSql + " from " + this.tableName + " where ");
/*  345 */       this.selectSql += whereColumns;
/*      */     }
/*  347 */     this.log.debug("select sql: " + this.selectSql);
/*      */
/*  350 */     if (this.dontFlushCreated)
/*      */     {
/*  352 */       this.duplicatePkSql = "select ";
/*  353 */       this.duplicatePkSql += pkFields[0].getColumnName();
/*  354 */       for (int i = 1; i < pkFields.length; i++)
/*      */       {
/*  356 */         this.duplicatePkSql = (this.duplicatePkSql + ", " + pkFields[i].getColumnName());
/*      */       }
/*  358 */       this.duplicatePkSql = (this.duplicatePkSql + " from " + this.tableName + " where ");
/*  359 */       this.duplicatePkSql = (this.duplicatePkSql + pkFields[0].getColumnName() + "=?");
/*  360 */       for (int i = 1; i < pkFields.length; i++)
/*      */       {
/*  362 */         this.duplicatePkSql = (this.duplicatePkSql + " and " + pkFields[i].getColumnName() + "=?");
/*      */       }
/*  364 */       this.log.debug("duplicate pk sql: " + this.duplicatePkSql);
/*      */     }
/*      */
/*  367 */     if (this.cacheName != null)
/*      */     {
/*      */       try
/*      */       {
/*  371 */         this.serviceController.start(this.cacheName);
/*      */       }
/*      */       catch (Exception e)
/*      */       {
/*  375 */         throw new DeploymentException("Failed to start table cache.", e);
/*      */       }
/*      */     }
/*      */   }
/*      */
/*      */   public void stop() throws Exception
/*      */   {
/*  382 */     if (this.cacheInvalidator != null)
/*      */     {
/*  384 */       this.cacheInvalidator.unregister();
/*      */     }
/*      */
/*  387 */     if (this.cacheName != null)
/*      */     {
/*  389 */       this.serviceController.stop(this.cacheName);
/*  390 */       this.serviceController.destroy(this.cacheName);
/*  391 */       this.serviceController.remove(this.cacheName);
/*      */     }
/*  393 */     this.serviceController = null;
/*      */   }
/*      */
/*      */   public StringBuffer appendColumnNames(JDBCCMPFieldBridge2[] fields, String alias, StringBuffer buf)
/*      */   {
/*  398 */     for (int i = 0; i < fields.length; i++)
/*      */     {
/*  400 */       if (i > 0)
/*      */       {
/*  402 */         buf.append(", ");
/*      */       }
/*      */
/*  405 */       if (alias != null)
/*      */       {
/*  407 */         buf.append(alias).append(".");
/*      */       }
/*      */
/*  410 */       buf.append(fields[i].getColumnName());
/*      */     }
/*      */
/*  413 */     return buf;
/*      */   }
/*      */
/*      */   public void addField()
/*      */   {
/*  418 */     this.fieldsTotal += 1;
/*      */   }
/*      */
/*      */   public int addVersionField()
/*      */   {
/*  423 */     return this.fieldsTotal++;
/*      */   }
/*      */
/*      */   public ForeignKeyConstraint addFkConstraint(JDBCCMPFieldBridge2[] fkFields, EntityTable referenced)
/*      */   {
/*  428 */     addReference(referenced);
/*  429 */     referenced.addReferencedBy(this);
/*      */
/*  431 */     if (this.fkConstraints == null)
/*      */     {
/*  433 */       this.fkConstraints = new ForeignKeyConstraint[1];
/*      */     }
/*      */     else
/*      */     {
/*  437 */       ForeignKeyConstraint[] tmp = this.fkConstraints;
/*  438 */       this.fkConstraints = new ForeignKeyConstraint[tmp.length + 1];
/*  439 */       System.arraycopy(tmp, 0, this.fkConstraints, 0, tmp.length);
/*      */     }
/*  441 */     int fkindex = this.fkConstraints.length - 1;
/*  442 */     ForeignKeyConstraint fkc = new ForeignKeyConstraint(fkindex, fkFields);
/*  443 */     this.fkConstraints[fkindex] = fkc;
/*  444 */     return fkc;
/*      */   }
/*      */
/*      */   public DataSource getDataSource()
/*      */   {
/*  449 */     return this.dataSource;
/*      */   }
/*      */
/*      */   public Object loadRow(ResultSet rs, boolean searchableOnly)
/*      */   {
/*  454 */     View view = getView();
/*  455 */     Object pk = view.loadPk(rs);
/*  456 */     if (pk != null)
/*      */     {
/*  458 */       view.loadRow(rs, pk, searchableOnly);
/*      */     }
/*  460 */     else if (this.log.isTraceEnabled())
/*      */     {
/*  462 */       this.log.trace("loaded pk is null.");
/*      */     }
/*  464 */     return pk;
/*      */   }
/*      */
/*      */   public Row getRow(Object id)
/*      */   {
/*  469 */     return getView().getRow(id);
/*      */   }
/*      */
/*      */   public boolean hasRow(Object id)
/*      */   {
/*  474 */     return getView().hasRow(id);
/*      */   }
/*      */
/*      */   public Row loadRow(Object id) throws SQLException
/*      */   {
/*  479 */     View view = getView();
/*      */
/*  481 */     Row row = view.getRowByPk(id, false);
/*  482 */     if (row != null)
/*      */     {
/*  484 */       if (this.log.isTraceEnabled())
/*      */       {
/*  486 */         this.log.trace("row is already loaded: pk=" + id);
/*      */       }
/*  488 */       return row;
/*      */     }
/*      */
/*  491 */     JDBCCMPFieldBridge2[] pkFields = (JDBCCMPFieldBridge2[])(JDBCCMPFieldBridge2[])this.entity.getPrimaryKeyFields();
/*      */
/*  493 */     Connection con = null;
/*  494 */     PreparedStatement ps = null;
/*  495 */     ResultSet rs = null;
/*      */     try
/*      */     {
/*  498 */       if (this.log.isDebugEnabled())
/*      */       {
/*  500 */         this.log.debug("executing sql: " + this.selectSql);
/*      */       }
/*      */
/*  503 */       con = this.dataSource.getConnection();
/*  504 */       ps = con.prepareStatement(this.selectSql);
/*      */
/*  506 */       int paramInd = 1;
/*  507 */       for (i = 0; i < pkFields.length; i++)
/*      */       {
/*  509 */         JDBCCMPFieldBridge2 pkField = pkFields[i];
/*  510 */         Object pkValue = pkField.getPrimaryKeyValue(id);
/*  511 */         paramInd = pkField.setArgumentParameters(ps, paramInd, pkValue);
/*      */       }
/*      */
/*  514 */       rs = ps.executeQuery();
/*      */
/*  516 */       if (!rs.next())
/*      */       {
/*  518 */         throw new NoSuchEntityException("Row not found: " + id);
/*      */       }
/*      */
/*  521 */       i = view.loadRow(rs, id, false);
/*      */     }
/*      */     catch (SQLException e)
/*      */     {
/*      */       int i;
/*  525 */       this.log.error("Failed to load row: table=" + this.tableName + ", pk=" + id);
/*  526 */       throw e;
/*      */     }
/*      */     finally
/*      */     {
/*  530 */       JDBCUtil.safeClose(rs);
/*  531 */       JDBCUtil.safeClose(ps);
/*  532 */       JDBCUtil.safeClose(con);
/*      */     }
/*      */   }
/*      */
/*      */   public int getTableId()
/*      */   {
/*  540 */     return this.tableId;
/*      */   }
/*      */
/*      */   public String getTableName()
/*      */   {
/*  545 */     return this.tableName;
/*      */   }
/*      */
/*      */   public Table.View createView(Transaction tx)
/*      */   {
/*  550 */     return new View(tx);
/*      */   }
/*      */
/*      */   private void addReference(EntityTable table)
/*      */   {
/*  557 */     boolean wasRegistered = false;
/*  558 */     if (this.references != null)
/*      */     {
/*  560 */       for (int i = 0; i < this.references.length; i++)
/*      */       {
/*  562 */         if (this.references[i] != table.getTableId())
/*      */           continue;
/*  564 */         wasRegistered = true;
/*  565 */         break;
/*      */       }
/*      */
/*  569 */       if (!wasRegistered)
/*      */       {
/*  571 */         int[] tmp = this.references;
/*  572 */         this.references = new int[this.references.length + 1];
/*  573 */         System.arraycopy(tmp, 0, this.references, 0, tmp.length);
/*  574 */         this.references[tmp.length] = table.getTableId();
/*      */       }
/*      */     }
/*      */     else
/*      */     {
/*  579 */       this.references = new int[1];
/*  580 */       this.references[0] = table.getTableId();
/*      */     }
/*      */
/*  583 */     if (!wasRegistered)
/*      */     {
/*  585 */       if (this.log.isTraceEnabled())
/*      */       {
/*  587 */         this.log.trace("references " + table.getTableName());
/*      */       }
/*      */     }
/*      */   }
/*      */
/*      */   private void addReferencedBy(EntityTable table)
/*      */   {
/*  594 */     boolean wasRegistered = false;
/*  595 */     if (this.referencedBy != null)
/*      */     {
/*  597 */       for (int i = 0; i < this.referencedBy.length; i++)
/*      */       {
/*  599 */         if (this.referencedBy[i] != table.getTableId())
/*      */           continue;
/*  601 */         wasRegistered = true;
/*  602 */         break;
/*      */       }
/*      */
/*  606 */       if (!wasRegistered)
/*      */       {
/*  608 */         int[] tmp = this.referencedBy;
/*  609 */         this.referencedBy = new int[this.referencedBy.length + 1];
/*  610 */         System.arraycopy(tmp, 0, this.referencedBy, 0, tmp.length);
/*  611 */         this.referencedBy[tmp.length] = table.getTableId();
/*      */       }
/*      */     }
/*      */     else
/*      */     {
/*  616 */       this.referencedBy = new int[1];
/*  617 */       this.referencedBy[0] = table.getTableId();
/*      */     }
/*      */
/*  620 */     if (!wasRegistered)
/*      */     {
/*  622 */       if (this.log.isTraceEnabled())
/*      */       {
/*  624 */         this.log.trace("referenced by " + table.getTableName());
/*      */       }
/*      */     }
/*      */   }
/*      */
/*      */   private void delete(View view) throws SQLException
/*      */   {
/*  631 */     JDBCCMPFieldBridge2[] pkFields = (JDBCCMPFieldBridge2[])(JDBCCMPFieldBridge2[])this.entity.getPrimaryKeyFields();
/*      */
/*  633 */     Connection con = null;
/*  634 */     PreparedStatement ps = null;
/*      */     try
/*      */     {
/*  637 */       if (this.log.isDebugEnabled())
/*      */       {
/*  639 */         this.log.debug("executing : " + this.deleteSql);
/*      */       }
/*      */
/*  642 */       con = this.dataSource.getConnection();
/*  643 */       ps = con.prepareStatement(this.deleteSql);
/*      */
/*  645 */       int batchCount = 0;
/*  646 */       while (view.deleted != null)
/*      */       {
/*  648 */         Row row = view.deleted;
/*      */
/*  650 */         int paramInd = 1;
/*  651 */         for (int pkInd = 0; pkInd < pkFields.length; pkInd++)
/*      */         {
/*  653 */           JDBCCMPFieldBridge2 pkField = pkFields[pkInd];
/*  654 */           Object fieldValue = row.fields[pkField.getRowIndex()];
/*  655 */           paramInd = pkField.setArgumentParameters(ps, paramInd, fieldValue);
/*      */         }
/*      */
/*  658 */         this.deleteStrategy.executeUpdate(ps);
/*      */
/*  660 */         batchCount++;
/*  661 */         row.flushStatus();
/*      */       }
/*      */
/*  664 */       this.deleteStrategy.executeBatch(ps);
/*      */
/*  666 */       if (view.deleted != null)
/*      */       {
/*  668 */         throw new IllegalStateException("There are still rows to delete!");
/*      */       }
/*      */
/*  671 */       if (this.log.isTraceEnabled())
/*      */       {
/*  673 */         this.log.trace("deleted rows: " + batchCount);
/*      */       }
/*      */     }
/*      */     catch (SQLException e)
/*      */     {
/*  678 */       this.log.error("Failed to delete view: " + e.getMessage(), e);
/*  679 */       throw e;
/*      */     }
/*      */     finally
/*      */     {
/*  683 */       JDBCUtil.safeClose(ps);
/*  684 */       JDBCUtil.safeClose(con);
/*      */     }
/*      */   }
/*      */
/*      */   private void update(View view) throws SQLException
/*      */   {
/*  690 */     JDBCCMPFieldBridge2[] tableFields = (JDBCCMPFieldBridge2[])(JDBCCMPFieldBridge2[])this.entity.getTableFields();
/*  691 */     JDBCCMPFieldBridge2[] pkFields = (JDBCCMPFieldBridge2[])(JDBCCMPFieldBridge2[])this.entity.getPrimaryKeyFields();
/*      */
/*  693 */     Connection con = null;
/*  694 */     PreparedStatement ps = null;
/*      */     try
/*      */     {
/*  697 */       if (this.log.isDebugEnabled())
/*      */       {
/*  699 */         this.log.debug("executing : " + this.updateSql);
/*      */       }
/*      */
/*  702 */       con = this.dataSource.getConnection();
/*  703 */       ps = con.prepareStatement(this.updateSql);
/*      */
/*  705 */       int batchCount = 0;
/*  706 */       while (view.dirty != null)
/*      */       {
/*  708 */         Row row = view.dirty;
/*      */
/*  710 */         int paramInd = 1;
/*  711 */         for (int fInd = 0; fInd < tableFields.length; fInd++)
/*      */         {
/*  713 */           JDBCCMPFieldBridge2 field = tableFields[fInd];
/*  714 */           if (field.isPrimaryKeyMember())
/*      */             continue;
/*  716 */           Object fieldValue = row.fields[field.getRowIndex()];
/*  717 */           paramInd = field.setArgumentParameters(ps, paramInd, fieldValue);
/*      */         }
/*      */
/*  721 */         for (int fInd = 0; fInd < pkFields.length; fInd++)
/*      */         {
/*  723 */           JDBCCMPFieldBridge2 pkField = pkFields[fInd];
/*  724 */           Object fieldValue = row.fields[pkField.getRowIndex()];
/*  725 */           paramInd = pkField.setArgumentParameters(ps, paramInd, fieldValue);
/*      */         }
/*      */
/*  728 */         JDBCCMPFieldBridge2 versionField = this.entity.getVersionField();
/*  729 */         if (versionField != null)
/*      */         {
/*  731 */           int versionIndex = versionField.getVersionIndex();
/*  732 */           Object curVersion = row.fields[versionIndex];
/*  733 */           paramInd = versionField.setArgumentParameters(ps, paramInd, curVersion);
/*      */
/*  735 */           Object newVersion = row.fields[versionField.getRowIndex()];
/*  736 */           row.fields[versionIndex] = newVersion;
/*      */         }
/*      */
/*  739 */         this.updateStrategy.executeUpdate(ps);
/*      */
/*  741 */         batchCount++;
/*  742 */         row.flushStatus();
/*      */       }
/*      */
/*  745 */       this.updateStrategy.executeBatch(ps);
/*      */
/*  747 */       if (this.log.isTraceEnabled())
/*      */       {
/*  749 */         this.log.trace("updated rows: " + batchCount);
/*      */       }
/*      */     }
/*      */     catch (SQLException e)
/*      */     {
/*  754 */       this.log.error("Failed to update: table=" + this.tableName, e);
/*  755 */       throw e;
/*      */     }
/*      */     finally
/*      */     {
/*  759 */       JDBCUtil.safeClose(ps);
/*  760 */       JDBCUtil.safeClose(con);
/*      */     }
/*      */   }
/*      */
/*      */   private void insert(View view) throws SQLException
/*      */   {
/*  766 */     JDBCCMPFieldBridge2[] tableFields = (JDBCCMPFieldBridge2[])(JDBCCMPFieldBridge2[])this.entity.getTableFields();
/*  767 */     Connection con = null;
/*  768 */     PreparedStatement ps = null;
/*      */     try
/*      */     {
/*  771 */       if (this.log.isDebugEnabled())
/*      */       {
/*  773 */         this.log.debug("executing : " + this.insertSql);
/*      */       }
/*      */
/*  776 */       con = this.dataSource.getConnection();
/*  777 */       ps = con.prepareStatement(this.insertSql);
/*      */
/*  779 */       int batchCount = 0;
/*  780 */       while (view.created != null)
/*      */       {
/*  782 */         Row row = view.created;
/*      */
/*  784 */         int paramInd = 1;
/*  785 */         for (int fInd = 0; fInd < tableFields.length; fInd++)
/*      */         {
/*  787 */           JDBCCMPFieldBridge2 field = tableFields[fInd];
/*  788 */           Object fieldValue = row.fields[field.getRowIndex()];
/*  789 */           paramInd = field.setArgumentParameters(ps, paramInd, fieldValue);
/*      */         }
/*      */
/*  792 */         this.insertStrategy.executeUpdate(ps);
/*      */
/*  794 */         batchCount++;
/*  795 */         row.flushStatus();
/*      */       }
/*      */
/*  798 */       this.insertStrategy.executeBatch(ps);
/*      */
/*  800 */       if (this.log.isTraceEnabled())
/*      */       {
/*  802 */         this.log.trace("inserted rows: " + batchCount);
/*      */       }
/*      */     }
/*      */     catch (SQLException e)
/*      */     {
/*  807 */       this.log.error("Failed to insert new rows: " + e.getMessage(), e);
/*  808 */       throw e;
/*      */     }
/*      */     finally
/*      */     {
/*  812 */       JDBCUtil.safeClose(ps);
/*  813 */       JDBCUtil.safeClose(con);
/*      */     }
/*      */   }
/*      */
/*      */   private View getView()
/*      */   {
/*  819 */     return (View)this.schema.getView(this);
/*      */   }
/*      */
/*      */   public class ForeignKeyConstraint
/*      */   {
/*      */     public final int index;
/*      */     private final String nullFkSql;
/*      */
/*      */     public ForeignKeyConstraint(int index, JDBCCMPFieldBridge2[] fkFields)
/*      */     {
/* 1865 */       this.index = index;
/*      */
/* 1867 */       StringBuffer buf = new StringBuffer();
/* 1868 */       buf.append("update ").append(EntityTable.this.tableName).append(" set ").append(fkFields[0].getColumnName()).append("=null");
/*      */
/* 1870 */       for (int i = 1; i < fkFields.length; i++)
/*      */       {
/* 1872 */         buf.append(", ").append(fkFields[i].getColumnName()).append("=null");
/*      */       }
/*      */
/* 1875 */       buf.append(" where ");
/* 1876 */       JDBCCMPFieldBridge2[] pkFields = (JDBCCMPFieldBridge2[])(JDBCCMPFieldBridge2[])EntityTable.this.entity.getPrimaryKeyFields();
/* 1877 */       buf.append(pkFields[0].getColumnName()).append("=?");
/* 1878 */       for (int i = 1; i < pkFields.length; i++)
/*      */       {
/* 1880 */         buf.append(" and ").append(pkFields[i].getColumnName()).append("=?");
/*      */       }
/*      */
/* 1883 */       this.nullFkSql = buf.toString();
/* 1884 */       if (EntityTable.this.log.isDebugEnabled())
/*      */       {
/* 1886 */         EntityTable.this.log.debug("update foreign key sql: " + this.nullFkSql);
/*      */       }
/*      */     }
/*      */   }
/*      */
/*      */   public static abstract interface CommitStrategy
/*      */   {
/*      */     public abstract void executeUpdate(PreparedStatement paramPreparedStatement)
/*      */       throws SQLException;
/*      */
/*      */     public abstract void executeBatch(PreparedStatement paramPreparedStatement)
/*      */       throws SQLException;
/*      */   }
/*      */
/*      */   public class Row
/*      */   {
/*      */     private EntityTable.View view;
/*      */     private Object pk;
/*      */     private final Object[] fields;
/*      */     private final Object[] relations;
/*      */     private byte state;
/*      */     private Row prev;
/*      */     private Row next;
/*      */     private boolean cacheUpdateScheduled;
/*      */     private Row nextCacheUpdate;
/*      */     private EntityTable.ForeignKeyConstraint[] fkUpdates;
/*      */
/*      */     public Row(EntityTable.View view)
/*      */     {
/* 1410 */       this.view = view;
/* 1411 */       this.fields = new Object[EntityTable.this.fieldsTotal];
/* 1412 */       this.relations = (EntityTable.this.relationsTotal == 0 ? null : new Object[EntityTable.this.relationsTotal]);
/* 1413 */       this.state = 0;
/*      */     }
/*      */
/*      */     public Row(EntityTable.View view, Object[] fields, Object[] relations)
/*      */     {
/* 1418 */       this.view = view;
/* 1419 */       this.fields = fields;
/* 1420 */       this.relations = relations;
/* 1421 */       this.state = 0;
/*      */     }
/*      */
/*      */     public Object getPk()
/*      */     {
/* 1426 */       return this.pk;
/*      */     }
/*      */
/*      */     public void loadCachedRelations(int index, Cache.CacheLoader loader)
/*      */     {
/* 1431 */       if (this.relations != null)
/*      */       {
/* 1433 */         Object cached = this.relations[index];
/* 1434 */         this.relations[index] = loader.loadFromCache(cached);
/*      */       }
/*      */     }
/*      */
/*      */     public void cacheRelations(int index, Cache.CacheLoader loader)
/*      */     {
/* 1440 */       this.relations[index] = loader.getCachedValue();
/* 1441 */       scheduleCacheUpdate();
/*      */     }
/*      */
/*      */     public void insert(Object pk) throws DuplicateKeyException
/*      */     {
/* 1446 */       this.pk = pk;
/* 1447 */       this.view.addCreated(this);
/*      */     }
/*      */
/*      */     public Object getFieldValue(int i)
/*      */     {
/* 1452 */       if (this.state == 8)
/*      */       {
/* 1454 */         throw new NoSuchObjectLocalException("The instance was removed: " + this.pk);
/*      */       }
/*      */
/* 1457 */       Object value = this.fields[i];
/* 1458 */       if (value == EntityTable.NOT_LOADED)
/*      */       {
/* 1460 */         value = loadField(i);
/*      */       }
/*      */
/* 1463 */       return value;
/*      */     }
/*      */
/*      */     public void setFieldValue(int i, Object value)
/*      */     {
/* 1468 */       this.fields[i] = value;
/*      */     }
/*      */
/*      */     public boolean isDirty()
/*      */     {
/* 1473 */       return (this.state != 1) && (this.state != 16);
/*      */     }
/*      */
/*      */     public void setDirty()
/*      */     {
/* 1478 */       if ((this.state == 1) || (this.state == 16))
/*      */       {
/* 1480 */         updateState(2);
/*      */       }
/*      */     }
/*      */
/*      */     public void setDirtyRelations()
/*      */     {
/* 1486 */       if (this.state == 1)
/*      */       {
/* 1488 */         updateState(16);
/*      */       }
/*      */     }
/*      */
/*      */     public void delete()
/*      */     {
/* 1494 */       if ((this.state == 1) || (this.state == 2) || (this.state == 16))
/*      */       {
/* 1496 */         updateState(8);
/*      */       }
/* 1498 */       else if (this.state == 4)
/*      */       {
/* 1500 */         dereference();
/* 1501 */         this.state = 8;
/* 1502 */         EntityTable.View.access$2700(this.view).remove(this.pk);
/*      */       }
/* 1504 */       else if (this.state == 8)
/*      */       {
/* 1506 */         throw new IllegalStateException("The row is already deleted: pk=" + this.pk);
/*      */       }
/*      */     }
/*      */
/*      */     public void nullForeignKey(EntityTable.ForeignKeyConstraint constraint)
/*      */     {
/* 1512 */       if (this.fkUpdates == null)
/*      */       {
/* 1514 */         this.fkUpdates = new EntityTable.ForeignKeyConstraint[EntityTable.this.fkConstraints.length];
/* 1515 */         this.view.addRowWithNullFk(this);
/*      */       }
/*      */
/* 1518 */       this.fkUpdates[constraint.index] = constraint;
/*      */     }
/*      */
/*      */     public void nonNullForeignKey(EntityTable.ForeignKeyConstraint constraint)
/*      */     {
/* 1523 */       if (this.fkUpdates != null)
/*      */       {
/* 1525 */         this.fkUpdates[constraint.index] = null;
/*      */       }
/*      */     }
/*      */
/*      */     private void flushStatus()
/*      */     {
/* 1531 */       if ((this.state == 4) || (this.state == 2))
/*      */       {
/* 1533 */         updateState(1);
/*      */       }
/* 1535 */       else if (this.state == 8)
/*      */       {
/* 1537 */         dereference();
/*      */       }
/* 1539 */       else if (this.state == 16)
/*      */       {
/* 1541 */         updateState(1);
/*      */       }
/*      */
/* 1544 */       scheduleCacheUpdate();
/*      */     }
/*      */
/*      */     private void scheduleCacheUpdate()
/*      */     {
/* 1549 */       if (!this.cacheUpdateScheduled)
/*      */       {
/* 1551 */         if (EntityTable.View.access$2800(this.view) == null)
/*      */         {
/* 1553 */           EntityTable.View.access$2802(this.view, this);
/*      */         }
/*      */         else
/*      */         {
/* 1557 */           this.nextCacheUpdate = EntityTable.View.access$2800(this.view);
/* 1558 */           EntityTable.View.access$2802(this.view, this);
/*      */         }
/* 1560 */         this.cacheUpdateScheduled = true;
/*      */       }
/*      */     }
/*      */
/*      */     private void updateState(byte state)
/*      */     {
/* 1566 */       dereference();
/*      */
/* 1568 */       if (state == 1)
/*      */       {
/* 1570 */         if (EntityTable.View.access$2900(this.view) != null)
/*      */         {
/* 1572 */           this.next = EntityTable.View.access$2900(this.view);
/* 1573 */           EntityTable.View.access$2900(this.view).prev = this;
/*      */         }
/* 1575 */         EntityTable.View.access$2902(this.view, this);
/*      */       }
/* 1577 */       else if (state == 2)
/*      */       {
/* 1579 */         if (EntityTable.View.access$300(this.view) != null)
/*      */         {
/* 1581 */           this.next = EntityTable.View.access$300(this.view);
/* 1582 */           EntityTable.View.access$300(this.view).prev = this;
/*      */         }
/* 1584 */         EntityTable.View.access$302(this.view, this);
/*      */       }
/* 1586 */       else if (state == 4)
/*      */       {
/* 1588 */         if (EntityTable.View.access$400(this.view) != null)
/*      */         {
/* 1590 */           this.next = EntityTable.View.access$400(this.view);
/* 1591 */           EntityTable.View.access$400(this.view).prev = this;
/*      */         }
/* 1593 */         EntityTable.View.access$402(this.view, this);
/*      */       }
/* 1595 */       else if (state == 8)
/*      */       {
/* 1597 */         if (EntityTable.View.access$000(this.view) != null)
/*      */         {
/* 1599 */           this.next = EntityTable.View.access$000(this.view);
/* 1600 */           EntityTable.View.access$000(this.view).prev = this;
/*      */         }
/* 1602 */         EntityTable.View.access$002(this.view, this);
/*      */       }
/* 1604 */       else if (state == 16)
/*      */       {
/* 1606 */         if (EntityTable.View.access$3000(this.view) != null)
/*      */         {
/* 1608 */           this.next = EntityTable.View.access$3000(this.view);
/* 1609 */           EntityTable.View.access$3000(this.view).prev = this;
/*      */         }
/* 1611 */         EntityTable.View.access$3002(this.view, this);
/*      */       }
/*      */       else
/*      */       {
/* 1615 */         throw new IllegalStateException("Can't update to state: " + state);
/*      */       }
/*      */
/* 1618 */       this.state = state;
/*      */     }
/*      */
/*      */     private void dereference()
/*      */     {
/* 1623 */       if ((this.state == 1) && (EntityTable.View.access$2900(this.view) == this))
/*      */       {
/* 1625 */         EntityTable.View.access$2902(this.view, this.next);
/*      */       }
/* 1627 */       else if ((this.state == 2) && (EntityTable.View.access$300(this.view) == this))
/*      */       {
/* 1629 */         EntityTable.View.access$302(this.view, this.next);
/*      */       }
/* 1631 */       else if ((this.state == 4) && (EntityTable.View.access$400(this.view) == this))
/*      */       {
/* 1633 */         EntityTable.View.access$402(this.view, this.next);
/*      */       }
/* 1635 */       else if ((this.state == 8) && (EntityTable.View.access$000(this.view) == this))
/*      */       {
/* 1637 */         EntityTable.View.access$002(this.view, this.next);
/*      */       }
/* 1639 */       else if ((this.state == 16) && (EntityTable.View.access$3000(this.view) == this))
/*      */       {
/* 1641 */         EntityTable.View.access$3002(this.view, this.next);
/*      */       }
/*      */
/* 1644 */       if (this.next != null)
/*      */       {
/* 1646 */         this.next.prev = this.prev;
/*      */       }
/*      */
/* 1649 */       if (this.prev != null)
/*      */       {
/* 1651 */         this.prev.next = this.next;
/*      */       }
/*      */
/* 1654 */       this.prev = null;
/* 1655 */       this.next = null;
/*      */     }
/*      */
/*      */     public void flush()
/*      */       throws SQLException, DuplicateKeyException
/*      */     {
/* 1662 */       if (this.state != 4)
/*      */       {
/* 1664 */         if (EntityTable.this.log.isTraceEnabled())
/*      */         {
/* 1666 */           EntityTable.this.log.trace("The row is already inserted: pk=" + this.pk);
/*      */         }
/* 1668 */         return;
/*      */       }
/*      */
/* 1671 */       Connection con = null;
/* 1672 */       PreparedStatement duplicatePkPs = null;
/* 1673 */       PreparedStatement insertPs = null;
/* 1674 */       ResultSet rs = null;
/*      */       try
/*      */       {
/* 1678 */         con = EntityTable.this.dataSource.getConnection();
/*      */
/* 1706 */         if (EntityTable.this.log.isDebugEnabled())
/*      */         {
/* 1708 */           EntityTable.this.log.debug("executing : " + EntityTable.this.insertSql);
/*      */         }
/*      */
/* 1711 */         insertPs = con.prepareStatement(EntityTable.this.insertSql);
/*      */
/* 1713 */         int paramInd = 1;
/* 1714 */         JDBCCMPFieldBridge2[] tableFields = (JDBCCMPFieldBridge2[])(JDBCCMPFieldBridge2[])EntityTable.this.entity.getTableFields();
/* 1715 */         for (int fInd = 0; fInd < tableFields.length; fInd++)
/*      */         {
/* 1717 */           JDBCCMPFieldBridge2 field = tableFields[fInd];
/* 1718 */           Object fieldValue = this.fields[field.getRowIndex()];
/* 1719 */           paramInd = field.setArgumentParameters(insertPs, paramInd, fieldValue);
/*      */         }
/*      */
/* 1722 */         insertPs.executeUpdate();
/*      */
/* 1724 */         flushStatus();
/*      */       }
/*      */       catch (SQLException e)
/*      */       {
/* 1728 */         EntityTable.this.log.error("Failed to insert new rows: " + e.getMessage(), e);
/* 1729 */         throw e;
/*      */       }
/*      */       finally
/*      */       {
/* 1733 */         JDBCUtil.safeClose(rs);
/* 1734 */         JDBCUtil.safeClose(duplicatePkPs);
/* 1735 */         JDBCUtil.safeClose(insertPs);
/* 1736 */         JDBCUtil.safeClose(con);
/*      */       }
/*      */     }
/*      */
/*      */     private Object loadField(int i)
/*      */     {
/* 1742 */       JDBCCMPFieldBridge2 field = (JDBCCMPFieldBridge2)EntityTable.this.entity.getFields().get(i);
/*      */
/* 1744 */       StringBuffer query = new StringBuffer();
/* 1745 */       query.append("select ").append(field.getColumnName()).append(" from ").append(EntityTable.this.tableName).append(" where ");
/*      */
/* 1751 */       JDBCCMPFieldBridge2[] pkFields = (JDBCCMPFieldBridge2[])(JDBCCMPFieldBridge2[])EntityTable.this.entity.getPrimaryKeyFields();
/* 1752 */       for (int pkI = 0; pkI < pkFields.length; pkI++)
/*      */       {
/* 1754 */         if (pkI > 0)
/*      */         {
/* 1756 */           query.append(" and ");
/*      */         }
/* 1758 */         query.append(pkFields[pkI].getColumnName()).append("=?");
/*      */       }
/*      */
/* 1761 */       if (EntityTable.this.log.isDebugEnabled())
/*      */       {
/* 1763 */         EntityTable.this.log.debug("executing: " + query.toString());
/*      */       }
/*      */
/* 1766 */       Object value = null;
/* 1767 */       Connection con = null;
/* 1768 */       PreparedStatement ps = null;
/* 1769 */       ResultSet rs = null;
/*      */       try
/*      */       {
/* 1773 */         con = EntityTable.this.dataSource.getConnection();
/* 1774 */         ps = con.prepareStatement(query.toString());
/*      */
/* 1776 */         for (int pkI = 0; pkI < pkFields.length; pkI++)
/*      */         {
/* 1778 */           JDBCCMPFieldBridge2 pkField = pkFields[pkI];
/* 1779 */           Object fieldValue = this.fields[pkField.getRowIndex()];
/* 1780 */           pkField.setArgumentParameters(ps, pkI + 1, fieldValue);
/*      */         }
/*      */
/* 1783 */         rs = ps.executeQuery();
/*      */
/* 1785 */         if (!rs.next())
/*      */         {
/* 1787 */           throw new NoSuchEntityException("Row not found: " + this.pk);
/*      */         }
/*      */
/* 1790 */         value = field.loadArgumentResults(rs, 1);
/*      */       }
/*      */       catch (SQLException e)
/*      */       {
/* 1794 */         throw new EJBException("Failed to load field " + EntityTable.this.entity.getEntityName() + "." + field.getFieldName() + ": " + e.getMessage(), e);
/*      */       }
/*      */       finally
/*      */       {
/* 1800 */         JDBCUtil.safeClose(rs);
/* 1801 */         JDBCUtil.safeClose(ps);
/* 1802 */         JDBCUtil.safeClose(con);
/*      */       }
/*      */
/* 1805 */       this.fields[field.getRowIndex()] = value;
/* 1806 */       return value;
/*      */     }
/*      */   }
/*      */
/*      */   public class View
/*      */     implements Table.View
/*      */   {
/*      */     private final Transaction tx;
/*  826 */     private Map rowByPk = new HashMap();
/*      */     private EntityTable.Row created;
/*      */     private EntityTable.Row deleted;
/*      */     private EntityTable.Row dirty;
/*      */     private EntityTable.Row dirtyRelations;
/*      */     private EntityTable.Row clean;
/*      */     private EntityTable.Row cacheUpdates;
/*      */     private List rowsWithNullFks;
/*      */     private boolean inFlush;
/*      */
/*      */     public View(Transaction tx)
/*      */     {
/*  841 */       this.tx = tx;
/*      */     }
/*      */
/*      */     public EntityTable.Row getRow(Object pk)
/*      */     {
/*      */       EntityTable.Row row;
/*      */       EntityTable.Row row;
/*  847 */       if (pk == null)
/*      */       {
/*  849 */         row = new EntityTable.Row(EntityTable.this, this);
/*      */       }
/*      */       else
/*      */       {
/*  853 */         row = getRowByPk(pk, false);
/*  854 */         if (row == null)
/*      */         {
/*  856 */           row = createCleanRow(pk);
/*      */         }
/*      */       }
/*  859 */       return row;
/*      */     }
/*      */
/*      */     public EntityTable.Row getRowByPk(Object pk, boolean required)
/*      */     {
/*  896 */       EntityTable.Row row = (EntityTable.Row)this.rowByPk.get(pk);
/*      */
/*  898 */       if (row == null) {
/*  901 */         Object[] relations = null;
/*      */         Object[] fields;
/*      */         try {
/*  904 */           EntityTable.this.cache.lock(pk);
/*      */
/*  906 */           fields = EntityTable.this.cache.getFields(pk);
/*  907 */           if ((fields != null) && (EntityTable.this.relationsTotal > 0))
/*      */           {
/*  909 */             relations = EntityTable.this.cache.getRelations(pk);
/*  910 */             if (relations == null)
/*      */             {
/*  912 */               relations = new Object[EntityTable.this.relationsTotal];
/*      */             }
/*      */           }
/*      */         }
/*      */         finally
/*      */         {
/*  918 */           EntityTable.this.cache.unlock(pk);
/*      */         }
/*      */
/*  921 */         if (fields != null)
/*      */         {
/*  923 */           row = createCleanRow(pk, fields, relations);
/*      */         }
/*      */       }
/*      */
/*  927 */       if ((row == null) && (required))
/*      */       {
/*  929 */         throw new IllegalStateException("row not found: pk=" + pk);
/*      */       }
/*      */
/*  932 */       return row;
/*      */     }
/*      */
/*      */     public void addClean(EntityTable.Row row)
/*      */     {
/*  944 */       if (this.clean != null)
/*      */       {
/*  946 */         EntityTable.Row.access$702(row, this.clean);
/*  947 */         EntityTable.Row.access$802(this.clean, row);
/*      */       }
/*      */
/*  950 */       this.clean = row;
/*  951 */       EntityTable.Row.access$902(row, 1);
/*      */
/*  953 */       this.rowByPk.put(row.pk, row);
/*      */     }
/*      */
/*      */     public void addCreated(EntityTable.Row row)
/*      */       throws DuplicateKeyException
/*      */     {
/*  963 */       if (this.created != null)
/*      */       {
/*  965 */         EntityTable.Row.access$702(row, this.created);
/*  966 */         EntityTable.Row.access$802(this.created, row);
/*      */       }
/*      */
/*  969 */       this.created = row;
/*  970 */       EntityTable.Row.access$902(row, 4);
/*      */
/*  972 */       this.rowByPk.put(row.pk, row);
/*      */
/*  974 */       JDBCCMPFieldBridge2 versionField = EntityTable.this.entity.getVersionField();
/*  975 */       if (versionField != null)
/*      */       {
/*  977 */         row.fields[versionField.getVersionIndex()] = EntityTable.Row.access$100(row)[versionField.getRowIndex()];
/*      */       }
/*      */     }
/*      */
/*      */     public EntityTable.Row loadRow(ResultSet rs, Object pk, boolean searchableOnly)
/*      */     {
/*  983 */       EntityTable.Row row = getRowByPk(pk, false);
/*  984 */       if (row != null)
/*      */       {
/*  986 */         if (EntityTable.this.log.isTraceEnabled())
/*      */         {
/*  988 */           EntityTable.this.log.trace("row is already loaded: pk=" + pk);
/*      */         }
/*  990 */         return row;
/*      */       }
/*  992 */       if (EntityTable.this.log.isTraceEnabled())
/*      */       {
/*  994 */         EntityTable.this.log.trace("reading result set: pk=" + pk);
/*      */       }
/*      */
/*  997 */       row = createCleanRow(pk);
/*  998 */       JDBCCMPFieldBridge2[] tableFields = (JDBCCMPFieldBridge2[])(JDBCCMPFieldBridge2[])EntityTable.this.entity.getTableFields();
/*      */
/* 1002 */       int rsOffset = 1;
/* 1003 */       for (int i = 0; i < tableFields.length; i++)
/*      */       {
/* 1005 */         JDBCCMPFieldBridge2 field = tableFields[i];
/* 1006 */         if ((searchableOnly) && (!field.getJDBCType().isSearchable()))
/*      */         {
/* 1008 */           row.fields[field.getRowIndex()] = EntityTable.access$1300();
/* 1009 */           rsOffset--;
/*      */         }
/*      */         else
/*      */         {
/* 1013 */           Object columnValue = field.loadArgumentResults(rs, field.getRowIndex() + rsOffset);
/* 1014 */           row.fields[field.getRowIndex()] = columnValue;
/*      */
/* 1016 */           if (field.getVersionIndex() == -1)
/*      */             continue;
/* 1018 */           row.fields[field.getVersionIndex()] = columnValue;
/*      */         }
/*      */       }
/*      */
/* 1022 */       Object[] relations = EntityTable.this.relationsTotal > 0 ? new Object[EntityTable.this.relationsTotal] : null;
/*      */       try
/*      */       {
/* 1026 */         EntityTable.this.cache.lock(row.pk);
/* 1027 */         EntityTable.this.cache.put(this.tx, row.pk, row.fields, relations);
/*      */       }
/*      */       finally
/*      */       {
/* 1031 */         EntityTable.this.cache.unlock(row.pk);
/*      */       }
/*      */
/* 1034 */       return row;
/*      */     }
/*      */
/*      */     public Object loadPk(ResultSet rs)
/*      */     {
/* 1039 */       Object pk = null;
/* 1040 */       JDBCCMPFieldBridge2[] pkFields = (JDBCCMPFieldBridge2[])(JDBCCMPFieldBridge2[])EntityTable.this.entity.getPrimaryKeyFields();
/*      */
/* 1042 */       for (int i = 0; i < pkFields.length; i++)
/*      */       {
/* 1044 */         JDBCCMPFieldBridge2 field = pkFields[i];
/*      */
/* 1046 */         Object columnValue = field.loadArgumentResults(rs, field.getRowIndex() + 1);
/* 1047 */         pk = field.setPrimaryKeyValue(pk, columnValue);
/*      */       }
/* 1049 */       return pk;
/*      */     }
/*      */
/*      */     public boolean hasRow(Object id)
/*      */     {
/* 1054 */       boolean has = this.rowByPk.containsKey(id);
/* 1055 */       if (!has)
/*      */       {
/*      */         try
/*      */         {
/* 1059 */           EntityTable.this.cache.lock(id);
/* 1060 */           has = EntityTable.this.cache.contains(this.tx, id);
/*      */         }
/*      */         finally
/*      */         {
/* 1064 */           EntityTable.this.cache.unlock(id);
/*      */         }
/*      */       }
/* 1067 */       return has;
/*      */     }
/*      */
/*      */     public void addRowWithNullFk(EntityTable.Row row)
/*      */     {
/* 1072 */       if (this.rowsWithNullFks == null)
/*      */       {
/* 1074 */         this.rowsWithNullFks = new ArrayList();
/*      */       }
/* 1076 */       this.rowsWithNullFks.add(row);
/*      */     }
/*      */
/*      */     private EntityTable.Row createCleanRow(Object pk)
/*      */     {
/* 1081 */       EntityTable.Row row = new EntityTable.Row(EntityTable.this, this);
/* 1082 */       EntityTable.Row.access$1002(row, pk);
/* 1083 */       addClean(row);
/* 1084 */       return row;
/*      */     }
/*      */
/*      */     private EntityTable.Row createCleanRow(Object pk, Object[] fields, Object[] relations)
/*      */     {
/* 1089 */       EntityTable.Row row = new EntityTable.Row(EntityTable.this, this, fields, relations);
/* 1090 */       EntityTable.Row.access$1002(row, pk);
/* 1091 */       addClean(row);
/* 1092 */       return row;
/*      */     }
/*      */
/*      */     public void flushDeleted(Schema.Views views)
/*      */       throws SQLException
/*      */     {
/* 1099 */       if (this.rowsWithNullFks != null)
/*      */       {
/* 1101 */         nullifyForeignKeys();
/* 1102 */         this.rowsWithNullFks = null;
/*      */       }
/*      */
/* 1105 */       if (this.deleted == null)
/*      */       {
/* 1107 */         if (EntityTable.this.log.isTraceEnabled())
/*      */         {
/* 1109 */           EntityTable.this.log.trace("no rows to delete");
/*      */         }
/* 1111 */         return;
/*      */       }
/*      */
/* 1114 */       if (EntityTable.this.referencedBy != null)
/*      */       {
/* 1116 */         if (this.inFlush)
/*      */         {
/* 1118 */           if (EntityTable.this.log.isTraceEnabled())
/*      */           {
/* 1120 */             EntityTable.this.log.trace("inFlush, ignoring flushDeleted");
/*      */           }
/* 1122 */           return;
/*      */         }
/*      */
/* 1125 */         this.inFlush = true;
/*      */         try
/*      */         {
/* 1129 */           for (int i = 0; i < EntityTable.this.referencedBy.length; i++)
/*      */           {
/* 1131 */             Table.View view = views.entityViews[EntityTable.this.referencedBy[i]];
/* 1132 */             if (view == null)
/*      */               continue;
/* 1134 */             view.flushDeleted(views);
/*      */           }
/*      */
/*      */         }
/*      */         finally
/*      */         {
/* 1140 */           this.inFlush = false;
/*      */         }
/*      */       }
/*      */
/* 1144 */       EntityTable.this.delete(this);
/*      */     }
/*      */
/*      */     public void flushCreated(Schema.Views views) throws SQLException
/*      */     {
/* 1149 */       if ((this.created == null) || (EntityTable.this.dontFlushCreated))
/*      */       {
/* 1151 */         if (EntityTable.this.log.isTraceEnabled())
/*      */         {
/* 1153 */           EntityTable.this.log.trace("no rows to insert");
/*      */         }
/* 1155 */         return;
/*      */       }
/*      */
/* 1158 */       if (EntityTable.this.references != null)
/*      */       {
/* 1160 */         if (this.inFlush)
/*      */         {
/* 1162 */           if (EntityTable.this.log.isTraceEnabled())
/*      */           {
/* 1164 */             EntityTable.this.log.trace("inFlush, ignorning flushCreated");
/*      */           }
/* 1166 */           return;
/*      */         }
/* 1168 */         if (EntityTable.this.log.isTraceEnabled())
/*      */         {
/* 1170 */           EntityTable.this.log.trace("flushing created references");
/*      */         }
/*      */
/* 1173 */         this.inFlush = true;
/*      */         try
/*      */         {
/* 1176 */           for (int i = 0; i < EntityTable.this.references.length; i++)
/*      */           {
/* 1178 */             Table.View view = views.entityViews[EntityTable.this.references[i]];
/* 1179 */             if (view == null)
/*      */               continue;
/* 1181 */             view.flushCreated(views);
/*      */           }
/*      */
/*      */         }
/*      */         finally
/*      */         {
/* 1187 */           this.inFlush = false;
/*      */         }
/*      */       }
/*      */
/* 1191 */       EntityTable.this.insert(this);
/*      */     }
/*      */
/*      */     public void flushUpdated() throws SQLException
/*      */     {
/* 1196 */       if (this.dirtyRelations != null)
/*      */       {
/* 1198 */         while (this.dirtyRelations != null)
/*      */         {
/* 1200 */           EntityTable.Row row = this.dirtyRelations;
/* 1201 */           row.flushStatus();
/*      */         }
/*      */       }
/*      */
/* 1205 */       if (this.dirty == null)
/*      */       {
/* 1207 */         if (EntityTable.this.log.isTraceEnabled())
/*      */         {
/* 1209 */           EntityTable.this.log.trace("no rows to update");
/*      */         }
/* 1211 */         return;
/*      */       }
/*      */
/* 1214 */       EntityTable.this.update(this);
/*      */     }
/*      */
/*      */     public void beforeCompletion()
/*      */     {
/*      */     }
/*      */
/*      */     public void committed()
/*      */     {
/* 1249 */       if (this.cacheUpdates != null)
/*      */       {
/* 1251 */         EntityTable.Row cursor = this.cacheUpdates;
/*      */
/* 1253 */         while (cursor != null)
/*      */         {
/* 1257 */           EntityTable.this.cache.lock(cursor.pk);
/*      */           try
/*      */           {
/* 1260 */             switch (cursor.state)
/*      */             {
/*      */             case 1:
/* 1263 */               EntityTable.this.cache.put(this.tx, cursor.pk, cursor.fields, cursor.relations);
/* 1264 */               break;
/*      */             case 8:
/*      */               try
/*      */               {
/* 1268 */                 EntityTable.this.cache.remove(this.tx, cursor.pk);
/*      */               }
/*      */               catch (Cache.RemoveException e)
/*      */               {
/* 1272 */                 EntityTable.this.log.warn(e.getMessage());
/*      */               }
/*      */
/*      */             default:
/* 1276 */               throw new IllegalStateException("Unexpected row state: table=" + EntityTable.this.entity.getQualifiedTableName() + ", pk=" + cursor.pk + ", state=" + cursor.state);
/*      */             }
/*      */
/*      */           }
/*      */           finally
/*      */           {
/* 1283 */             EntityTable.this.cache.unlock(cursor.pk);
/*      */           }
/*      */
/* 1287 */           cursor = cursor.nextCacheUpdate;
/*      */         }
/*      */       }
/*      */     }
/*      */
/*      */     public void rolledback()
/*      */     {
/*      */     }
/*      */
/*      */     private void nullifyForeignKeys()
/*      */       throws SQLException
/*      */     {
/* 1327 */       if (EntityTable.this.log.isTraceEnabled())
/*      */       {
/* 1329 */         EntityTable.this.log.trace("nullifying foreign keys");
/*      */       }
/*      */
/* 1332 */       Connection con = null;
/* 1333 */       PreparedStatement[] ps = new PreparedStatement[EntityTable.this.fkConstraints.length];
/*      */       try
/*      */       {
/* 1337 */         JDBCCMPFieldBridge2[] pkFields = (JDBCCMPFieldBridge2[])(JDBCCMPFieldBridge2[])EntityTable.this.entity.getPrimaryKeyFields();
/* 1338 */         con = EntityTable.this.dataSource.getConnection();
/*      */
/* 1340 */         for (int i = 0; i < this.rowsWithNullFks.size(); i++)
/*      */         {
/* 1342 */           EntityTable.Row row = (EntityTable.Row)this.rowsWithNullFks.get(i);
/* 1343 */           if (row.state == 8)
/*      */             continue;
/* 1345 */           EntityTable.ForeignKeyConstraint[] cons = row.fkUpdates;
/* 1346 */           for (int c = 0; c < EntityTable.this.fkConstraints.length; c++)
/*      */           {
/* 1348 */             if (cons[c] == null)
/*      */               continue;
/* 1350 */             PreparedStatement s = ps[c];
/* 1351 */             if (s == null)
/*      */             {
/* 1353 */               if (EntityTable.this.log.isDebugEnabled())
/*      */               {
/* 1355 */                 EntityTable.this.log.debug("nullifying fk: " + cons[c].nullFkSql);
/*      */               }
/* 1357 */               s = con.prepareStatement(cons[c].nullFkSql);
/* 1358 */               ps[c] = s;
/*      */             }
/*      */
/* 1361 */             int paramInd = 1;
/* 1362 */             for (int fInd = 0; fInd < pkFields.length; fInd++)
/*      */             {
/* 1364 */               JDBCCMPFieldBridge2 pkField = pkFields[fInd];
/* 1365 */               Object fieldValue = row.fields[pkField.getRowIndex()];
/* 1366 */               paramInd = pkField.setArgumentParameters(s, paramInd, fieldValue);
/*      */             }
/*      */
/* 1369 */             int affected = s.executeUpdate();
/* 1370 */             if (affected == 1)
/*      */               continue;
/* 1372 */             throw new EJBException("Affected " + affected + " rows while expected just one");
/*      */           }
/*      */
/*      */         }
/*      */
/*      */       }
/*      */       finally
/*      */       {
/* 1381 */         for (int i = 0; i < ps.length; i++)
/*      */         {
/* 1383 */           JDBCUtil.safeClose(ps[i]);
/*      */         }
/* 1385 */         JDBCUtil.safeClose(con);
/*      */       }
/*      */     }
/*      */   }
/*      */ }

/* Location:           /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name:     org.jboss.ejb.plugins.cmp.jdbc2.schema.EntityTable
* JD-Core Version:    0.6.0
*/
TOP

Related Classes of org.jboss.ejb.plugins.cmp.jdbc2.schema.EntityTable$View

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.