js/main.js
/* Check the answer
 * @param {json} inputResult - the user input containing their sql output in json.stringify!
 * @param {string} raw - the raw SQL that the user inputted
 * @return {bool} - correct or not?
 */
Check the answer
@param {json} inputResult - the user input containing their sql output in json.stringify.
Check the answer @param { json } inputResult - the user input containing their sql output in json . stringify .
function checkAnswer(inputResult, raw) {
    var currQuestion =
        (typeof Cookies.get('CurrQuestion') !== 'undefined') ? Cookies.get('CurrQuestion') : 1
    var cache = Cookies.get('Question-' + currQuestion)
    if (typeof cache === 'undefined') {
        return 'An error occurred while fetching the answer from the cache!';
    }
    cache = Base64.decode(cache)
    cache = JSON.parse(cache)
    if (typeof cache.Include !== 'undefined') {
        var keywordIndex = -1
        for (var i = 0; i < cache.Include.length; i++) {
            keywordIndex = raw.toUpperCase().indexOf(cache.Include[i], keywordIndex + 1)
            if (keywordIndex == -1) { 
                return 'Looking for the incursion of the keyword: ' +
                    cache.Include[i] + ', but not found in the correct position!'
            }
        }
    }
    var modelResults = [],
        userResults = []
    var stmt = db.prepare(raw)
    var answerStmt = db.prepare(cache.Answer)
    while (answerStmt.step()) modelResults.push(answerStmt.getAsObject())
    while (stmt.step()) userResults.push(stmt.getAsObject())
    stmt.free()
    answerStmt.free()
    if (modelResults.length != userResults.length || !userResults.length) {
        return 'Expected a total of ' + modelResults.length + ' row(s) to be returned' +
            ', instead got ' + userResults.length + '!';
    }
    var userColumns = Object.keys(userResults[0])
    var modelColumns = Object.keys(modelResults[0])
    if (modelColumns.length != userColumns.length) {
        return 'Expected only the following column(s) to be selected: ' +
            modelColumns.join(', ');
    }
    for (var i = 0; i < userColumns.length; i++) {
        var answerObj = modelResults.map(function(item) {
            return item[userColumns[i]
                .replace(/[^A-Za-z()*]+/g, "")
                .replace(/(COUNT|SUM|AVG|MIN|TOTAL|MAX|SUM)\(/gi, l => l.toUpperCase())]
        }).filter(function(x) {
            return typeof x !== 'undefined'
        })
        var userObj = userResults.map(function(item) {
            return item[userColumns[i]]
        })
        if (answerObj.length != userObj.length) {
            return 'Expected only the following column(s) to be selected: ' +
                modelColumns.join(', ');
        }
        var lastItem;
        var isPresent = answerObj.every(function(item, idx) {
            lastItem = item;
            return userObj.indexOf(item) !== -1
        })
        if (!isPresent) {
            return 'The row containing "' + lastItem + '" in the column ' +
                userColumns[i] + ' wasn\'t found within your result set';
        }
    }
    return true
}
function checkAnswer ( inputResult , raw ) { var currQuestion = ( typeof Cookies . get ( 'CurrQuestion' ) !== 'undefined' ) ? Cookies . get ( 'CurrQuestion' ) : 1 var cache = Cookies . get ( 'Question-' + currQuestion ) if ( typeof cache === 'undefined' ) { return 'An error occurred while fetching the answer from the cache!' ; } cache = Base64 . decode ( cache ) cache = JSON . parse ( cache ) if ( typeof cache . Include !== 'undefined' ) { var keywordIndex = - 1 for ( var i = 0 ; i < cache . Include . length ; i ++ ) { keywordIndex = raw . toUpperCase ( ) . indexOf ( cache . Include [ i ] , keywordIndex + 1 ) if ( keywordIndex == - 1 ) { return 'Looking for the incursion of the keyword: ' + cache . Include [ i ] + ', but not found in the correct position!' } } } var modelResults = [ ] , userResults = [ ] var stmt = db . prepare ( raw ) var answerStmt = db . prepare ( cache . Answer ) while ( answerStmt . step ( ) ) modelResults . push ( answerStmt . getAsObject ( ) ) while ( stmt . step ( ) ) userResults . push ( stmt . getAsObject ( ) ) stmt . free ( ) answerStmt . free ( ) if ( modelResults . length != userResults . length || ! userResults . length ) { return 'Expected a total of ' + modelResults . length + ' row(s) to be returned' + ', instead got ' + userResults . length + '!' ; } var userColumns = Object . keys ( userResults [ 0 ] ) var modelColumns = Object . keys ( modelResults [ 0 ] ) if ( modelColumns . length != userColumns . length ) { return 'Expected only the following column(s) to be selected: ' + modelColumns . join ( ', ' ) ; } for ( var i = 0 ; i < userColumns . length ; i ++ ) { var answerObj = modelResults . map ( function ( item ) { return item [ userColumns [ i ] . replace ( / [^A-Za-z()*]+ / g , "" ) . replace ( / (COUNT|SUM|AVG|MIN|TOTAL|MAX|SUM)\( / gi , l => l . toUpperCase ( ) ) ] } ) . filter ( function ( x ) { return typeof x !== 'undefined' } ) var userObj = userResults . map ( function ( item ) { return item [ userColumns [ i ] ] } ) if ( answerObj . length != userObj . length ) { return 'Expected only the following column(s) to be selected: ' + modelColumns . join ( ', ' ) ; } var lastItem ; var isPresent = answerObj . every ( function ( item , idx ) { lastItem = item ; return userObj . indexOf ( item ) !== - 1 } ) if ( ! isPresent ) { return 'The row containing "' + lastItem + '" in the column ' + userColumns [ i ] + ' wasn\'t found within your result set' ; } } return true }
Check the answer
 @param {json} inputResult - the user input containing their sql output in json.stringify!
Check the answer @param { json } inputResult - the user input containing their sql output in json . stringify!
// refresh the current question from cookie
 // fetch the model answer from the cache (generated when a question was stored)
 // if the answer isn't in the cache, return error
 // decode the cookie
 // parse the string into a JSON object
 // Check to make sure syntax includes certain keywords, if set
 // search for the keyword, if strict, must come AFTER the previous keyword
 // not found
 // set the blank arrays
 // prepare both queries
 // run the statements in steps to loop each row
 // free the statements to prevent memory leaks
 // check both result objects are of equal length
 // extract the column names via the object keys
 // check if the columns selected is the same LENGTH as the model answer
 // loop through each column
 // construct a variable containing the row values contained in this column
 // remove any unwanted punctuation
 // and capitalize aggregate functions
 // filter out the undefined values, indication of mis-matched column names
 // do the same with the user's answer
 // checks that the columns selected are expected
 // checks every value in the users answer is included in the model answer
 // if one column returns false, stop checking and return feedback
 // if the code executed to this point, the solution is valid
