<commit_before>import mysql from 'mysql';

const debug = require('../../debug')('db:clients:mysql');
const mysqlErrors = {
  ER_EMPTY_QUERY: 'ER_EMPTY_QUERY',
};


export default function(server, database) {
  return new Promise(async (resolve, reject) => {
    const dbConfig = _configDatabase(server, database);

    debug('creating database client %j', dbConfig);
    const client = mysql.createConnection(dbConfig);

    client.on('error', error => {
      // it will be handled later in the next query execution
      debug('Connection fatal error %j', error);
    });

    debug('connecting');
    client.connect(err => {
      if (err) {
        client.end();
        return reject(err);
      }

      debug('connected');
      resolve({
        disconnect: () => disconnect(client),
        listTables: () => listTables(client),
        listViews: () => listViews(client),
        listRoutines: () => listRoutines(client),
        executeQuery: (query) => executeQuery(client, query),
        listDatabases: () => listDatabases(client),
        getQuerySelectTop: (table, limit) => getQuerySelectTop(client, table, limit),
        truncateAllTables: () => truncateAllTables(client),
      });
    });
  });
}


export function disconnect(client) {
  client.end();
}


export function listTables(client) {
  return new Promise((resolve, reject) => {
    const sql = `
      SELECT table_name
      FROM information_schema.tables
      WHERE table_schema = database()
      AND table_type NOT LIKE '%VIEW%'
      ORDER BY table_name
    `;
    const params = [];
    client.query(sql, params, (err, data) => {
      if (err) return reject(_getRealError(client, err));
      resolve(data.map(row => row.table_name));
    });
  });
}

export function listViews(client) {
  return new Promise((resolve, reject) => {
    const sql = `
      SELECT table_name
      FROM information_schema.views
      WHERE table_schema = database()
      ORDER BY table_name
    `;
    const params = [];
    client.query(sql, params, (err, data) => {
      if (err) return reject(_getRealError(client, err));
      resolve(data.map(row => row.table_name));
    });
  });
}

export function listRoutines(client) {
  return new Promise((resolve, reject) => {
    const sql = `
      SELECT routine_name, routine_type
      FROM information_schema.routines
      WHERE routine_schema = database()
      ORDER BY routine_name
    `;
    const params = [];
    client.query(sql, params, (err, data) => {
      if (err) return reject(_getRealError(client, err));
      resolve(data.map(row => ({
        routineName: row.routine_name,
        routineType: row.routine_type,
      })));
    });
  });
}

export function executeQuery(client, query) {
  return new Promise((resolve, reject) => {
    client.query(query, (err, data, fields) => {
      if (err && err.code === mysqlErrors.ER_EMPTY_QUERY) return resolve([]);
      if (err) return reject(_getRealError(client, err));

      if (!isMultipleQuery(fields)) {
        return resolve([parseRowQueryResult(data, fields)]);
      }<commit_msg>Add list table columns feature for MySQL<commit_after>import mysql from 'mysql';

const debug = require('../../debug')('db:clients:mysql');
const mysqlErrors = {
  ER_EMPTY_QUERY: 'ER_EMPTY_QUERY',
};


export default function(server, database) {
  return new Promise(async (resolve, reject) => {
    const dbConfig = _configDatabase(server, database);

    debug('creating database client %j', dbConfig);
    const client = mysql.createConnection(dbConfig);

    client.on('error', error => {
      // it will be handled later in the next query execution
      debug('Connection fatal error %j', error);
    });

    debug('connecting');
    client.connect(err => {
      if (err) {
        client.end();
        return reject(err);
      }

      debug('connected');
      resolve({
        disconnect: () => disconnect(client),
        listTables: () => listTables(client),
        listViews: () => listViews(client),
        listRoutines: () => listRoutines(client),
        listTableColumns: (table) => listTableColumns(client, table),
        executeQuery: (query) => executeQuery(client, query),
        listDatabases: () => listDatabases(client),
        getQuerySelectTop: (table, limit) => getQuerySelectTop(client, table, limit),
        truncateAllTables: () => truncateAllTables(client),
      });
    });
  });
}


export function disconnect(client) {
  client.end();
}


export function listTables(client) {
  return new Promise((resolve, reject) => {
    const sql = `
      SELECT table_name
      FROM information_schema.tables
      WHERE table_schema = database()
      AND table_type NOT LIKE '%VIEW%'
      ORDER BY table_name
    `;
    const params = [];
    client.query(sql, params, (err, data) => {
      if (err) return reject(_getRealError(client, err));
      resolve(data.map(row => row.table_name));
    });
  });
}

export function listViews(client) {
  return new Promise((resolve, reject) => {
    const sql = `
      SELECT table_name
      FROM information_schema.views
      WHERE table_schema = database()
      ORDER BY table_name
    `;
    const params = [];
    client.query(sql, params, (err, data) => {
      if (err) return reject(_getRealError(client, err));
      resolve(data.map(row => row.table_name));
    });
  });
}

export function listRoutines(client) {
  return new Promise((resolve, reject) => {
    const sql = `
      SELECT routine_name, routine_type
      FROM information_schema.routines
      WHERE routine_schema = database()
      ORDER BY routine_name
    `;
    const params = [];
    client.query(sql, params, (err, data) => {
      if (err) return reject(_getRealError(client, err));
      resolve(data.map(row => ({
        routineName: row.routine_name,
        routineType: row.routine_type,
      })));
    });
  });
}

export function listTableColumns(client, table) {
  return new Promise((resolve, reject) => {
    const sql = `
      SELECT column_name, data_type
      FROM information_schema.columns
      WHERE table_schema = database()
      AND table_name = ?
    `;
    const params = [
      table,
    ];
    client.query(sql, params, (err, data) => {
      if (err) return reject(_getRealError(client, err));
      resolve(data.map(row => ({
        columnName: row.column_name,
        dataType: row.data_type,
      })));
    });
  });
}

export function executeQuery(client, query) {
  return new Promise((resolve, reject) => {
    client.query(query, (err, data, fields) => {
      if (err && err.code === mysqlErrors.ER_EMPTY_QUERY) return resolve([]);
      if (err) return reject(_getRealError(client, err));

      if (!isMultipleQuery(fields)) {
        return resolve([parseRowQueryResult(data, fields)]);
      }
{'fraction_non_alphanumeric': 0.13949035204006482, 'fraction_numerical': 0.0, 'mean_word_length': 3.001178550383029, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 51, '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': '1842925', 'n_tokens_mistral': 2007, 'n_tokens_neox': 1971, 'n_words': 481}