<commit_before>import knex from 'knex';
import databaseConfig from 'lib/../../config/database.config';
import { mapGhostNames } from 'lib/falcor/FalcorRouter';
import _ from 'lodash';
import { formatDate, formatDateTime } from 'lib/utilities';

const knexConnectionObject = {
  client: 'mysql',
  connection: databaseConfig,
  pool: {
    min: 10,
    max: 50,
  },
};

const database = knex(knexConnectionObject);

export default class db {
  authorQuery(slugs, columns) {
    // parameters are both expected to be arrays
    // the first one with author slugs to fetch
    // and the other one the columns to retrieve from the authors
    return new Promise((resolve, reject) => {
      // const database = knex(knexConnectionObject);
      // So the Falcor Router knows which author we're talking about
      if (!columns.some((col) => {return col === "slug"})) {
        // Use concat to make a copy, if you just push
        // it will change pathSet in the falcorPath
        // as objects are passed by reference
        columns = columns.concat(['slug']);
      }
      database.select(...columns)
      .from('authors')
      .whereIn('slug', slugs)
      .then((rows) => {
        // database.destroy();
        resolve(rows);
      })
      .catch((e) => {
        // database.destroy();
        throw new Error(e);
      });
    });
  }

  authorArticleQuery(slugs) {
    // slugs function parameter is an array of author slugs
    // of which to fetch the articles they have written.
    // The function returns an object with author slugs
    // as keys and values being arrays of article slugs
    // sorted by most recent article first.
    return new Promise((resolve, reject) => {
      // const database = knex(knexConnectionObject);
      database.select('posts.slug as post_slug', 'authors.slug as author_slug')
      .from('authors')
      .innerJoin('authors_posts', 'authors.id', '=', 'author_id')
      .innerJoin('posts', 'posts.id', '=', 'post_id')
      .innerJoin('posts_meta', 'posts.id', '=', 'posts_meta.id')
      .whereNotNull('gazelle_published_at')
      .whereIn('authors.slug', slugs).orderBy('gazelle_published_at', 'desc')
      .then((rows) => {
        // rows is an array of objects with keys author_slug and post_slug
        const data = {};
        rows.forEach((row) => {
          // This will input them in chronological order as
          // the query was structured as so.
          if (!data.hasOwnProperty(row.author_slug)) {
            data[row.author_slug] = [row.post_slug];
          }
          else {
            data[row.author_slug].push(row.post_slug);
          }
        });
        // database.destroy();
        resolve(data);
      })
      .catch((e) => {
        // database.destroy();
        throw new Error(e);
      })
    })
  }

  infoPagesQuery(slugs, columns) {
    // parameters are both expected to be arrays
    // first one with page slugs to fetch
    // second one which columns to fetch from the db
    return new Promise((resolve, reject) => {
      // const database = knex(knexConnectionObject);
      // So the Falcor Router knows which author we're talking about
      if (columns.find((col) => {return col === "slug"}) === undefined) {
        // Use concat to make a copy, if you just push
        // it will change pathSet in the falcorPath
        // as objects are passed by reference
        columns = columns.concat(['slug']);
      }
      database.select(...columns)
      .from('info_pages')
      .whereIn('slug', slugs)
      .then((rows) => {
        // database.destroy();
        resolve(rows);
      })
      .catch((e) => {
        // database.destroy();
        throw new Error(e);
      })
    })
  }

  articleQuery(slugs, columns) {
    // parameters are both expected to be arrays
    // first one with article slugs to fetch
    // second one which columns to fetch from the posts_meta table
    return new Promise((resolve, reject) => {
      // const database = knex(knexConnectionObject);
      // we join with posts table to find slug, and always return slug
      columns = columns.map((col) => {
        // make it compatible for the sql query
        if (col === "category") {
          return "categories.slug as category";
        }
        else if (col === "published_at") {
          return "gazelle_published_at as published_at";
        }
        else {
          return col;
        }
      })
      // Put slug there so we know what we fetched
      // Use concat to make a copy, if you just push
      // it will change pathSet in the falcorPath
      // as objects are passed by reference
      columns = columns.concat(['posts.slug as slug']);
      database.select(...columns)
      .from('posts')
      .innerJoin('posts_meta', 'posts.id', '=', 'posts_meta.id')
      .innerJoin('categories', 'posts_meta.category_id', '=', 'categories.id')
      .whereIn('posts.slug', slugs)
      .then((rows) => {
        // database.destroy();
        resolve(rows);
      })
      .catch((e) => {
        // database.destroy();
        throw new Error(e);
      })
    })
  }

