<commit_before>const data = require("../data/repos");
const mongoose = require("../db/db");

const RepositoryDAO = require("../db/dao/repo.dao");
const Promise = require("bluebird").Promise;

const graphQLClient = require("./graphql_client");

const queryPR = require("./queries/pr_query");
const queryIssue = require("./queries/issue_query");

createRepositories(data.repositories)
    .then(() => {
        console.log("All repositories successfully added to DB.");
        mongoose.disconnect();
        process.exit();
    })
    .catch(err => {
        console.error(err);
    });

function createRepositories(repos) {
    return Promise.all(repos.map(repo => {
        return createRepository(repo)
            .catch(err => {
                console.error(err);
            });
    }));
}

async function createRepository(repo) {
    const repoResult = await getPullRequests(graphQLClient, queryPR, repo);
    const pullRequests = repoResult.repository.pullRequests.edges.map(pr => mapToPullRequestModel(pr.node));
    const issues = await getIssues(repo, pullRequests);

    return storeRepository(repo, issues, pullRequests);
}

async function getIssues(repo, pullRequests) {
    let issues = [];

    for (let pr of pullRequests) {
        let issueNumbers = getIssueNumbers(pr.bodyText);

        if (issueNumbers) {
            issueNumbers.map(n => parseInt(n.substring(1))).forEach(n => {
                pr.issues.push(n);
                issues.push(getIssue(graphQLClient, queryIssue, repo, n)); //parse to int, ignore '#'
            });
        }
    }

    return Promise.all(issues);
}

/**
 * Retrieves repository information from GitHub API.
 * @param {GraphQL client for send/retrieve requests.} client 
 * @param {Query object with two properties: query() and variables.} query 
 * @param {Repository model instance.} repo 
 */
function getPullRequests(client, query, repo) {
    return client.request(query.query(repo.owner, repo.name), query.variables);
}

/**
 * Retrieves issue info for a particular repo by providing the issue number.
 * @param {GraphQL client for send/retrieve requests.} client
 * @param {Query object with two properties: query() and variables.} query
 * @param {Repository model instance.} repo
 * @param {Issue number as an Int.} issue
 */
async function getIssue(client, query, repo, issue) {
    let response = await client.request(query.query(repo.owner, repo.name, issue), query.variables);
    return mapToIssueModel(response.repository.issue);
}

/**
 * Creates DB document with repository information.
 * @param {Repository object with name, repo and url properties.} repo 
 * @param {Array of issue objects.} issues 
 * @param {Array of pull request objects.} pullRequests 
 */
function storeRepository(repo, issues, pullRequests) {
    return RepositoryDAO.createRepository(repo, issues, pullRequests);
}

/**
 * Returns the elements that match an issue number in the body text of a pull request.
 * @param {Body text of a pull request.} text 
 */
function getIssueNumbers(text) {
    return text.match(/#[0-9]+/g);
}

function mapToPullRequestModel(pr) {
    return {
        _id: pr.id,
        title: pr.title,
        bodyText: pr.bodyText,
        state: pr.state,
        issues: [],
        mergeCommit: pr.mergeCommit.abbreviatedOid,
        createdAt: pr.createdAt,
        updatedAt: pr.updatedAt
    }
}

function mapToIssueModel(issue) {
    return {
        _id: issue.number,
        state: issue.closed ? "CLOSED" : "OPEN",
        title: issue.title,
        bodyText: issue.bodyText,
        createdAt: issue.createdAt,
        updatedAt: issue.updatedAt
    }
}<commit_msg>Fix an issue where rejecting a promise blocks the results<commit_after>const data = require("../data/repos");
const mongoose = require("../db/db");

const RepositoryDAO = require("../db/dao/repo.dao");
const Promise = require("bluebird").Promise;

const graphQLClient = require("./graphql_client");

const queryPR = require("./queries/pr_query");
const queryIssue = require("./queries/issue_query");

createRepositories(data.repositories)
    .then(() => {
        console.log("All repositories successfully added to DB.");
        mongoose.disconnect();
        process.exit();
    })
    .catch(err => {
        console.error(err);
    });

function createRepositories(repos) {
    return Promise.all(repos.map(repo => {
        return createRepository(repo)
            .catch(err => {
                console.error(err);
            });
    }));
}

async function createRepository(repo) {
    const repoResult = await getPullRequests(graphQLClient, queryPR, repo);
    const pullRequests = repoResult.repository.pullRequests.edges.map(pr => mapToPullRequestModel(pr.node));
    const issues = await getIssues(repo, pullRequests);

    return storeRepository(repo, issues, pullRequests);
}

async function getIssues(repo, pullRequests) {
    let issues = [];

    for (let pr of pullRequests) {
        let issueNumbers = getIssueNumbers(pr.bodyText);

        if (issueNumbers) {
            issueNumbers.map(n => parseInt(n.substring(1))).forEach(n => {
                pr.issues.push(n);
                issues.push(getIssue(graphQLClient, queryIssue, repo, n)); //parse to int, ignore '#'
            });
        }
    }

    return Promise.all(issues.map(reflect))
        .then(results => {
            return results.filter(x => x.status === "resolved").map(x => x.result);
        });
}

/**
 * Retrieves repository information from GitHub API.
 * @param {GraphQL client for send/retrieve requests.} client 
 * @param {Query object with two properties: query() and variables.} query 
 * @param {Repository model instance.} repo 
 */
function getPullRequests(client, query, repo) {
    return client.request(query.query(repo.owner, repo.name), query.variables);
}

/**
 * Retrieves issue info for a particular repo by providing the issue number.
 * @param {GraphQL client for send/retrieve requests.} client
 * @param {Query object with two properties: query() and variables.} query
 * @param {Repository model instance.} repo
 * @param {Issue number as an Int.} issue
 */
async function getIssue(client, query, repo, issue) {
    let response = await client.request(query.query(repo.owner, repo.name, issue), query.variables);
    return mapToIssueModel(response.repository.issue);
}

/**
 * Creates DB document with repository information.
 * @param {Repository object with name, repo and url properties.} repo 
 * @param {Array of issue objects.} issues 
 * @param {Array of pull request objects.} pullRequests 
 */
function storeRepository(repo, issues, pullRequests) {
    return RepositoryDAO.createRepository(repo, issues, pullRequests);
}

/**
 * Returns the elements that match an issue number in the body text of a pull request.
 * @param {Body text of a pull request.} text 
 */
function getIssueNumbers(text) {
    return text.match(/#[0-9]+/g);
}

function reflect(promise) {
    return promise.then(function (result) {
            return {
                result: result,
                status: "resolved"
            }
        },
        function (err) {
            return {
                err: err,
                status: "rejected"
            }
        });
}

function mapToPullRequestModel(pr) {
    return {
        _id: pr.id,
        title: pr.title,
        bodyText: pr.bodyText,
        state: pr.state,
        issues: [],
        mergeCommit: pr.mergeCommit.abbreviatedOid,
        createdAt: pr.createdAt,
        updatedAt: pr.updatedAt
    }
}

function mapToIssueModel(issue) {
    return {
        _id: issue.number,
        state: issue.closed ? "CLOSED" : "OPEN",
        title: issue.title,
        bodyText: issue.bodyText,
        createdAt: issue.createdAt,
        updatedAt: issue.updatedAt
    }
}
{'fraction_non_alphanumeric': 0.12442337262942081, 'fraction_numerical': 0.0007688364941055869, 'mean_word_length': 2.9319899244332492, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1972293', 'n_tokens_mistral': 2245, 'n_tokens_neox': 2198, 'n_words': 600}