function( json, typeSpecification, array ) {

      var keys,
          current = json,
          nested = [],
          nestedKeys = [],
          levels = [],
          query = 'COLUMN_CREATE(',
          root = true,
          curNest = '',
          curItem,
          item = 0,
          level = 0;

    while( current ) {

      keys = Object.keys( current );
      var len = keys.length;
      var _l;
      var deepestLevel = 1;

      for( var i = 0; i < len; ++i ) {

        if( ( _l = current[ keys[ i ] ] ) === null || _l === undefined ) {
          continue;
        }

        if( typeof( _l ) === 'object' ) {

          // skip empty objects, we do not store them,
          // this needs us to set NULL instead
          if( !Object.keys( _l ).length ) {

            _l = null;
            if( !typeSpecification ) {
              query += '\'' + keys[ i ].replace(/\\/g, '\\\\')
                .replace(/\u0008/g, '\\b')
                .replace(/'/g, '\\\'')
                .replace(/\u0000/g, '\\0') + '\', NULL, ';
            }
            else {
              query += '?, NULL, ';
              array.push( keys[ i ] );
            }

            continue;
          }

          nested.push( _l );
          nestedKeys.push( keys[ i ] );
          if ( curItem !== item ) {
              curItem = item;
              ++level;

              levels.push( { level: level - 1, nestSep: curNest + ')' } );
          }
          else {
            levels.push( { level: level - 1, nestSep: ')' } );
          }

          //save nesting level
        }
        else {

          var queryType = typeof( _l );
          if( !typeSpecification ) {
            query += '\'' + keys[ i ].replace(/\\/g, '\\\\')
              .replace(/\u0008/g, '\\b')
              .replace(/'/g, '\\\'')
              .replace(/\u0000/g, '\\0') + '\', ';
          }
          else {
            query += '?, ';
            array.push( keys[ i ] );
          }

          switch( queryType ) {

            case 'boolean':
              query += ( ( _l === true ) ? 1 : 0 ) + ' AS unsigned integer, ';
              break;

            case 'number':
              query += _l + ' AS double, ';
              break;

            default:

              if( !typeSpecification ) {

                query += '\'' + _l.replace(/\\/g, '\\\\')
                .replace(/\u0008/g, '\\b')
                .replace(/'/g, '\\\'')
                .replace(/\u0000/g, '\\0') + '\', ';
              }
              else {
                query += '?, ';
                array.push( _l );
              }
              break;
          }
        }
      }

      if( root ) {

        root = false;
      }
      else {

        if( level === 0 )
          query = query.substring( 0, query.length - 2 ) + curNest + ', ';
      }

      if( nested.length !== 0 ) {

        if( !typeSpecification ) {
          query += '\'' + nestedKeys.pop().replace(/\\/g, '\\\\')
            .replace(/\u0008/g, '\\b')
            .replace(/'/g, '\\\'')
            .replace(/\u0000/g, '\\0') + '\', COLUMN_CREATE(';
        }
        else {
          query += '?, COLUMN_CREATE(';
          array.push( nestedKeys.pop() );
        }
      }
      else {
        query = query.substring( 0, query.length - 2 );
      }

      current = nested.pop();
      ++item;

      //restore nesting level
      level = levels.pop() || 0;
      if ( level ) {

        curNest = level.nestSep;
        level = level.level;
      }

      deepestLevel = level + 1;
    }

    query += ')';

    return query;
  }
function( json, typeSpecification, array ) {

      var keys,
          current = json,
          nested = [],
          nestedKeys = [],
          levels = [],
          query = 'COLUMN_CREATE(',
          root = true,
          curNest = '',
          curItem,
          item = 0,
          level = 0;

    while( current ) {

      keys = Object.keys( current );
      var len = keys.length;
      var _l;
      var deepestLevel = 1;

      for( var i = 0; i < len; ++i ) {

        if( ( _l = current[ keys[ i ] ] ) === null || _l === undefined ) {
          continue;
        }

        if( typeof( _l ) === 'object' ) {

          // skip empty objects, we do not store them,
          // this needs us to set NULL instead
          if( !Object.keys( _l ).length ) {

            _l = null;
            if( !typeSpecification ) {
              query += '\'' + keys[ i ].replace(/\\/g, '\\\\')
                .replace(/\u0008/g, '\\b')
                .replace(/'/g, '\\\'')
                .replace(/\u0000/g, '\\0') + '\', NULL, ';
            }
            else {
              query += '?, NULL, ';
              array.push( keys[ i ] );
            }

            continue;
          }

          nested.push( _l );
          nestedKeys.push( keys[ i ] );
          if ( curItem !== item ) {
              curItem = item;
              ++level;

              levels.push( { level: level - 1, nestSep: curNest + ')' } );
          }
          else {
            levels.push( { level: level - 1, nestSep: ')' } );
          }

          //save nesting level
        }
        else {

          var queryType = typeof( _l );
          if( !typeSpecification ) {
            query += '\'' + keys[ i ].replace(/\\/g, '\\\\')
              .replace(/\u0008/g, '\\b')
              .replace(/'/g, '\\\'')
              .replace(/\u0000/g, '\\0') + '\', ';
          }
          else {
            query += '?, ';
            array.push( keys[ i ] );
          }

          switch( queryType ) {

            case 'boolean':
              query += ( ( _l === true ) ? 1 : 0 ) + ' AS unsigned integer, ';
              break;

            case 'number':
              query += _l + ' AS double, ';
              break;

            default:

              if( !typeSpecification ) {

                query += '\'' + _l.replace(/\\/g, '\\\\')
                .replace(/\u0008/g, '\\b')
                .replace(/'/g, '\\\'')
                .replace(/\u0000/g, '\\0') + '\', ';
              }
              else {
                query += '?, ';
                array.push( _l );
              }
              break;
          }
        }
      }

      if( root ) {

        root = false;
      }
      else {

        if( level === 0 )
          query = query.substring( 0, query.length - 2 ) + curNest + ', ';
      }

      if( nested.length !== 0 ) {

        if( !typeSpecification ) {
          query += '\'' + nestedKeys.pop().replace(/\\/g, '\\\\')
            .replace(/\u0008/g, '\\b')
            .replace(/'/g, '\\\'')
            .replace(/\u0000/g, '\\0') + '\', COLUMN_CREATE(';
        }
        else {
          query += '?, COLUMN_CREATE(';
          array.push( nestedKeys.pop() );
        }
      }
      else {
        query = query.substring( 0, query.length - 2 );
      }

      current = nested.pop();
      ++item;

      //restore nesting level
      level = levels.pop() || 0;
      if ( level ) {

        curNest = level.nestSep;
        level = level.level;
      }

      deepestLevel = level + 1;
    }

    query += ')';

    return query;
  }