  articleIssueQuery(slugs) {
    // the parameter is the slugs the issueNumber is being requested from
    return new Promise((resolve, reject) => {
      // const database = knex(knexConnectionObject);
      database.select('issue_order as issueNumber', 'posts.slug as slug')
      .from('posts')
      .innerJoin('issues_posts_order', 'issues_posts_order.post_id', '=', 'posts.id')
      .innerJoin('issues', 'issues.id', '=', 'issues_posts_order.issue_id')
      .whereIn('posts.slug', slugs)
      .then((rows) => {
        // database.destroy();
        resolve(rows);
      })
      .catch((e) => {
        // database.destroy();
        throw new Error(e);
      })
    });
  }

  articleAuthorQuery(slugs) {
    // slugs function parameter is an array of article slugs
    // of which to fetch the authors of.
    // The function returns an object with article slugs
    // as keys and values being arrays of author slugs.
    return new Promise((resolve, reject) => {
      // const database = knex(knexConnectionObject);
      database.select('posts.slug as post_slug', 'authors.slug as author_slug')
      .from('authors')
      .innerJoin('authors_posts', 'authors.id', '=', 'author_id')
      .innerJoin('posts', 'posts.id', '=', 'post_id')
      .innerJoin('posts_meta', 'posts.id', '=', 'posts_meta.id')
      .whereIn('posts.slug', slugs)
      .orderBy('authors_posts.id', 'asc')
      .then((rows) => {
        // rows is an array of objects with keys author_slug and post_slug
        const data = {};
        rows.forEach((row) => {
          // This will input them in ascending order by id (which represents time they were
          // inserted as author of that article) as the query was structured so.<commit_msg>Update get article's issueNumber falcor route to handle articles that are in several issues (always fetchest the earliest issue it was published in as this is assumed the original one)<commit_after>import knex from 'knex';
import databaseConfig from 'lib/../../config/database.config';
import { mapGhostNames } from 'lib/falcor/FalcorRouter';
import _ from 'lodash';
import { formatDate, formatDateTime } from 'lib/utilities';

const knexConnectionObject = {
  client: 'mysql',
  connection: databaseConfig,
  pool: {
    min: 10,
    max: 50,
  },
};

const database = knex(knexConnectionObject);

export default class db {
  authorQuery(slugs, columns) {
    // parameters are both expected to be arrays
    // the first one with author slugs to fetch
    // and the other one the columns to retrieve from the authors
    return new Promise((resolve, reject) => {
      // const database = knex(knexConnectionObject);
      // So the Falcor Router knows which author we're talking about
      if (!columns.some((col) => {return col === "slug"})) {
        // Use concat to make a copy, if you just push
        // it will change pathSet in the falcorPath
        // as objects are passed by reference
        columns = columns.concat(['slug']);
      }
      database.select(...columns)
      .from('authors')
      .whereIn('slug', slugs)
      .then((rows) => {
        // database.destroy();
        resolve(rows);
      })
      .catch((e) => {
        // database.destroy();
        throw new Error(e);
      });
    });
  }

  authorArticleQuery(slugs) {
    // slugs function parameter is an array of author slugs
    // of which to fetch the articles they have written.
    // The function returns an object with author slugs
    // as keys and values being arrays of article slugs
    // sorted by most recent article first.
    return new Promise((resolve, reject) => {
      // const database = knex(knexConnectionObject);
      database.select('posts.slug as post_slug', 'authors.slug as author_slug')
      .from('authors')
      .innerJoin('authors_posts', 'authors.id', '=', 'author_id')
      .innerJoin('posts', 'posts.id', '=', 'post_id')
      .innerJoin('posts_meta', 'posts.id', '=', 'posts_meta.id')
      .whereNotNull('gazelle_published_at')
      .whereIn('authors.slug', slugs).orderBy('gazelle_published_at', 'desc')
      .then((rows) => {
        // rows is an array of objects with keys author_slug and post_slug
        const data = {};
        rows.forEach((row) => {
          // This will input them in chronological order as
          // the query was structured as so.
          if (!data.hasOwnProperty(row.author_slug)) {
            data[row.author_slug] = [row.post_slug];
          }
          else {
            data[row.author_slug].push(row.post_slug);
          }
        });
        // database.destroy();
        resolve(data);
      })
      .catch((e) => {
        // database.destroy();
        throw new Error(e);
      })
    })
  }

  infoPagesQuery(slugs, columns) {
    // parameters are both expected to be arrays
    // first one with page slugs to fetch
    // second one which columns to fetch from the db
    return new Promise((resolve, reject) => {
      // const database = knex(knexConnectionObject);
      // So the Falcor Router knows which author we're talking about
      if (columns.find((col) => {return col === "slug"}) === undefined) {
        // Use concat to make a copy, if you just push
        // it will change pathSet in the falcorPath
        // as objects are passed by reference
        columns = columns.concat(['slug']);
      }
      database.select(...columns)
      .from('info_pages')
      .whereIn('slug', slugs)
      .then((rows) => {
        // database.destroy();
        resolve(rows);
      })
      .catch((e) => {
        // database.destroy();
        throw new Error(e);
      })
    })
  }

  articleQuery(slugs, columns) {
    // parameters are both expected to be arrays
    // first one with article slugs to fetch
    // second one which columns to fetch from the posts_meta table
    return new Promise((resolve, reject) => {
      // const database = knex(knexConnectionObject);
      // we join with posts table to find slug, and always return slug
      columns = columns.map((col) => {
        // make it compatible for the sql query
        if (col === "category") {
          return "categories.slug as category";
        }
        else if (col === "published_at") {
          return "gazelle_published_at as published_at";
        }
        else {
          return col;
        }
      })
      // Put slug there so we know what we fetched
      // Use concat to make a copy, if you just push
      // it will change pathSet in the falcorPath
      // as objects are passed by reference
      columns = columns.concat(['posts.slug as slug']);
      database.select(...columns)
      .from('posts')
      .innerJoin('posts_meta', 'posts.id', '=', 'posts_meta.id')
      .innerJoin('categories', 'posts_meta.category_id', '=', 'categories.id')
      .whereIn('posts.slug', slugs)
      .then((rows) => {
        // database.destroy();
        resolve(rows);
      })
      .catch((e) => {
        // database.destroy();
        throw new Error(e);
      })
    })
  }

  articleIssueQuery(slugs) {
    // the parameter is the slugs the issueNumber is being requested from
    return new Promise((resolve, reject) => {
      database.select('issue_order as issueNumber', 'posts.slug as slug')
      .from('posts')
      .innerJoin('issues_posts_order', 'issues_posts_order.post_id', '=', 'posts.id')
      .innerJoin('issues', 'issues.id', '=', 'issues_posts_order.issue_id')
      .whereIn('posts.slug', slugs)
      .orderBy('posts.slug')
      .then((rows) => {
        // We always want to return the first issue the article was published in
        // and no more (currently we don't support falcor fetching all issues an
        // article was published in, if needed that's not a problem though)
        const toDelete = [];
        let lastRow = null;
        rows.forEach((row, index) => {
          if (lastRow && row.slug === lastRow.slug) {
            if (row.issueNumber < lastRow.issueNumber) {
              toDelete.push(index-1);
            }
            else if (row.issueNumber > lastRow.issueNumber) {
              toDelete.push(index);
            }
            else {
              throw new Error("Data corrupted, article: " + row.slug + " occurs twice in issue " + lastRow.issueNumber.toString());
            }
          }
        });
        toDelete.reverse().forEach((index) => {
          rows.splice(index, 1);
        });
        resolve(rows);
      })
      .catch((e) => {
        throw new Error(e);
      })
    });
  }

  articleAuthorQuery(slugs) {
    // slugs function parameter is an array of article slugs
    // of which to fetch the authors of.
    // The function returns an object with article slugs
    // as keys and values being arrays of author slugs.
    return new Promise((resolve, reject) => {
      // const database = knex(knexConnectionObject);
      database.select('posts.slug as post_slug', 'authors.slug as author_slug')
      .from('authors')
      .innerJoin('authors_posts', 'authors.id', '=', 'author_id')
      .innerJoin('posts', 'posts.id', '=', 'post_id')
      .innerJoin('posts_meta', 'posts.id', '=', 'posts_meta.id')
      .whereIn('posts.slug', slugs)
      .orderBy('authors_posts.id', 'asc')
      .then((rows) => {
        // rows is an array of objects with keys author_slug and post_slug
        const data = {};
        rows.forEach((row) => {
          // This will input them in ascending order by id (which represents time they were
          // inserted as author of that article) as the query was structured so.
{'fraction_non_alphanumeric': 0.13135795726087254, 'fraction_numerical': 0.0006827336655970506, 'mean_word_length': 2.2776907585589616, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 50, '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': '3044271', 'n_tokens_mistral': 4175, 'n_tokens_neox': 4167, 'n_words': 1277}