File indexing completed on 2024-04-28 05:42:08
0001 /* 0002 * Port for usage with qt-framework and development for kdesvn 0003 * Copyright (C) 2005-2009 by Rajko Albrecht (ral@alwins-world.de) 0004 * https://kde.org/applications/development/org.kde.kdesvn 0005 */ 0006 /* 0007 * ==================================================================== 0008 * Copyright (c) 2002-2005 The RapidSvn Group. All rights reserved. 0009 * dev@rapidsvn.tigris.org 0010 * 0011 * This library is free software; you can redistribute it and/or 0012 * modify it under the terms of the GNU Lesser General Public 0013 * License as published by the Free Software Foundation; either 0014 * version 2.1 of the License, or (at your option) any later version. 0015 * 0016 * This library is distributed in the hope that it will be useful, 0017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0019 * Lesser General Public License for more details. 0020 * 0021 * You should have received a copy of the GNU Lesser General Public 0022 * License along with this library (in the file LGPL.txt); if not, 0023 * write to the Free Software Foundation, Inc., 51 Franklin St, 0024 * Fifth Floor, Boston, MA 02110-1301 USA 0025 * 0026 * This software consists of voluntary contributions made by many 0027 * individuals. For exact contribution history, see the revision 0028 * history and logs, available at http://rapidsvn.tigris.org/. 0029 * ==================================================================== 0030 */ 0031 0032 // svncpp 0033 #include "client_impl.h" 0034 0035 // subversion api 0036 #include <svn_client.h> 0037 #include <svn_path.h> 0038 0039 #include "client_parameter.h" 0040 #include "exception.h" 0041 #include "helper.h" 0042 #include "path.h" 0043 #include "pool.h" 0044 #include "revision.h" 0045 #include "svnqt_defines.h" 0046 #include <QCoreApplication> 0047 #include <QDir> 0048 0049 namespace svn 0050 { 0051 0052 struct ProplistBaton { 0053 ContextWP m_context; 0054 PathPropertiesMapListPtr resultlist; 0055 }; 0056 0057 static svn_error_t *ProplistReceiver(void *baton, const char *path, apr_hash_t *prop_hash, apr_pool_t *pool) 0058 { 0059 ProplistBaton *_baton = static_cast<ProplistBaton *>(baton); 0060 PathPropertiesMapListPtr mapList = _baton->resultlist; 0061 0062 ContextP l_context = _baton->m_context; 0063 if (!l_context) { 0064 return svn_error_create(SVN_ERR_CANCELLED, nullptr, QCoreApplication::translate("svnqt", "Cancelled by user.").toUtf8()); 0065 } 0066 svn_client_ctx_t *ctx = l_context->ctx(); 0067 if (ctx && ctx->cancel_func) { 0068 SVN_ERR(ctx->cancel_func(ctx->cancel_baton)); 0069 } 0070 0071 mapList->push_back(PathPropertiesMapEntry(QString::fromUtf8(path), svn::internal::Hash2Map(prop_hash, pool))); 0072 return SVN_NO_ERROR; 0073 } 0074 0075 PathPropertiesMapListPtr Client_impl::proplist(const Path &path, const Revision &revision, const Revision &peg, Depth depth, const StringArray &changelists) 0076 { 0077 Pool pool; 0078 0079 PathPropertiesMapListPtr path_prop_map_list = PathPropertiesMapListPtr(new PathPropertiesMapList); 0080 0081 ProplistBaton baton; 0082 baton.m_context = m_context; 0083 baton.resultlist = path_prop_map_list; 0084 // todo svn 1.8: svn_client_proplist4 0085 svn_error_t *error = svn_client_proplist3(path.cstr(), 0086 peg.revision(), 0087 revision.revision(), 0088 internal::DepthToSvn(depth), 0089 changelists.array(pool), 0090 ProplistReceiver, 0091 &baton, 0092 *m_context, 0093 pool); 0094 if (error != nullptr) { 0095 throw ClientException(error); 0096 } 0097 0098 return path_prop_map_list; 0099 } 0100 0101 QPair<qlonglong, PathPropertiesMapList> 0102 Client_impl::propget(const QString &propName, const Path &path, const Revision &revision, const Revision &peg, Depth depth, const StringArray &changelists) 0103 { 0104 Pool pool; 0105 0106 apr_hash_t *props; 0107 svn_revnum_t actual = svn_revnum_t(-1); 0108 // todo svn 1.8: svn_client_propget5 0109 svn_error_t *error = svn_client_propget4(&props, 0110 propName.toUtf8(), 0111 path.cstr(), 0112 peg.revision(), 0113 revision.revision(), 0114 &actual, 0115 internal::DepthToSvn(depth), 0116 changelists.array(pool), 0117 *m_context, 0118 pool, 0119 pool); 0120 0121 if (error != nullptr) { 0122 throw ClientException(error); 0123 } 0124 0125 PathPropertiesMapList path_prop_map_list; 0126 0127 apr_hash_index_t *hi; 0128 for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi)) { 0129 PropertiesMap prop_map; 0130 0131 const void *key; 0132 void *val; 0133 0134 apr_hash_this(hi, &key, nullptr, &val); 0135 prop_map[propName] = QString::fromUtf8(((const svn_string_t *)val)->data); 0136 QString filename = QString::fromUtf8((const char *)key); 0137 path_prop_map_list.push_back(PathPropertiesMapEntry(filename, prop_map)); 0138 } 0139 0140 return QPair<qlonglong, PathPropertiesMapList>(actual, path_prop_map_list); 0141 } 0142 0143 void Client_impl::propset(const PropertiesParameter ¶ms) 0144 { 0145 Pool pool; 0146 const svn_string_t *propval; 0147 0148 if (params.propertyValue().isNull()) { 0149 propval = nullptr; 0150 } else { 0151 propval = svn_string_create(params.propertyValue().toUtf8(), pool); 0152 } 0153 0154 svn_error_t *error = nullptr; 0155 const QByteArray tgtTmp = params.path().cstr(); 0156 if (svn_path_is_url(tgtTmp)) { 0157 error = svn_client_propset_remote(params.propertyName().toUtf8(), 0158 propval, 0159 tgtTmp, 0160 params.skipCheck(), 0161 params.revision(), 0162 map2hash(params.revisionProperties(), pool), 0163 nullptr, // we don't need a commit info - ignore 0164 nullptr, 0165 *m_context, 0166 pool); 0167 } else { 0168 apr_array_header_t *targets = apr_array_make(pool, 1, sizeof(const char *)); 0169 APR_ARRAY_PUSH(targets, const char *) = tgtTmp; 0170 error = svn_client_propset_local(params.propertyName().toUtf8(), 0171 propval, 0172 targets, 0173 internal::DepthToSvn(params.depth()), 0174 params.skipCheck(), 0175 params.changeList().array(pool), 0176 *m_context, 0177 pool); 0178 } 0179 0180 if (error != nullptr) { 0181 throw ClientException(error); 0182 } 0183 } 0184 0185 //-------------------------------------------------------------------------------- 0186 // 0187 // revprop functions 0188 // 0189 //-------------------------------------------------------------------------------- 0190 /** 0191 * lists revision properties in @a path no matter whether local or 0192 * repository 0193 * 0194 * @param path 0195 * @param revision 0196 * @param recurse 0197 * @return PropertiesList 0198 */ 0199 QPair<qlonglong, PropertiesMap> Client_impl::revproplist(const Path &path, const Revision &revision) 0200 { 0201 Pool pool; 0202 0203 apr_hash_t *props; 0204 svn_revnum_t revnum; 0205 svn_error_t *error = svn_client_revprop_list(&props, path.cstr(), revision.revision(), &revnum, *m_context, pool); 0206 if (error != nullptr) { 0207 throw ClientException(error); 0208 } 0209 0210 PropertiesMap prop_map; 0211 0212 apr_hash_index_t *hi; 0213 for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi)) { 0214 const void *key; 0215 void *val; 0216 0217 apr_hash_this(hi, &key, nullptr, &val); 0218 prop_map[QString::fromUtf8((const char *)key)] = QString::fromUtf8(((const svn_string_t *)val)->data); 0219 } 0220 0221 return QPair<qlonglong, PropertiesMap>(revnum, prop_map); 0222 } 0223 0224 /** 0225 * lists one revision property in @a path no matter whether local or 0226 * repository 0227 * 0228 * @param path 0229 * @param revision 0230 * @param recurse 0231 * @return PropertiesList 0232 */ 0233 0234 QPair<qlonglong, QString> Client_impl::revpropget(const QString &propName, const Path &path, const Revision &revision) 0235 { 0236 Pool pool; 0237 0238 svn_string_t *propval; 0239 svn_revnum_t revnum; 0240 svn_error_t *error = svn_client_revprop_get(propName.toUtf8(), &propval, path.cstr(), revision.revision(), &revnum, *m_context, pool); 0241 if (error != nullptr) { 0242 throw ClientException(error); 0243 } 0244 0245 // if the property does not exist NULL is returned 0246 if (propval == nullptr) { 0247 return QPair<qlonglong, QString>(0, QString()); 0248 } 0249 0250 return QPair<qlonglong, QString>(revnum, QString::fromUtf8(propval->data)); 0251 } 0252 0253 qlonglong Client_impl::revpropset(const PropertiesParameter ¶m) 0254 { 0255 Pool pool; 0256 0257 const svn_string_t *propval = param.propertyValue().isNull() ? nullptr : svn_string_create(param.propertyValue().toUtf8(), pool); 0258 0259 svn_revnum_t revnum; 0260 0261 const svn_string_t *oldpropval = param.propertyOriginalValue().isNull() ? nullptr : svn_string_create(param.propertyOriginalValue().toUtf8(), pool); 0262 svn_error_t *error = svn_client_revprop_set2(param.propertyName().toUtf8(), 0263 propval, 0264 oldpropval, 0265 param.path().cstr(), 0266 param.revision().revision(), 0267 &revnum, 0268 param.force(), 0269 *m_context, 0270 pool); 0271 0272 if (error != nullptr) { 0273 throw ClientException(error); 0274 } 0275 0276 return revnum; 0277 } 0278 0279 qlonglong Client_impl::revpropdel(const QString &propName, const Path &path, const Revision &revision) 0280 { 0281 Pool pool; 0282 0283 svn_revnum_t revnum; 0284 svn_error_t *error = svn_client_revprop_set2(propName.toUtf8(), 0285 nullptr, // value = NULL 0286 nullptr, 0287 path.cstr(), 0288 revision.revision(), 0289 &revnum, 0290 false, 0291 *m_context, 0292 pool); 0293 0294 if (error != nullptr) { 0295 throw ClientException(error); 0296 } 0297 0298 return revnum; 0299 } 0300 0301 } 0302 0303 /* ----------------------------------------------------------------- 0304 * local variables: 0305 * eval: (load-file "../../rapidsvn-dev.el") 0306 * end: 0307 */