Skip to content

Commit

Permalink
DB: use commits-stakeholder connection
Browse files Browse the repository at this point in the history
- instead of storing the signature of an author in the `signature` attribute of commits, a connection is used
- the frontend still uses the `signature` attribute, but it is inferred using the connection
- #145
  • Loading branch information
Nyzabes committed Aug 29, 2023
1 parent 6aff209 commit 488d14f
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 89 deletions.
2 changes: 1 addition & 1 deletion binocular.js
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ async function indexing(indexers, context, reporter, gateway, indexingThread) {
threadLog(indexingThread, 'All indexers stopped!');
return;
}
Promise.all([Commit.deduceStakeholders(), Issue.deduceStakeholders()]).then(() => {
Issue.deduceStakeholders().then(() => {
threadLog(indexingThread, 'Indexing finished');
projectStructureHelper.checkProjectStructureAndFix();
});
Expand Down
1 change: 1 addition & 0 deletions foxx/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ const queryType = new gql.GraphQLObjectType({
${limit}
RETURN stakeholder`,
}),
//TODO use stakeholders collection here
committers: {
type: new gql.GraphQLList(gql.GraphQLString),
resolve: () => {
Expand Down
11 changes: 11 additions & 0 deletions foxx/types/commit.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ module.exports = new gql.GraphQLObjectType({
signature: {
type: gql.GraphQLString,
description: "The commit author's signature",
resolve(commit) {
return db
._query(
aql`
FOR stakeholder, edge
IN INBOUND ${commit} ${commitsToStakeholders}
return stakeholder.gitSignature
`
)
.toArray()[0];
},
},
branch: {
type: gql.GraphQLString,
Expand Down
13 changes: 2 additions & 11 deletions lib/indexers/vcs/GitIndexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,14 @@ class GitIndexer {
}
log('Processing', this.counter.commits.total, 'commits');

//persist commits
//also creates (and connects) stakeholder objects from commit signature
for (const commit of commits) {
await processCommit
.bind(this)(commit, currentBranch)
.catch({ stop: true }, () => null);
}

//create stakeholder objects
await createStakeholders();

//create branch-file connections
//in the process, check which files have been renamed and store these in the branch-file-file connection
await createBranchFileConnections(this.repo);
Expand Down Expand Up @@ -451,14 +450,6 @@ function adjustStatistic(key, list, newElements) {
return emitCount;
}

async function createStakeholders() {
const commitsDAO = await Commit.findAll();
const signatures = _.uniq(commitsDAO.map((c) => c.data.signature));
for (const stakeholder of signatures) {
await Stakeholder.ensureByGitSignature(stakeholder);
}
}

async function createBranchFileConnections(repo) {
//find all branch file connections so we can skip them
const existingBranchFileConnections = await BranchFileConnection.findAll();
Expand Down
58 changes: 11 additions & 47 deletions lib/models/Commit.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,24 @@ Commit.persist = async function (repo, nCommit, urlProvider) {
}

// create new commit and link it to its parent commits
const authorSignature = nCommit.commit.author.name + ' <' + nCommit.commit.author.email + '>';
return Commit.create(
{
sha,
signature: nCommit.commit.author.name + ' <' + nCommit.commit.author.email + '>',
date: new Date(nCommit.commit.author.timestamp * 1000),
message: nCommit.commit.message,
webUrl: urlProvider ? urlProvider.getCommitUrl(sha) : '',
branch: nCommit.commit.branch,
history: history,
parents: parents,
parents: parents, //TODO can be removed since commit is connected to parents through the commits-commits connection
stats: {
additions: 0,
deletions: 0,
},
},
{ isNew: true }
).then(function (commit) {
//connect commit to parents
Promise.resolve(
parents.split(',').map((parentSha) => {
if (parentSha === '') {
Expand All @@ -71,7 +72,14 @@ Commit.persist = async function (repo, nCommit, urlProvider) {
return Commit.findById(parentSha).then((parentCommit) => commit.connect(parentCommit));
})
);
return commit;

//connect commit to author
const Stakeholder = require('./Stakeholder.js');
return Stakeholder.ensureByGitSignature(authorSignature).then((results) => {
const stakeholder = results[0];
commit.connect(stakeholder);
return commit;
});
});
});
});
Expand Down Expand Up @@ -276,48 +284,4 @@ Commit.prototype.processTree = function (repo, nCommit, currentBranch, urlProvid
);
};

/**
* create a connection for each stakeholder and all of their commits
*
* @returns {*}
*/
Commit.deduceStakeholders = async function () {
const CommitStakeholderConnection = require('./CommitStakeholderConnection.js');
const Stakeholder = require('./Stakeholder.js');

// walk through all commits
return Promise.resolve(
Commit.rawDb.query(
aql`
FOR commit IN ${Commit.collection}
LET stakeholders = (FOR stakeholder
IN
INBOUND commit ${CommitStakeholderConnection.collection}
RETURN stakeholder)
FILTER LENGTH(stakeholders) == 0
COLLECT sig = commit.signature INTO commitsPerSignature = commit
RETURN {
"signature": sig,
"commits": commitsPerSignature
}`
)
)
.then((cursor) => cursor.all())
.then((signatures) =>
signatures.forEach((signature) => {
// try to get an already existing stakeholder with that signature
return Stakeholder.ensureByGitSignature(signature.signature).then((results) => {
const stakeholder = results[0];
// walk over all commits with that signature
return signature.commits.map((rawCommit) =>
Promise.resolve(rawCommit, (commit) => {
// assign the commit to the stakeholder
return Commit.parse(commit).connect(stakeholder);
})
);
});
})
);
};

module.exports = Commit;
2 changes: 2 additions & 0 deletions test/backend/commit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const File = require('../../lib/models/File');
const Language = require('../../lib/models/Language');
const Hunk = require('../../lib/models/Hunk');
const LanguageFileConnection = require('../../lib/models/LanguageFileConnection');
const CommitStakeholderConnection = require('../../lib/models/CommitStakeholderConnection.js');

const config = require('../../lib/config.js').get();
const ctx = require('../../lib/context');
Expand Down Expand Up @@ -45,6 +46,7 @@ describe('commit', function () {
await Hunk.ensureCollection();
await Language.ensureCollection();
await LanguageFileConnection.ensureCollection();
await CommitStakeholderConnection.ensureCollection();

await fake.file(repo, 'test.js', testFile);
await helpers.commit(repo, ['test.js'], bob, 'Commit1');
Expand Down
14 changes: 7 additions & 7 deletions ui/src/database/localDB.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,23 +116,23 @@ export default class LocalDB {
}

static getCommitData(commitSpan, significantSpan) {
return Commits.getCommitData(db, commitSpan, significantSpan);
return Commits.getCommitData(db, tripleStore, commitSpan, significantSpan);
}

static getCommitDataForSha(sha) {
return Commits.getCommitDataForSha(db, sha);
return Commits.getCommitDataForSha(db, tripleStore, sha);
}

static getBuildData(commitSpan, significantSpan) {
return Builds.getBuildData(db, commitSpan, significantSpan);
}

static getIssueData(issueSpan, significantSpan) {
return Issues.getIssueData(db, issueSpan, significantSpan);
return Issues.getIssueData(db, tripleStore, issueSpan, significantSpan);
}

static getCommitsForIssue(iid) {
return Issues.getCommitsForIssue(db, iid);
return Issues.getCommitsForIssue(db, tripleStore, iid);
}

static getMergeRequestData(mergeRequestSpan, significantSpan) {
Expand Down Expand Up @@ -168,7 +168,7 @@ export default class LocalDB {
}

static getCommitDataOwnershipRiver(commitSpan, significantSpan, granularity, interval, excludeMergeCommits) {
return Commits.getCommitDataOwnershipRiver(db, commitSpan, significantSpan, granularity, interval, excludeMergeCommits);
return Commits.getCommitDataOwnershipRiver(db, tripleStore, commitSpan, significantSpan, granularity, interval, excludeMergeCommits);
}

static getBuildDataOwnershipRiver(commitSpan, significantSpan, granularity, interval) {
Expand All @@ -180,11 +180,11 @@ export default class LocalDB {
}

static getRelatedCommitDataOwnershipRiver(issue) {
return Commits.getRelatedCommitDataOwnershipRiver(db, issue);
return Commits.getRelatedCommitDataOwnershipRiver(db, tripleStore, issue);
}

static getCommitDateHistogram(granularity, dateField, since, until) {
return Commits.getCommitDateHistogram(db, granularity, dateField, since, until);
return Commits.getCommitDateHistogram(db, tripleStore, granularity, dateField, since, until);
}

static issueImpactQuery(iid, since, until) {
Expand Down
Loading

0 comments on commit 488d14f

Please sign in to comment.