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)  );
}
示例#2
0
// 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);
}