void SG_vfile__update__vhash( SG_context* pCtx, const SG_pathname* pPath, /**< The path of the file containing the JSON text */ const char* putf8Key, const SG_vhash* pHashValue ) { SG_vfile* pvf = NULL; SG_vhash* pvh = NULL; SG_vhash* pvhCopy = NULL; SG_ERR_CHECK( SG_vfile__begin(pCtx, pPath, SG_FILE_RDWR | SG_FILE_OPEN_OR_CREATE, &pvh, &pvf) ); if (!pvh) { SG_ERR_CHECK( SG_VHASH__ALLOC(pCtx, &pvh) ); } SG_ERR_CHECK( SG_VHASH__ALLOC__COPY(pCtx, &pvhCopy, pHashValue) ); SG_ERR_CHECK( SG_vhash__update__vhash(pCtx, pvh, putf8Key, &pvhCopy) ); SG_ERR_CHECK( SG_vfile__end(pCtx, &pvf, pvh) ); SG_VHASH_NULLFREE(pCtx, pvh); return; fail: SG_ERR_IGNORE( sg_vfile__dispose(pCtx, pvf) ); SG_VHASH_NULLFREE(pCtx, pvhCopy); SG_VHASH_NULLFREE(pCtx, pvh); }
/** * We allocate the vhash pointer; caller owns thereafter */ void SG_dbrecord__to_vhash(SG_context* pCtx, SG_dbrecord* prec, SG_vhash** ppVh) { SG_NULLARGCHECK_RETURN(prec); SG_NULLARGCHECK_RETURN(ppVh); SG_ERR_CHECK_RETURN( SG_vhash__sort(pCtx, prec->pvh, SG_FALSE, SG_vhash_sort_callback__increasing) ); SG_ERR_CHECK( SG_VHASH__ALLOC__COPY(pCtx, ppVh, prec->pvh) ); return; fail: SG_VHASH_NULLFREE(pCtx, *ppVh); }
/** * Return a VHASH containing the resolve info * if there is any. * * We return NULL if there is nothing. * */ void SG_wc_tx__get_item_resolve_info(SG_context * pCtx, SG_wc_tx * pWcTx, const char * pszInput, SG_vhash ** ppvhResolveInfo) { SG_vhash * pvhResolveInfo = NULL; SG_string * pStringRepoPath = NULL; sg_wc_liveview_item * pLVI; // we do not own this SG_bool bKnown; char chDomain; SG_NULLARGCHECK_RETURN( pWcTx ); SG_NONEMPTYCHECK_RETURN( pszInput ); SG_NULLARGCHECK_RETURN( ppvhResolveInfo ); SG_ERR_CHECK( sg_wc_db__path__anything_to_repopath(pCtx, pWcTx->pDb, pszInput, SG_WC_DB__PATH__IMPORT_FLAGS__TREAT_NULL_AS_ERROR, &pStringRepoPath, &chDomain) ); #if TRACE_WC_TX_STATUS SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "SG_wc_tx__get_item_resolve_info: '%s' normalized to [domain %c] '%s'\n", pszInput, chDomain, SG_string__sz(pStringRepoPath)) ); #endif SG_ERR_CHECK( sg_wc_tx__liveview__fetch_item__domain(pCtx, pWcTx, pStringRepoPath, &bKnown, &pLVI) ); if (!bKnown) { // We only get this if the path is completely bogus and // took us off into the weeds (as opposed to reporting // something just not-controlled). SG_ERR_THROW2( SG_ERR_NOT_FOUND, (pCtx, "Unknown item '%s'.", SG_string__sz(pStringRepoPath)) ); } if (pLVI->pvhIssue && pLVI->pvhSavedResolutions) SG_ERR_CHECK( SG_VHASH__ALLOC__COPY(pCtx, &pvhResolveInfo, pLVI->pvhSavedResolutions) ); *ppvhResolveInfo = pvhResolveInfo; pvhResolveInfo = NULL; fail: SG_STRING_NULLFREE(pCtx, pStringRepoPath); SG_VHASH_NULLFREE(pCtx, pvhResolveInfo); }
void sg_vc_hooks__lookup_by_interface__single_result( SG_context* pCtx, SG_repo* pRepo, const char* psz_interface, SG_vhash** ppvh_latest_version ) { //This version will return only the hook with the largest version. //If multiple versions of the hook are defined, //all old versions will be deleted. SG_varray* pva_hooks = NULL; SG_vhash* pvh_latest_hook = NULL; SG_zingtx* pztx = NULL; char* psz_hid_cs_leaf = NULL; SG_dagnode* pdn = NULL; SG_changeset* pcs = NULL; SG_ERR_CHECK( SG_vc_hooks__lookup_by_interface( pCtx, pRepo, psz_interface, &pva_hooks ) ); if (!pva_hooks) { SG_ERR_THROW2( SG_ERR_VC_HOOK_MISSING, (pCtx, "%s", psz_interface) ); } else { SG_uint32 count = 0; SG_ERR_CHECK( SG_varray__count(pCtx, pva_hooks, &count) ); if (0 == count) { SG_ERR_THROW2( SG_ERR_VC_HOOK_MISSING, (pCtx, "%s", psz_interface) ); } else { if (count > 1) { SG_uint32 i = 0; SG_int32 nVersion = 0; SG_int32 nHighestVersion = -1; SG_int32 nAmbiguousVersion = -2; const char * hidRecToSave = NULL; const char * hidrec = NULL; SG_vhash * pvh_current_hook = NULL; //There are multiple versions installed for this hook. //delete the lesser numbered versions. for (i=0; i < count; i++) { SG_ERR_CHECK( SG_varray__get__vhash(pCtx, pva_hooks, i, &pvh_current_hook) ); SG_ERR_CHECK( SG_vhash__get__int32(pCtx, pvh_current_hook, "version", &nVersion) ); if (nVersion == nHighestVersion) { nAmbiguousVersion = nHighestVersion; } if (nVersion > nHighestVersion) { nHighestVersion = nVersion; SG_ERR_CHECK( SG_vhash__get__sz(pCtx, pvh_current_hook, "hidrec", &hidRecToSave) ); } } if (nAmbiguousVersion == nHighestVersion) SG_ERR_THROW2( SG_ERR_VC_HOOK_AMBIGUOUS, (pCtx, "%s defined multiple times at version %d", psz_interface, nHighestVersion) ); if (nHighestVersion > 0 && hidRecToSave != NULL) { SG_audit q; SG_ERR_CHECK( SG_audit__init(pCtx,&q,pRepo,SG_AUDIT__WHEN__NOW,SG_AUDIT__WHO__FROM_SETTINGS) ); SG_ERR_CHECK( SG_zing__get_leaf(pCtx, pRepo, NULL, SG_DAGNUM__VC_HOOKS, &psz_hid_cs_leaf) ); /* start a changeset */ SG_ERR_CHECK( SG_zing__begin_tx(pCtx, pRepo, SG_DAGNUM__VC_HOOKS, q.who_szUserId, psz_hid_cs_leaf, &pztx) ); SG_ERR_CHECK( SG_zingtx__add_parent(pCtx, pztx, psz_hid_cs_leaf) ); for (i=0; i < count; i++) { SG_ERR_CHECK( SG_varray__get__vhash(pCtx, pva_hooks, i, &pvh_current_hook) ); SG_ERR_CHECK( SG_vhash__get__sz(pCtx, pvh_current_hook, "hidrec", &hidrec) ); if (SG_strcmp__null(hidrec, hidRecToSave) != 0) { //This isn't the recid to save. Delete it! SG_ERR_CHECK( SG_zingtx__delete_record__hid(pCtx, pztx, "hook", hidrec) ); } } /* commit the changes */ SG_ERR_CHECK( SG_zing__commit_tx(pCtx, q.when_int64, &pztx, &pcs, &pdn, NULL) ); } } else { //There's only one hook installed return it. SG_vhash * pvh_temp = NULL; SG_ERR_CHECK( SG_varray__get__vhash(pCtx, pva_hooks, 0, &pvh_temp) ); SG_ERR_CHECK( SG_VHASH__ALLOC__COPY(pCtx, &pvh_latest_hook, pvh_temp) ); } } } SG_RETURN_AND_NULL(pvh_latest_hook, ppvh_latest_version); fail: if (pztx) { SG_ERR_IGNORE( SG_zing__abort_tx(pCtx, &pztx) ); } SG_NULLFREE(pCtx, psz_hid_cs_leaf); SG_DAGNODE_NULLFREE(pCtx, pdn); SG_CHANGESET_NULLFREE(pCtx, pcs); SG_VARRAY_NULLFREE(pCtx, pva_hooks); }