File indexing completed on 2024-05-12 17:16:22
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 * http://kdesvn.alwins-world.de 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 "path.h" 0040 #include "exception.h" 0041 #include "pool.h" 0042 #include "revision.h" 0043 #include "svnqt_defines.h" 0044 #include "client_parameter.h" 0045 #include "helper.h" 0046 #include <QCoreApplication> 0047 #include <QDir> 0048 0049 0050 namespace svn 0051 { 0052 0053 struct ProplistBaton { 0054 ContextWP m_context; 0055 PathPropertiesMapListPtr resultlist; 0056 }; 0057 0058 static svn_error_t *ProplistReceiver(void *baton, const char *path, apr_hash_t *prop_hash, apr_pool_t *pool) 0059 { 0060 ProplistBaton *_baton = static_cast<ProplistBaton *>(baton); 0061 PathPropertiesMapListPtr mapList = _baton->resultlist; 0062 0063 ContextP l_context = _baton->m_context; 0064 if (!l_context) { 0065 return svn_error_create(SVN_ERR_CANCELLED, nullptr, QCoreApplication::translate("svnqt", "Cancelled by user.").toUtf8()); 0066 } 0067 svn_client_ctx_t *ctx = l_context->ctx(); 0068 if (ctx && ctx->cancel_func) { 0069 SVN_ERR(ctx->cancel_func(ctx->cancel_baton)); 0070 } 0071 0072 mapList->push_back(PathPropertiesMapEntry(QString::fromUtf8(path), svn::internal::Hash2Map(prop_hash, pool))); 0073 return SVN_NO_ERROR; 0074 } 0075 0076 PathPropertiesMapListPtr 0077 Client_impl::proplist(const Path &path, 0078 const Revision &revision, 0079 const Revision &peg, 0080 Depth depth, 0081 const StringArray &changelists) 0082 { 0083 Pool pool; 0084 0085 PathPropertiesMapListPtr path_prop_map_list = PathPropertiesMapListPtr(new PathPropertiesMapList); 0086 0087 ProplistBaton baton; 0088 baton.m_context = m_context; 0089 baton.resultlist = path_prop_map_list; 0090 // todo svn 1.8: svn_client_proplist4 0091 svn_error_t *error = 0092 svn_client_proplist3( 0093 path.cstr(), 0094 peg.revision(), 0095 revision.revision(), 0096 internal::DepthToSvn(depth), 0097 changelists.array(pool), 0098 ProplistReceiver, 0099 &baton, 0100 *m_context, 0101 pool); 0102 if (error != nullptr) { 0103 throw ClientException(error); 0104 } 0105 0106 return path_prop_map_list; 0107 } 0108 0109 QPair<qlonglong, PathPropertiesMapList> 0110 Client_impl::propget(const QString &propName, 0111 const Path &path, 0112 const Revision &revision, 0113 const Revision &peg, 0114 Depth depth, 0115 const StringArray &changelists 0116 ) 0117 { 0118 Pool pool; 0119 0120 apr_hash_t *props; 0121 svn_revnum_t actual = svn_revnum_t(-1); 0122 // todo svn 1.8: svn_client_propget5 0123 svn_error_t *error = svn_client_propget4(&props, 0124 propName.toUtf8(), 0125 path.cstr(), 0126 peg.revision(), 0127 revision.revision(), 0128 &actual, 0129 internal::DepthToSvn(depth), 0130 changelists.array(pool), 0131 *m_context, 0132 pool, 0133 pool 0134 ); 0135 0136 if (error != nullptr) { 0137 throw ClientException(error); 0138 } 0139 0140 PathPropertiesMapList path_prop_map_list; 0141 0142 apr_hash_index_t *hi; 0143 for (hi = apr_hash_first(pool, props); hi; 0144 hi = apr_hash_next(hi)) { 0145 PropertiesMap prop_map; 0146 0147 const void *key; 0148 void *val; 0149 0150 apr_hash_this(hi, &key, nullptr, &val); 0151 prop_map[propName] = QString::fromUtf8(((const svn_string_t *)val)->data); 0152 QString filename = QString::fromUtf8((const char *)key); 0153 path_prop_map_list.push_back(PathPropertiesMapEntry(filename, prop_map)); 0154 } 0155 0156 return QPair<qlonglong, PathPropertiesMapList>(actual, path_prop_map_list); 0157 } 0158 0159 void 0160 Client_impl::propset(const PropertiesParameter ¶ms) 0161 { 0162 Pool pool; 0163 const svn_string_t *propval; 0164 0165 if (params.propertyValue().isNull()) { 0166 propval = nullptr; 0167 } else { 0168 propval = svn_string_create(params.propertyValue().toUtf8(), pool); 0169 } 0170 0171 svn_error_t *error = nullptr; 0172 const QByteArray tgtTmp = params.path().cstr(); 0173 if (svn_path_is_url(tgtTmp)) { 0174 error = svn_client_propset_remote(params.propertyName().toUtf8(), 0175 propval, 0176 tgtTmp, 0177 params.skipCheck(), 0178 params.revision(), 0179 map2hash(params.revisionProperties(), pool), 0180 nullptr, // we don't need a commit info - ignore 0181 nullptr, 0182 *m_context, 0183 pool 0184 ); 0185 } else { 0186 apr_array_header_t *targets = apr_array_make(pool, 1, 0187 sizeof(const char *)); 0188 APR_ARRAY_PUSH(targets, const char *) = tgtTmp; 0189 error = svn_client_propset_local(params.propertyName().toUtf8(), 0190 propval, 0191 targets, 0192 internal::DepthToSvn(params.depth()), 0193 params.skipCheck(), 0194 params.changeList().array(pool), 0195 *m_context, 0196 pool); 0197 0198 } 0199 0200 if (error != nullptr) { 0201 throw ClientException(error); 0202 } 0203 } 0204 0205 //-------------------------------------------------------------------------------- 0206 // 0207 // revprop functions 0208 // 0209 //-------------------------------------------------------------------------------- 0210 /** 0211 * lists revision properties in @a path no matter whether local or 0212 * repository 0213 * 0214 * @param path 0215 * @param revision 0216 * @param recurse 0217 * @return PropertiesList 0218 */ 0219 QPair<qlonglong, PropertiesMap> 0220 Client_impl::revproplist(const Path &path, 0221 const Revision &revision) 0222 { 0223 Pool pool; 0224 0225 apr_hash_t *props; 0226 svn_revnum_t revnum; 0227 svn_error_t *error = 0228 svn_client_revprop_list(&props, 0229 path.cstr(), 0230 revision.revision(), 0231 &revnum, 0232 *m_context, 0233 pool); 0234 if (error != nullptr) { 0235 throw ClientException(error); 0236 } 0237 0238 PropertiesMap prop_map; 0239 0240 apr_hash_index_t *hi; 0241 for (hi = apr_hash_first(pool, props); hi; 0242 hi = apr_hash_next(hi)) { 0243 const void *key; 0244 void *val; 0245 0246 apr_hash_this(hi, &key, nullptr, &val); 0247 prop_map[ QString::fromUtf8((const char *)key) ] = QString::fromUtf8(((const svn_string_t *)val)->data); 0248 } 0249 0250 return QPair<qlonglong, PropertiesMap>(revnum, prop_map); 0251 } 0252 0253 /** 0254 * lists one revision property in @a path no matter whether local or 0255 * repository 0256 * 0257 * @param path 0258 * @param revision 0259 * @param recurse 0260 * @return PropertiesList 0261 */ 0262 0263 QPair<qlonglong, QString> 0264 Client_impl::revpropget(const QString &propName, 0265 const Path &path, 0266 const Revision &revision) 0267 { 0268 Pool pool; 0269 0270 svn_string_t *propval; 0271 svn_revnum_t revnum; 0272 svn_error_t *error = 0273 svn_client_revprop_get( 0274 propName.toUtf8(), 0275 &propval, 0276 path.cstr(), 0277 revision.revision(), 0278 &revnum, 0279 *m_context, 0280 pool); 0281 if (error != nullptr) { 0282 throw ClientException(error); 0283 } 0284 0285 // if the property does not exist NULL is returned 0286 if (propval == nullptr) { 0287 return QPair<qlonglong, QString>(0, QString()); 0288 } 0289 0290 return QPair<qlonglong, QString>(revnum, QString::fromUtf8(propval->data)); 0291 } 0292 0293 qlonglong 0294 Client_impl::revpropset(const PropertiesParameter ¶m) 0295 { 0296 Pool pool; 0297 0298 const svn_string_t *propval 0299 = param.propertyValue().isNull() ? nullptr : svn_string_create(param.propertyValue().toUtf8(), pool); 0300 0301 svn_revnum_t revnum; 0302 0303 const svn_string_t *oldpropval = param.propertyOriginalValue().isNull() ? nullptr : svn_string_create(param.propertyOriginalValue().toUtf8(), pool); 0304 svn_error_t *error = svn_client_revprop_set2( 0305 param.propertyName().toUtf8(), 0306 propval, 0307 oldpropval, 0308 param.path().cstr(), 0309 param.revision().revision(), 0310 &revnum, 0311 param.force(), 0312 *m_context, 0313 pool); 0314 0315 if (error != nullptr) { 0316 throw ClientException(error); 0317 } 0318 0319 return revnum; 0320 } 0321 0322 qlonglong 0323 Client_impl::revpropdel(const QString &propName, 0324 const Path &path, 0325 const Revision &revision) 0326 { 0327 Pool pool; 0328 0329 svn_revnum_t revnum; 0330 svn_error_t *error = 0331 svn_client_revprop_set2( 0332 propName.toUtf8(), 0333 nullptr, // value = NULL 0334 nullptr, 0335 path.cstr(), 0336 revision.revision(), 0337 &revnum, 0338 false, 0339 *m_context, 0340 pool); 0341 0342 if (error != nullptr) { 0343 throw ClientException(error); 0344 } 0345 0346 return revnum; 0347 } 0348 0349 } 0350 0351 /* ----------------------------------------------------------------- 0352 * local variables: 0353 * eval: (load-file "../../rapidsvn-dev.el") 0354 * end: 0355 */