void sg_wc_db__gid__delete_all_tmp(SG_context * pCtx, sg_wc_db * pDb) { sqlite3_stmt * pStmt = NULL; #if TRACE_WC_DB SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "sg_wc_db__gid__delete_all_tmp: had %d tmp gids.\n", pDb->nrTmpGids) ); #endif if (pDb->nrTmpGids == 0) return; SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("DELETE FROM tbl_gid WHERE tmp != 0")) ); SG_ERR_CHECK( sg_sqlite__step(pCtx, pStmt, SQLITE_DONE) ); SG_ERR_CHECK( sg_sqlite__finalize(pCtx, pStmt) ); pDb->nrTmpGids = 0; return; fail: SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); }
// TODO consider the possible perf benefits of changing this routine // to accept lots of changeset ids instead of just one, so it // can handle them all at once. void SG_treendx__update__multiple( SG_context* pCtx, SG_treendx* pTreeNdx, SG_stringarray* psa ) { SG_changeset* pcs = NULL; sqlite3_stmt* pStmt = NULL; SG_vhash* pvh_treepaths = NULL; SG_uint32 count_treepaths = 0; SG_uint32 count_changesets = 0; SG_uint32 ics = 0; SG_NULLARGCHECK_RETURN(psa); SG_NULLARGCHECK_RETURN(pTreeNdx); SG_ERR_CHECK( SG_stringarray__count(pCtx, psa, &count_changesets) ); SG_ERR_CHECK( sg_sqlite__exec__va(pCtx, pTreeNdx->psql, "BEGIN TRANSACTION; ") ); SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pTreeNdx->psql, &pStmt, "INSERT OR IGNORE INTO treendx (gid, strpath) VALUES (?, ?)") ); for (ics=0; ics<count_changesets; ics++) { const char* psz_hid = NULL; SG_uint32 i = 0; SG_ERR_CHECK( SG_stringarray__get_nth(pCtx, psa, ics, &psz_hid) ); SG_ERR_CHECK( SG_changeset__load_from_repo(pCtx, pTreeNdx->pRepo, psz_hid, &pcs) ); SG_ERR_CHECK( SG_changeset__get_treepaths(pCtx, pcs, &pvh_treepaths) ); if (pvh_treepaths) { SG_ERR_CHECK( SG_vhash__count(pCtx, pvh_treepaths, &count_treepaths) ); for (i=0; i<count_treepaths; i++) { const char* psz_gid = NULL; const SG_variant* pv = NULL; const char* psz_path = NULL; SG_ERR_CHECK( SG_vhash__get_nth_pair(pCtx, pvh_treepaths, i, &psz_gid, &pv) ); SG_ERR_CHECK( SG_variant__get__sz(pCtx, pv, &psz_path) ); SG_ERR_CHECK( sg_sqlite__reset(pCtx, pStmt) ); SG_ERR_CHECK( sg_sqlite__clear_bindings(pCtx, pStmt) ); SG_ERR_CHECK( sg_sqlite__bind_text(pCtx, pStmt, 1, psz_gid) ); SG_ERR_CHECK( sg_sqlite__bind_text(pCtx, pStmt, 2, psz_path) ); SG_ERR_CHECK( sg_sqlite__step(pCtx, pStmt, SQLITE_DONE) ); } } SG_CHANGESET_NULLFREE(pCtx, pcs); } SG_ERR_CHECK( sg_sqlite__nullfinalize(pCtx, &pStmt) ); SG_ERR_CHECK( sg_sqlite__exec__va(pCtx, pTreeNdx->psql, "COMMIT TRANSACTION; ") ); fail: SG_CHANGESET_NULLFREE(pCtx, pcs); }
void sg_wc_db__tne__bind_insert_and_step(SG_context * pCtx, sqlite3_stmt * pStmt, SG_uint64 uiAliasGid, SG_uint64 uiAliasGidParent, const SG_treenode_entry * pTreenodeEntry) { SG_ERR_CHECK( sg_wc_db__tne__bind_insert(pCtx, pStmt, uiAliasGid, uiAliasGidParent, pTreenodeEntry) ); SG_ERR_CHECK( sg_sqlite__step(pCtx, pStmt, SQLITE_DONE) ); fail: return; }
/** * Insert a row into the "tbl_gid" table WITH A FIXED AND KNOWN ALIAS. * We only use this for the special pseudo-gids. This overrides the * auto-increment feature on the alias_gid field. */ void sg_wc_db__gid__insert_known(SG_context * pCtx, sg_wc_db * pDb, SG_uint64 uiAliasGid, const char * pszGid) { sqlite3_stmt * pStmt = NULL; SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("INSERT OR REPLACE INTO tbl_gid ( alias_gid, gid, tmp ) VALUES (?, ?, 0)")) ); SG_ERR_CHECK( sg_sqlite__bind_int64(pCtx, pStmt, 1, uiAliasGid) ); SG_ERR_CHECK( sg_sqlite__bind_text(pCtx, pStmt, 2, pszGid) ); SG_ERR_CHECK( sg_sqlite__step(pCtx, pStmt, SQLITE_DONE) ); SG_ERR_CHECK( sg_sqlite__finalize(pCtx, pStmt) ); return; fail: SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); }
static void _sg_wc_db__gid__insert(SG_context * pCtx, sg_wc_db * pDb, const char * pszGid, SG_bool bIsTmp) { sqlite3_stmt * pStmt = NULL; SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("INSERT OR IGNORE INTO tbl_gid ( gid, tmp ) VALUES ( ?, ? )")) ); SG_ERR_CHECK( sg_sqlite__bind_text(pCtx, pStmt, 1, pszGid) ); SG_ERR_CHECK( sg_sqlite__bind_int( pCtx, pStmt, 2, bIsTmp) ); SG_ERR_CHECK( sg_sqlite__step(pCtx, pStmt, SQLITE_DONE) ); SG_ERR_CHECK( sg_sqlite__finalize(pCtx, pStmt) ); return; fail: SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); }
void sg_wc_db__branch__detach(SG_context * pCtx, sg_wc_db * pDb) { sqlite3_stmt * pStmt = NULL; #if TRACE_WC_DB SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "sg_wc_db__branch__detach:\n") ); #endif SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("INSERT OR REPLACE INTO tbl_branch ( id, name ) VALUES ( ?, ? )")) ); SG_ERR_CHECK( sg_sqlite__bind_int(pCtx, pStmt, 1, ID_KEY) ); SG_ERR_CHECK( sg_sqlite__bind_null(pCtx, pStmt, 2) ); SG_ERR_CHECK( sg_sqlite__step(pCtx, pStmt, SQLITE_DONE) ); SG_ERR_CHECK( sg_sqlite__finalize(pCtx, pStmt) ); return; fail: SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); }
/** * Attach/tie the WD to the given branch. * * We optionally validate the name (so that they can attach to * old pre-2.0 branches that allowed punctuation characters). * * We optionally verify that the branch name does/does not exist * (corresponding to --attach or --attach-new). * * We don't care one way or the other and only provide these * options as a service to the caller. You probably don't need * to use them since the caller should have already validated/verified * all this before while they were parsing the user's input. * */ void sg_wc_db__branch__attach(SG_context * pCtx, sg_wc_db * pDb, const char * pszBranchName, SG_vc_branches__check_attach_name__flags flags, SG_bool bValidateName) { sqlite3_stmt * pStmt = NULL; char * pszNormalizedBranchName = NULL; // however, we always normalize the name SG_NONEMPTYCHECK_RETURN( pszBranchName ); #if TRACE_WC_DB SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "sg_wc_db__branch__attach: [flags %d][validate %d] %s\n", (SG_uint32)flags, bValidateName, pszBranchName) ); #endif SG_ERR_CHECK( SG_vc_branches__check_attach_name(pCtx, pDb->pRepo, pszBranchName, flags, bValidateName, &pszNormalizedBranchName) ); SG_ERR_CHECK( sg_sqlite__prepare(pCtx, pDb->psql, &pStmt, ("INSERT OR REPLACE INTO tbl_branch ( id, name ) VALUES ( ?, ? )")) ); SG_ERR_CHECK( sg_sqlite__bind_int(pCtx, pStmt, 1, ID_KEY) ); // probably unnecessary since __check_attach_name should have thrown. if (pszNormalizedBranchName && *pszNormalizedBranchName) SG_ERR_CHECK( sg_sqlite__bind_text(pCtx, pStmt, 2, pszNormalizedBranchName) ); else SG_ERR_CHECK( sg_sqlite__bind_null(pCtx, pStmt, 2) ); SG_ERR_CHECK( sg_sqlite__step(pCtx, pStmt, SQLITE_DONE) ); SG_ERR_CHECK( sg_sqlite__finalize(pCtx, pStmt) ); SG_NULLFREE(pCtx, pszNormalizedBranchName); return; fail: SG_ERR_IGNORE( sg_sqlite__finalize(pCtx, pStmt) ); SG_NULLFREE(pCtx, pszNormalizedBranchName); }