private static void upgradeExternals(SVNSqlJetDb sDb, File wcRootAbsPath) throws SVNException {
    SVNSqlJetStatement stmt = sDb.getStatement(SVNWCDbStatements.SELECT_EXTERNAL_PROPERTIES);
    SVNSqlJetStatement addStmt = sDb.getStatement(SVNWCDbStatements.INSERT_EXTERNAL);

    /* ### For this intermediate upgrade we just assume WC_ID = 1.
    ### Before this bump we lost track of externals all the time, so lets keep this easy. */
    stmt.bindf("is", 1, "");
    try {
      while (stmt.next()) {
        SVNProperties props = stmt.getColumnProperties(SVNWCDbSchema.NODES__Fields.properties);
        String externalsValues = props.getStringValue(SVNProperty.EXTERNALS);
        File localRelPath =
            SVNFileUtil.createFilePath(
                stmt.getColumnString(SVNWCDbSchema.NODES__Fields.properties));
        File localAbsPath = SVNFileUtil.createFilePath(wcRootAbsPath, localRelPath);

        if (externalsValues != null) {
          SVNExternal[] externalDefs = SVNExternal.parseExternals(localAbsPath, externalsValues);
          for (SVNExternal externalDef : externalDefs) {
            File externalPath = SVNFileUtil.createFilePath(localAbsPath, externalDef.getPath());

            /* Insert dummy externals definitions: Insert an unknown external, to make sure it will be cleaned up when it is not
            updated on the next update. */
            addStmt.bindf(
                "isssssis",
                1, /* wc_id*/
                SVNFileUtil.getFilePath(externalPath),
                SVNFileUtil.getFilePath(SVNFileUtil.getFileDir(externalPath)),
                "normal",
                "unknown",
                SVNFileUtil.getFilePath(localRelPath),
                1, /* repos_id */
                "" /* repos_relpath */);
            addStmt.exec();
          }
        }
      }
    } finally {
      stmt.reset();
    }
  }
  private static void migrateTreeConflictData(SVNSqlJetDb sDb) throws SVNException {
    SVNSqlJetStatement stmt =
        new SVNSqlJetSelectFieldsStatement<SVNWCDbSchema.ACTUAL_NODE__Fields>(
            sDb, SVNWCDbSchema.ACTUAL_NODE) {
          protected void defineFields() {
            fields.add(SVNWCDbSchema.ACTUAL_NODE__Fields.wc_id);
            fields.add(SVNWCDbSchema.ACTUAL_NODE__Fields.local_relpath);
            fields.add(SVNWCDbSchema.ACTUAL_NODE__Fields.tree_conflict_data);
          }

          protected boolean isFilterPassed() throws SVNException {
            return !isColumnNull(SVNWCDbSchema.ACTUAL_NODE__Fields.tree_conflict_data);
          }
        };
    /* Iterate over each node which has a set of tree conflicts, then insert all of them into the new schema.  */
    try {
      while (stmt.next()) {
        migrateSingleTreeConflictData(
            sDb,
            stmt.getColumnString(SVNWCDbSchema.ACTUAL_NODE__Fields.tree_conflict_data),
            stmt.getColumnLong(SVNWCDbSchema.ACTUAL_NODE__Fields.wc_id),
            SVNFileUtil.createFilePath(
                stmt.getColumnString(SVNWCDbSchema.ACTUAL_NODE__Fields.local_relpath)));
      }
    } finally {
      stmt.reset();
    }

    /* Erase all the old tree conflict data.  */
    stmt =
        new SVNSqlJetUpdateStatement(sDb, SVNWCDbSchema.ACTUAL_NODE) {
          public Map<String, Object> getUpdateValues() throws SVNException {
            Map<String, Object> rowValues = getRowValues();
            rowValues.put(SVNWCDbSchema.ACTUAL_NODE__Fields.tree_conflict_data.toString(), null);
            return rowValues;
          }
        };
    try {
      stmt.exec();
    } finally {
      stmt.reset();
    }
  }
  private static void migrateSingleTreeConflictData(
      SVNSqlJetDb sDb, String treeConflictData, long wcId, File localRelPath) throws SVNException {
    Map conflicts = SVNTreeConflictUtil.readTreeConflicts(localRelPath, treeConflictData);
    for (Iterator keys = conflicts.keySet().iterator(); keys.hasNext(); ) {
      File entryPath = (File) keys.next();
      SVNTreeConflictDescription conflict = (SVNTreeConflictDescription) conflicts.get(entryPath);

      // String conflictRelpath = SVNFileUtil.getFilePath(
      //      SVNFileUtil.createFilePath(localRelPath,
      // SVNFileUtil.getBasePath(conflict.getPath())));

      /* See if we need to update or insert an ACTUAL node. */
      SVNSqlJetStatement stmt = sDb.getStatement(SVNWCDbStatements.SELECT_ACTUAL_NODE);
      stmt.bindf("is", wcId, conflict.getPath());

      boolean haveRow = false;
      try {
        haveRow = stmt.next();
      } finally {
        stmt.reset();
      }

      if (haveRow) {
        /* There is an existing ACTUAL row, so just update it. */
        stmt = sDb.getStatement(SVNWCDbStatements.UPDATE_ACTUAL_CONFLICT_DATA);
      } else {
        /* We need to insert an ACTUAL row with the tree conflict data. */
        stmt = sDb.getStatement(SVNWCDbStatements.INSERT_ACTUAL_CONFLICT_DATA);
      }

      stmt.bindf(
          "iss", wcId, conflict.getPath(), SVNTreeConflictUtil.getSingleTreeConflictData(conflict));
      if (!haveRow) stmt.bindString(4, SVNFileUtil.getFilePath(localRelPath));

      try {
        stmt.exec();
      } finally {
        stmt.reset();
      }
    }
  }
