1 19 20 package org.apache.cayenne.access; 21 22 import java.util.ArrayList ; 23 import java.util.Collection ; 24 import java.util.Collections ; 25 import java.util.Iterator ; 26 import java.util.List ; 27 import java.util.Map ; 28 29 import org.apache.cayenne.CayenneException; 30 import org.apache.cayenne.access.util.IteratedSelectObserver; 31 import org.apache.cayenne.map.DbEntity; 32 import org.apache.cayenne.map.DerivedDbEntity; 33 import org.apache.cayenne.query.InsertBatchQuery; 34 import org.apache.cayenne.query.Query; 35 import org.apache.cayenne.query.SQLTemplate; 36 import org.apache.cayenne.query.SelectQuery; 37 38 54 public class DataPort { 55 56 public static final int INSERT_BATCH_SIZE = 1000; 57 58 protected DataNode sourceNode; 59 protected DataNode destinationNode; 60 protected Collection entities; 61 protected boolean cleaningDestination; 62 protected DataPortDelegate delegate; 63 protected int insertBatchSize; 64 65 public DataPort() { 66 this.insertBatchSize = INSERT_BATCH_SIZE; 67 } 68 69 72 public DataPort(DataPortDelegate delegate) { 73 this.delegate = delegate; 74 } 75 76 81 public void execute() throws CayenneException { 82 if (sourceNode == null) { 84 throw new CayenneException("Can't port data, source node is null."); 85 } 86 87 if (destinationNode == null) { 88 throw new CayenneException("Can't port data, destination node is null."); 89 } 90 91 if (sourceNode == destinationNode) { 94 throw new CayenneException( 95 "Can't port data, source and target nodes are the same."); 96 } 97 98 if (entities == null || entities.isEmpty()) { 99 return; 100 } 101 102 List sorted = new ArrayList (entities); 104 destinationNode.getEntitySorter().sortDbEntities(sorted, false); 105 106 if (cleaningDestination) { 107 List entitiesInDeleteOrder = new ArrayList (sorted.size()); 109 entitiesInDeleteOrder.addAll(sorted); 110 Collections.reverse(entitiesInDeleteOrder); 111 processDelete(entitiesInDeleteOrder); 112 } 113 114 processInsert(sorted); 115 } 116 117 120 protected void processDelete(List entities) { 121 if (delegate != null) { 126 entities = delegate.willCleanData(this, entities); 127 } 128 129 if (entities == null || entities.isEmpty()) { 130 return; 131 } 132 133 QueryResult observer = new QueryResult(); 136 137 Iterator it = entities.iterator(); 139 while (it.hasNext()) { 140 DbEntity entity = (DbEntity) it.next(); 141 142 if (entity instanceof DerivedDbEntity) { 145 continue; 146 } 147 148 Query query = new SQLTemplate(entity, "DELETE FROM " 149 + entity.getFullyQualifiedName()); 150 151 if (delegate != null) { 153 query = delegate.willCleanData(this, entity, query); 154 } 155 156 observer.clear(); 158 destinationNode.performQueries(Collections.singletonList(query), observer); 159 160 if (delegate != null) { 162 int count = observer.getFirstUpdateCount(query); 164 delegate.didCleanData(this, entity, count); 165 } 166 } 167 } 168 169 172 protected void processInsert(List entities) throws CayenneException { 173 if (delegate != null) { 178 entities = delegate.willCleanData(this, entities); 179 } 180 181 if (entities == null || entities.isEmpty()) { 182 return; 183 } 184 185 IteratedSelectObserver observer = new IteratedSelectObserver(); 188 189 QueryResult insertObserver = new QueryResult(); 192 193 Iterator it = entities.iterator(); 195 while (it.hasNext()) { 196 insertObserver.clear(); 197 198 DbEntity entity = (DbEntity) it.next(); 199 200 if (entity instanceof DerivedDbEntity) { 202 continue; 203 } 204 205 SelectQuery select = new SelectQuery(entity); 206 select.setFetchingDataRows(true); 207 208 Query query = (delegate != null) ? delegate.willPortEntity( 210 this, 211 entity, 212 select) : select; 213 214 sourceNode.performQueries(Collections.singletonList(query), observer); 215 ResultIterator result = observer.getResultIterator(); 216 InsertBatchQuery insert = new InsertBatchQuery(entity, INSERT_BATCH_SIZE); 217 218 try { 219 220 int currentRow = 0; 224 225 int batchSize = insertBatchSize > 0 ? insertBatchSize : INSERT_BATCH_SIZE; 228 229 while (result.hasNextRow()) { 230 if (insertBatchSize > 0 231 && currentRow > 0 232 && currentRow % insertBatchSize == 0) { 233 destinationNode.performQueries( 236 Collections.singletonList(insert), 237 insertObserver); 238 insert = new InsertBatchQuery(entity, batchSize); 239 insertObserver.clear(); 240 } 241 242 currentRow++; 243 244 Map nextRow = result.nextDataRow(); 245 insert.add(nextRow); 246 } 247 248 if (insert.size() > 0) { 250 destinationNode.performQueries( 251 Collections.singletonList(insert), 252 insertObserver); 253 } 254 255 if (delegate != null) { 256 delegate.didPortEntity(this, entity, currentRow); 257 } 258 } 259 finally { 260 try { 261 result.close(); 263 } 264 catch (CayenneException ex) { 265 } 266 } 267 } 268 } 269 270 public Collection getEntities() { 271 return entities; 272 } 273 274 public DataNode getSourceNode() { 275 return sourceNode; 276 } 277 278 public DataNode getDestinationNode() { 279 return destinationNode; 280 } 281 282 286 public void setEntities(Collection entities) { 287 this.entities = entities; 288 } 289 290 293 public void setSourceNode(DataNode sourceNode) { 294 this.sourceNode = sourceNode; 295 } 296 297 300 public void setDestinationNode(DataNode destinationNode) { 301 this.destinationNode = destinationNode; 302 } 303 304 307 public DataPortDelegate getDelegate() { 308 return delegate; 309 } 310 311 public void setDelegate(DataPortDelegate delegate) { 312 this.delegate = delegate; 313 } 314 315 319 public boolean isCleaningDestination() { 320 return cleaningDestination; 321 } 322 323 327 public void setCleaningDestination(boolean cleaningDestination) { 328 this.cleaningDestination = cleaningDestination; 329 } 330 331 public int getInsertBatchSize() { 332 return insertBatchSize; 333 } 334 335 340 public void setInsertBatchSize(int insertBatchSize) { 341 this.insertBatchSize = insertBatchSize; 342 } 343 } 344 | Popular Tags |