function ( json , typeSpecification , array ) { var keys , current = json , nested = [ ] , nestedKeys = [ ] , levels = [ ] , query = 'COLUMN_CREATE(' , root = true , curNest = '' , curItem , item = 0 , level = 0 ; while ( current ) { keys = Object . keys ( current ) ; var len = keys . length ; var _l ; var deepestLevel = 1 ; for ( var i = 0 ; i < len ; ++ i ) { if ( ( _l = current [ keys [ i ] ] ) === null || _l === undefined ) { continue ; } if ( typeof ( _l ) === 'object' ) { // skip empty objects, we do not store them, // this needs us to set NULL instead if ( ! Object . keys ( _l ) . length ) { _l = null ; if ( ! typeSpecification ) { query += '\'' + keys [ i ] . replace ( / \\ / g , '\\\\' ) . replace ( / \u0008 / g , '\\b' ) . replace ( / ' / g , '\\\'' ) . replace ( / \u0000 / g , '\\0' ) + '\', NULL, ' ; } else { query += '?, NULL, ' ; array . push ( keys [ i ] ) ; } continue ; } nested . push ( _l ) ; nestedKeys . push ( keys [ i ] ) ; if ( curItem !== item ) { curItem = item ; ++ level ; levels . push ( { level : level - 1 , nestSep : curNest + ')' } ) ; } else { levels . push ( { level : level - 1 , nestSep : ')' } ) ; } //save nesting level } else { var queryType = typeof ( _l ) ; if ( ! typeSpecification ) { query += '\'' + keys [ i ] . replace ( / \\ / g , '\\\\' ) . replace ( / \u0008 / g , '\\b' ) . replace ( / ' / g , '\\\'' ) . replace ( / \u0000 / g , '\\0' ) + '\', ' ; } else { query += '?, ' ; array . push ( keys [ i ] ) ; } switch ( queryType ) { case 'boolean' : query += ( ( _l === true ) ? 1 : 0 ) + ' AS unsigned integer, ' ; break ; case 'number' : query += _l + ' AS double, ' ; break ; default : if ( ! typeSpecification ) { query += '\'' + _l . replace ( / \\ / g , '\\\\' ) . replace ( / \u0008 / g , '\\b' ) . replace ( / ' / g , '\\\'' ) . replace ( / \u0000 / g , '\\0' ) + '\', ' ; } else { query += '?, ' ; array . push ( _l ) ; } break ; } } } if ( root ) { root = false ; } else { if ( level === 0 ) query = query . substring ( 0 , query . length - 2 ) + curNest + ', ' ; } if ( nested . length !== 0 ) { if ( ! typeSpecification ) { query += '\'' + nestedKeys . pop ( ) . replace ( / \\ / g , '\\\\' ) . replace ( / \u0008 / g , '\\b' ) . replace ( / ' / g , '\\\'' ) . replace ( / \u0000 / g , '\\0' ) + '\', COLUMN_CREATE(' ; } else { query += '?, COLUMN_CREATE(' ; array . push ( nestedKeys . pop ( ) ) ; } } else { query = query . substring ( 0 , query . length - 2 ) ; } current = nested . pop ( ) ; ++ item ; //restore nesting level level = levels . pop ( ) || 0 ; if ( level ) { curNest = level . nestSep ; level = level . level ; } deepestLevel = level + 1 ; } query += ')' ; return query ; }
A non recursive way to resolve our json schema to the create query.

We handle Numbers by default as double, booleans as unsigned integer
and everything else as string.

If you need or want to specify the types, you can set the second parameter
to call the type defined variant instead.

@return string
A non recursive way to resolve our json schema to the create query .