UNPKG

jones-ndb

Version:

Native NDB (MySQL Cluster) Service Provider for Database Jones

334 lines (280 loc) 8.25 kB
/* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // configure.js: // If "-m /path/to/mysql/tree" is specified, configure jones-ndb to // build with that mysql. // Otherwise, run interactively: // Try to find installed mysql that matches architecture of node // Ask user for mysql pathname // // Writes mysql pathname and other options into config.gypi // // TODO: Auto-detect mysql layout here, and write about it in config.gypi "use strict"; var fs = require("fs"), path = require("path"), readline = require("readline"); var archbits, archname, archmysql; switch(process.arch) { case 'ia32': archbits = 32; archmysql = 'i686'; break; case 'x64': archbits = 64; archmysql = 'x86_64'; break; default: throw "Architecture " + process.arch + " unsupported."; } var path_sep = ( path.sep === undefined ? '/' : path.sep); archname = String(archbits) + '-bit'; var lf = '\n'; var greeting = '# ' +lf+ '# MySQL Cluster Driver for Jones' +lf+ '# ' +lf+ '# This Driver provides high-performance native access to MySQL Cluster ' +lf+ '# using the NDB API.' +lf+ '# ' +lf+ '# In order to build and run the ndb adapter, you must have: ' +lf+ '# - An installation of MySQL Cluster 7.x or MySQL 5.6 ' +lf+ '# including headers and shared library files [' +archname +']' +lf+ '# - A working C++ compiler ' +lf+ '# ' +lf; function verify(dir) { var stats; try { stats = fs.statSync(dir); return stats.isDirectory(); } catch(e) { return false; } } function get_candidates_windows() { var candidates = []; var c1 = "C:\\Program Files\\MySQL Server 5.6"; if(verify(c1)) { candidates.push(c1); } return candidates; } function get_candidates() { var candidates = []; var link, verified; if(verify('/usr/share/mysql/java')) { // RPM candidates.push('/usr'); } if(verify('/usr/local/mysql/share/java')) { // Mac or generic TAR /* if /usr/local/mysql is a symlink, the real directory name must match the target architecture */ try { link = fs.readlinkSync('/usr/local/mysql'); verified = (link.indexOf(archmysql) > 0); } catch(e) { verified = null; // not a symlink } if(verified !== false) { candidates.push('/usr/local/mysql'); } } if(verify('/opt/mysql/server-5.6/share/java')) { // Debian candidates.push('/opt/mysql/server-5.6'); } return candidates; } function build_prompt(candidates) { var i = 0, found = ''; if(candidates.length) { found = '# ' +lf+ '# ' +lf+ '# Choose your preferred mysql install location: ' +lf+ '# ' +lf; for(i ; i < candidates.length ; i++) { found += ' [' + String(i+1) + '] ' + candidates[i] + lf; } } else { found = '# ' +lf+ '# ~~~~~~~~ No '+archname+' MySQL Cluster installations found.' +lf+ '# ' +lf; } found += ' [' + String(++i) + '] Choose custom mysql directory' +lf; return found; } function finish() { console.log(""); // The -d in the following line configures a debug build // It is strictly necessary only on Windows platforms console.log("Now run this command:\n\tnode-gyp configure build -d"); process.exit(0); } function testPath(mysqlPath) { // We assert that a path is a valid mysql install tree if and only if // it contains a mysql-test directory return verify(path.join(mysqlPath.trim(), "mysql-test")); } function configure(mysql, layout) { if(mysql) { var gyp = {}; gyp.variables = { "mysql_path" : mysql, "mysql_layout" : layout || "", "node_version" : process.versions.node }; fs.writeFileSync("config.gypi", JSON.stringify(gyp) + "\n", "ascii"); finish(); } else { process.exit(-1); } } // Filename completion // Returns [ [array of matches], original substring ] function completion(line) { var matches = []; var files = []; var dir, base, stat, i; function readCurrentDir(dir) { files = []; // parent scope try { files = fs.readdirSync(dir); } catch(ignore) {} } if(line.slice(-1) == path_sep) { dir = line; readCurrentDir(dir); base = ""; } else { dir = path.dirname(line); // returns "." if path is unrooted base = path.basename(line); readCurrentDir(dir); } for(i = 0; i < files.length ; i++) { if(files[i].substring(0,1) !== "." && files[i].match("^" + base)) { matches.push(path.join(dir, files[i])); } } if(matches.length == 1) { try { stat = fs.statSync(matches[0]); if(stat.isDirectory()) { matches[0] += path_sep; } } catch(ignore) {} } return [matches, line]; } ///// ****** INTERACTIVE MAIN ROUTINE STARTS HERE ****** ///// function interactive_main(options) { var candidates; if(process.platform == 'win32') { candidates = get_candidates_windows(); } else { candidates = get_candidates(); } var text = build_prompt(candidates); var rl = readline.createInterface(process.stdin, process.stdout, completion); function hangup() { rl.close(); process.exit(-1); } function onPath(mysqlPath) { if(testPath(mysqlPath)) { rl.close(); configure(mysqlPath); } else { console.log("ERROR: not a MySQL install tree" + lf); rl.prompt(true); } } function customMode() { rl.setPrompt('MySQL Install Path> ', 20); rl.on('line', onPath); rl.prompt(true); } function onEntry(choice) { var range = candidates.length + 1; var num = Number(choice); if(isNaN(num)) { // user skipped straight to pathname entry onPath(choice); } else if(num < 1 || num > range) { rl.write("Please enter a number between 1 and " + range + "." + lf); rl.write("Hit CTRL-C to exit." +lf); rl.prompt(true); } else if(num === (range - 1)) { rl.removeListener('line', onEntry); customMode(); } else { rl.close(); configure(candidates[num - 1]); } } function mainMode() { rl.setPrompt('Your choice> ', 13); rl.on('line', onEntry); rl.prompt(true); } /* Start here: */ /* MySQL Path was supplied on the command line */ if(process.argv[2]) { configure(process.argv[2]); } /* Get path interactively */ rl.write(greeting); rl.on('SIGINT', hangup); if(candidates.length) { rl.write(text); mainMode(); } else { customMode(); } } function process_options() { var i, len, opts; len = process.argv.length; opts = { "interactive" : true }; for(i = 2 ; i < len ; i++) { if(process.argv[i] == "-m" && (i+1 < len)) { opts.interactive = false; opts.path = process.argv[i+1]; } } return opts; } function utility_main(options) { if(verify(options.path)) { configure(options.path); } else { console.log("ERROR: " + options.path + " is not a directory."); process.exit(-1); } } /* Script starts here: */ var opts = process_options(); if(opts.interactive) { interactive_main(opts); } else { utility_main(opts); }