static svn_error_t * vbindf(svn_sqlite__stmt_t *stmt, const char *fmt, va_list ap) { int count; for (count = 1; *fmt; fmt++, count++) { const void *blob; apr_size_t blob_size; switch (*fmt) { case 's': SVN_ERR(svn_sqlite__bind_text(stmt, count, va_arg(ap, const char *))); break; case 'i': SVN_ERR(svn_sqlite__bind_int64(stmt, count, va_arg(ap, apr_int64_t))); break; case 'b': blob = va_arg(ap, const void *); blob_size = va_arg(ap, apr_size_t); SVN_ERR(svn_sqlite__bind_blob(stmt, count, blob, blob_size)); break; default: SVN_ERR_MALFUNCTION(); } } return SVN_NO_ERROR; }
static svn_error_t * vbindf(svn_sqlite__stmt_t *stmt, const char *fmt, va_list ap) { int count; for (count = 1; *fmt; fmt++, count++) { const void *blob; apr_size_t blob_size; const svn_token_map_t *map; switch (*fmt) { case 's': SVN_ERR(svn_sqlite__bind_text(stmt, count, va_arg(ap, const char *))); break; case 'd': SVN_ERR(svn_sqlite__bind_int(stmt, count, va_arg(ap, int))); break; case 'i': case 'L': SVN_ERR(svn_sqlite__bind_int64(stmt, count, va_arg(ap, apr_int64_t))); break; case 'b': blob = va_arg(ap, const void *); blob_size = va_arg(ap, apr_size_t); SVN_ERR(svn_sqlite__bind_blob(stmt, count, blob, blob_size)); break; case 'r': SVN_ERR(svn_sqlite__bind_revnum(stmt, count, va_arg(ap, svn_revnum_t))); break; case 't': map = va_arg(ap, const svn_token_map_t *); SVN_ERR(svn_sqlite__bind_token(stmt, count, map, va_arg(ap, int))); break; case 'n': /* Skip this column: no binding */ break; default: SVN_ERR_MALFUNCTION(); } } return SVN_NO_ERROR; }
/* Handle the moving of a pristine from SRC_WCROOT to DST_WCROOT. The existing pristine in SRC_WCROOT is described by CHECKSUM, MD5_CHECKSUM and SIZE */ static svn_error_t * maybe_transfer_one_pristine(svn_wc__db_wcroot_t *src_wcroot, svn_wc__db_wcroot_t *dst_wcroot, const svn_checksum_t *checksum, const svn_checksum_t *md5_checksum, apr_int64_t size, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *scratch_pool) { const char *pristine_abspath; svn_sqlite__stmt_t *stmt; svn_stream_t *src_stream; svn_stream_t *dst_stream; const char *tmp_abspath; const char *src_abspath; int affected_rows; svn_error_t *err; SVN_ERR(svn_sqlite__get_statement(&stmt, dst_wcroot->sdb, STMT_INSERT_OR_IGNORE_PRISTINE)); SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, checksum, scratch_pool)); SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, scratch_pool)); SVN_ERR(svn_sqlite__bind_int64(stmt, 3, size)); SVN_ERR(svn_sqlite__update(&affected_rows, stmt)); if (affected_rows == 0) return SVN_NO_ERROR; SVN_ERR(svn_stream_open_unique(&dst_stream, &tmp_abspath, pristine_get_tempdir(dst_wcroot, scratch_pool, scratch_pool), svn_io_file_del_on_pool_cleanup, scratch_pool, scratch_pool)); SVN_ERR(get_pristine_fname(&src_abspath, src_wcroot->abspath, checksum, scratch_pool, scratch_pool)); SVN_ERR(svn_stream_open_readonly(&src_stream, src_abspath, scratch_pool, scratch_pool)); /* ### Should we verify the SHA1 or MD5 here, or is that too expensive? */ SVN_ERR(svn_stream_copy3(src_stream, dst_stream, cancel_func, cancel_baton, scratch_pool)); SVN_ERR(get_pristine_fname(&pristine_abspath, dst_wcroot->abspath, checksum, scratch_pool, scratch_pool)); /* Move the file to its target location. (If it is already there, it is * an orphan file and it doesn't matter if we overwrite it.) */ err = svn_io_file_rename2(tmp_abspath, pristine_abspath, FALSE, scratch_pool); /* Maybe the directory doesn't exist yet? */ if (err && APR_STATUS_IS_ENOENT(err->apr_err)) { svn_error_t *err2; err2 = svn_io_dir_make(svn_dirent_dirname(pristine_abspath, scratch_pool), APR_OS_DEFAULT, scratch_pool); if (err2) /* Creating directory didn't work: Return all errors */ return svn_error_trace(svn_error_compose_create(err, err2)); else /* We could create a directory: retry install */ svn_error_clear(err); SVN_ERR(svn_io_file_rename2(tmp_abspath, pristine_abspath, FALSE, scratch_pool)); } else SVN_ERR(err); return SVN_NO_ERROR; }
/* Install the pristine text described by BATON into the pristine store of * SDB. If it is already stored then just delete the new file * BATON->tempfile_abspath. * * This function expects to be executed inside a SQLite txn that has already * acquired a 'RESERVED' lock. * * Implements 'notes/wc-ng/pristine-store' section A-3(a). */ static svn_error_t * pristine_install_txn(svn_sqlite__db_t *sdb, /* The path to the source file that is to be moved into place. */ svn_stream_t *install_stream, /* The target path for the file (within the pristine store). */ const char *pristine_abspath, /* The pristine text's SHA-1 checksum. */ const svn_checksum_t *sha1_checksum, /* The pristine text's MD-5 checksum. */ const svn_checksum_t *md5_checksum, apr_pool_t *scratch_pool) { svn_sqlite__stmt_t *stmt; svn_boolean_t have_row; /* If this pristine text is already present in the store, just keep it: * delete the new one and return. */ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_PRISTINE)); SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool)); SVN_ERR(svn_sqlite__step(&have_row, stmt)); SVN_ERR(svn_sqlite__reset(stmt)); if (have_row) { #ifdef SVN_DEBUG /* Consistency checks. Verify both files exist and match. * ### We could check much more. */ { apr_finfo_t finfo1, finfo2; SVN_ERR(svn_stream__install_get_info(&finfo1, install_stream, APR_FINFO_SIZE, scratch_pool)); SVN_ERR(svn_io_stat(&finfo2, pristine_abspath, APR_FINFO_SIZE, scratch_pool)); if (finfo1.size != finfo2.size) { return svn_error_createf( SVN_ERR_WC_CORRUPT_TEXT_BASE, NULL, _("New pristine text '%s' has different size: %s versus %s"), svn_checksum_to_cstring_display(sha1_checksum, scratch_pool), apr_off_t_toa(scratch_pool, finfo1.size), apr_off_t_toa(scratch_pool, finfo2.size)); } } #endif /* Remove the temp file: it's already there */ SVN_ERR(svn_stream__install_delete(install_stream, scratch_pool)); return SVN_NO_ERROR; } /* Move the file to its target location. (If it is already there, it is * an orphan file and it doesn't matter if we overwrite it.) */ { apr_finfo_t finfo; SVN_ERR(svn_stream__install_get_info(&finfo, install_stream, APR_FINFO_SIZE, scratch_pool)); SVN_ERR(svn_stream__install_stream(install_stream, pristine_abspath, TRUE, scratch_pool)); SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_INSERT_PRISTINE)); SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool)); SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, scratch_pool)); SVN_ERR(svn_sqlite__bind_int64(stmt, 3, finfo.size)); SVN_ERR(svn_sqlite__insert(NULL, stmt)); SVN_ERR(svn_io_set_file_read_only(pristine_abspath, FALSE, scratch_pool)); } return SVN_NO_ERROR; }