1 56 package org.objectstyle.cayenne.access; 57 58 import java.util.ArrayList ; 59 import java.util.Collection ; 60 import java.util.Collections ; 61 import java.util.Iterator ; 62 import java.util.List ; 63 import java.util.Map ; 64 65 import org.objectstyle.cayenne.CayenneException; 66 import org.objectstyle.cayenne.access.util.IteratedSelectObserver; 67 import org.objectstyle.cayenne.map.DbEntity; 68 import org.objectstyle.cayenne.map.DerivedDbEntity; 69 import org.objectstyle.cayenne.query.GenericSelectQuery; 70 import org.objectstyle.cayenne.query.InsertBatchQuery; 71 import org.objectstyle.cayenne.query.Query; 72 import org.objectstyle.cayenne.query.SQLTemplate; 73 import org.objectstyle.cayenne.query.SelectQuery; 74 75 91 public class DataPort { 92 93 public static final int INSERT_BATCH_SIZE = 1000; 94 95 protected DataNode sourceNode; 96 protected DataNode destinationNode; 97 protected Collection entities; 98 protected boolean cleaningDestination; 99 protected DataPortDelegate delegate; 100 protected int insertBatchSize; 101 102 public DataPort() { 103 this.insertBatchSize = INSERT_BATCH_SIZE; 104 } 105 106 109 public DataPort(DataPortDelegate delegate) { 110 this.delegate = delegate; 111 } 112 113 118 public void execute() throws CayenneException { 119 if (sourceNode == null) { 121 throw new CayenneException("Can't port data, source node is null."); 122 } 123 124 if (destinationNode == null) { 125 throw new CayenneException("Can't port data, destination node is null."); 126 } 127 128 if (sourceNode == destinationNode) { 131 throw new CayenneException( 132 "Can't port data, source and target nodes are the same."); 133 } 134 135 if (entities == null || entities.isEmpty()) { 136 return; 137 } 138 139 List sorted = new ArrayList (entities); 141 destinationNode.getEntitySorter().sortDbEntities(sorted, false); 142 143 if (cleaningDestination) { 144 List entitiesInDeleteOrder = new ArrayList (sorted.size()); 146 entitiesInDeleteOrder.addAll(sorted); 147 Collections.reverse(entitiesInDeleteOrder); 148 processDelete(entitiesInDeleteOrder); 149 } 150 151 processInsert(sorted); 152 } 153 154 157 protected void processDelete(List entities) { 158 if (delegate != null) { 163 entities = delegate.willCleanData(this, entities); 164 } 165 166 if (entities == null || entities.isEmpty()) { 167 return; 168 } 169 170 QueryResult observer = new QueryResult(); 173 174 Iterator it = entities.iterator(); 176 while (it.hasNext()) { 177 DbEntity entity = (DbEntity) it.next(); 178 179 if (entity instanceof DerivedDbEntity) { 182 continue; 183 } 184 185 Query query = new SQLTemplate(entity, "DELETE FROM " 186 + entity.getFullyQualifiedName(), false); 187 188 if (delegate != null) { 190 query = delegate.willCleanData(this, entity, query); 191 } 192 193 observer.clear(); 195 destinationNode.performQueries(Collections.singletonList(query), observer); 196 197 if (delegate != null) { 199 int count = observer.getFirstUpdateCount(query); 201 delegate.didCleanData(this, entity, count); 202 } 203 } 204 } 205 206 209 protected void processInsert(List entities) throws CayenneException { 210 if (delegate != null) { 215 entities = delegate.willCleanData(this, entities); 216 } 217 218 if (entities == null || entities.isEmpty()) { 219 return; 220 } 221 222 IteratedSelectObserver observer = new IteratedSelectObserver(); 225 226 QueryResult insertObserver = new QueryResult(); 229 230 Iterator it = entities.iterator(); 232 while (it.hasNext()) { 233 insertObserver.clear(); 234 235 DbEntity entity = (DbEntity) it.next(); 236 237 if (entity instanceof DerivedDbEntity) { 239 continue; 240 } 241 242 SelectQuery select = new SelectQuery(entity); 243 select.setFetchingDataRows(true); 244 245 GenericSelectQuery query = (delegate != null) ? delegate.willPortEntity(this, 247 entity, 248 select) : select; 249 250 sourceNode.performQueries(Collections.singletonList(query), observer); 251 ResultIterator result = observer.getResultIterator(); 252 InsertBatchQuery insert = new InsertBatchQuery(entity, INSERT_BATCH_SIZE); 253 254 try { 255 256 int currentRow = 0; 260 261 int batchSize = insertBatchSize > 0 ? insertBatchSize : INSERT_BATCH_SIZE; 264 265 while (result.hasNextRow()) { 266 if (insertBatchSize > 0 267 && currentRow > 0 268 && currentRow % insertBatchSize == 0) { 269 destinationNode.performQueries(Collections.singletonList(insert), 272 insertObserver); 273 insert = new InsertBatchQuery(entity, batchSize); 274 insertObserver.clear(); 275 } 276 277 currentRow++; 278 279 Map nextRow = result.nextDataRow(); 280 insert.add(nextRow); 281 } 282 283 if (insert.size() > 0) { 285 destinationNode.performQueries(Collections.singletonList(insert), 286 insertObserver); 287 } 288 289 if (delegate != null) { 290 delegate.didPortEntity(this, entity, currentRow); 291 } 292 } 293 finally { 294 try { 295 result.close(); 297 } 298 catch (CayenneException ex) { 299 } 300 } 301 } 302 } 303 304 public Collection getEntities() { 305 return entities; 306 } 307 308 public DataNode getSourceNode() { 309 return sourceNode; 310 } 311 312 public DataNode getDestinationNode() { 313 return destinationNode; 314 } 315 316 320 public void setEntities(Collection entities) { 321 this.entities = entities; 322 } 323 324 327 public void setSourceNode(DataNode sourceNode) { 328 this.sourceNode = sourceNode; 329 } 330 331 334 public void setDestinationNode(DataNode destinationNode) { 335 this.destinationNode = destinationNode; 336 } 337 338 341 public DataPortDelegate getDelegate() { 342 return delegate; 343 } 344 345 public void setDelegate(DataPortDelegate delegate) { 346 this.delegate = delegate; 347 } 348 349 353 public boolean isCleaningDestination() { 354 return cleaningDestination; 355 } 356 357 361 public void setCleaningDestination(boolean cleaningDestination) { 362 this.cleaningDestination = cleaningDestination; 363 } 364 365 public int getInsertBatchSize() { 366 return insertBatchSize; 367 } 368 369 374 public void setInsertBatchSize(int insertBatchSize) { 375 this.insertBatchSize = insertBatchSize; 376 } 377 } | Popular Tags |