Check out this super-simple node.js program:
var g = { a : 1, b : 2 }
function callBack (key, value) {
console.log("Callback called with key: " + key + "\nAnd value: " + value) ;
}
function doNothing (key, value, cb) {
true ;
console.log(key + ": doing nothing") ;
cb() ;
}
function doLoop () {
for (k in g) {
f = function () {
callBack(k, g[k]) ;
}
doNothing(k, g[k], f) ;
}
}
doLoop() ;
When run, it produces this output:
a: doing nothing
Callback called with key: a
And value: 1
b: doing nothing
Callback called with key: b
And value: 2
OK. That makes sense - each time the callback is called, it has the correct arguments.
Now look at this program:
var mysql = require('mysql') ;
var dbClient = undefined ;
var db_uri = "mysql://xxx:xxx@127.0.0.1/xxx" ;
var schema = {
redirects : "(id int AUTO_INCREMENT, key VARCHAR(50), url VARCHAR(2048))",
clicks : "(ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP, IP VARBINARY(16))"
} ;
function createOnEmpty(err, results, fields, tableName, create_def) {
console.log("createOnEmpty called on " + tableName) ;
if (err) {
console.error(err) ;
process.exit(1) ;
} else {
if (0 == results.length) {
dbClient.query(["create table ", tableName, create_def].join(" "),
function (err, results, fields) {} ) ;
} else {
console.log(tableName + " table already exists.") ;
}
}
console.log("\n\n") ;
}
function setupSchema() {
for (table in schema) {
console.log("Checking for table: " + table) ;
// FIXME: Why does this always seem to pass clicks as tablename?!
dbClient.query(
"show tables LIKE '" + table + "'",
function (err, results, fields) {
createOnEmpty(err, results, fields, table, schema[table])
}
);
}
}
function handleDBConnect(err) {
if (err) {
console.error("ERROR: problem connecting to DB: " + err.code) ;
process.exit(1) ;
} else {
console.log("Connected to database.") ;
// Automatically set up the schema, if the tables don't exist
setupSchema() ;
}
}
function MySQLConnect() {
dbClient = mysql.createConnection(db_uri) ;
dbClient.connect(handleDBConnect) ;
}
MySQLConnect() ;
It outputs:
Connected to database.
Checking for table: redirects
Checking for table: clicks
createOnEmpty called on clicks
createOnEmpty called on clicks
The loop seems to be giving the argument 'clicks' as the argument 'table' both times, even though the variable has clearly been switched to 'redirects'.
I figure I must have some fundamental misunderstanding of how JavaScript/Node works here.