Example #4
0
  private long commit() throws SVNException {
    long oldRev = myFSFS.getYoungestRevision();

    if (myTxn.getBaseRevision() != oldRev) {
      SVNErrorMessage err =
          SVNErrorMessage.create(SVNErrorCode.FS_TXN_OUT_OF_DATE, "Transaction out of date");
      SVNErrorManager.error(err, SVNLogType.FSFS);
    }

    verifyLocks();

    final String startNodeId;
    final String startCopyId;
    if (myFSFS.getDBFormat() < FSFS.MIN_NO_GLOBAL_IDS_FORMAT) {
      String[] ids = myFSFS.getNextRevisionIDs();
      startNodeId = ids[0];
      startCopyId = ids[1];
    } else {
      startNodeId = null;
      startCopyId = null;
    }

    final long newRevision = oldRev + 1;
    final OutputStream protoFileOS = null;
    final FSID newRootId = null;
    final FSTransactionRoot txnRoot = getTxnRoot();
    FSWriteLock txnWriteLock = FSWriteLock.getWriteLockForTxn(myTxn.getTxnId(), myFSFS);
    synchronized (txnWriteLock) {
      try {
        // start transaction.
        txnWriteLock.lock();
        final File revisionPrototypeFile = txnRoot.getTransactionProtoRevFile();
        final long offset = revisionPrototypeFile.length();
        if (myFSFS.getRepositoryCacheManager() != null) {
          myFSFS
              .getRepositoryCacheManager()
              .runWriteTransaction(
                  new IFSSqlJetTransaction() {
                    public void run() throws SVNException {
                      commit(
                          startNodeId,
                          startCopyId,
                          newRevision,
                          protoFileOS,
                          newRootId,
                          txnRoot,
                          revisionPrototypeFile,
                          offset);
                    }
                  });
        } else {
          commit(
              startNodeId,
              startCopyId,
              newRevision,
              protoFileOS,
              newRootId,
              txnRoot,
              revisionPrototypeFile,
              offset);
        }
        File dstRevFile = myFSFS.getNewRevisionFile(newRevision);
        SVNFileUtil.rename(revisionPrototypeFile, dstRevFile);
      } finally {
        txnWriteLock.unlock();
        FSWriteLock.release(txnWriteLock);
      }
    }

    String commitTime = SVNDate.formatDate(new Date(System.currentTimeMillis()));
    SVNProperties presetRevisionProperties = myFSFS.getTransactionProperties(myTxn.getTxnId());
    if (presetRevisionProperties == null
        || !presetRevisionProperties.containsName(SVNRevisionProperty.DATE)) {
      myFSFS.setTransactionProperty(
          myTxn.getTxnId(), SVNRevisionProperty.DATE, SVNPropertyValue.create(commitTime));
    }

    File txnPropsFile = myFSFS.getTransactionPropertiesFile(myTxn.getTxnId());

    if (myFSFS.getDBFormat() < FSFS.MIN_PACKED_REVPROP_FORMAT
        || newRevision >= myFSFS.getMinUnpackedRevProp()) {
      File dstRevPropsFile = myFSFS.getNewRevisionPropertiesFile(newRevision);
      SVNFileUtil.rename(txnPropsFile, dstRevPropsFile);
    } else {
      /* Read the revprops, and commit them to the permenant sqlite db. */
      FSFile fsfProps = new FSFile(txnPropsFile);
      try {
        final SVNProperties revProperties = fsfProps.readProperties(false, true);
        final SVNSqlJetStatement stmt =
            myFSFS.getRevisionProperitesDb().getStatement(SVNWCDbStatements.FSFS_SET_REVPROP);
        try {
          stmt.insert(
              new Object[] {newRevision, SVNSkel.createPropList(revProperties.asMap()).getData()});
        } finally {
          stmt.reset();
        }
      } finally {
        fsfProps.close();
      }
    }

    try {
      txnRoot.writeFinalCurrentFile(newRevision, startNodeId, startCopyId);
    } catch (IOException ioe) {
      SVNErrorMessage err =
          SVNErrorMessage.create(SVNErrorCode.IO_ERROR, ioe.getLocalizedMessage());
      SVNErrorManager.error(err, ioe, SVNLogType.FSFS);
    }
    myFSFS.setYoungestRevisionCache(newRevision);
    myFSFS.purgeTxn(myTxn.getTxnId());
    return newRevision;
  }