@function sync

checks that database matches model spec and attempts update if possible

@param {object} args

@returns {Promise}

@throws {Error}
967258
async function sync (args) {
    // set validation properties
    this.needsValidate = false
    this.validated = false
    this.updated = 0
    // get args object
    args = requireValidOptionalObject(args)
    // create elasticsearch index
    if (this.elasticsearch()) {
        await this.createElasticsearchIndex()
    }
    // get existing schema
    var schema = await this.schema(args)
    // if table exists then update table
    if (schema) {
        // add schema to args
        args.schema = schema
        // attempt to alter table to match schema
        await this.alterTable(args)
    }
    // otherwise attempt to create table
    else {
        await this.createTable(args)
    }
    // run validate after complete sync if needed
    if (this.needsValidate || defined(process.env.VALIDATE)) {
        await this.validate(args)
    }
}
1129955
function (arr, arr_name, config) {
	
	if (l_names.hasOwnProperty(arr_name)) {
		LOG.warn('array [' + arr_name + '] already sync with DB', 'SR.Sync');
		//return UTIL.safeCall(onDone, false);
		return false;
	}
	
	// first override the array's functions	
	arr.push = l_push;
	
	// store array's name
	arr._name = arr_name;
	
	// store last stored index
	arr._index = 0;

	// store to list of arrays
	l_names[arr_name] = arr;
	
	// NOTE: the DB creation may finish *after* this function returns
	// check if the array has been created inside DB, if not then create new record
	SR.DB.getArray(SR.Settings.DB_NAME_SYNC,
					function (result) {
						// NOTE: if array does not exist it'll return success with an empty array
						if (result === null || result.length === 0) {

							LOG.sys('array [' + arr_name + '] does not exist, create...', 'SR.Sync');
							SR.DB.setData(SR.Settings.DB_NAME_SYNC, {name: arr_name, data: []}, 
											function (r) {
												LOG.sys('array [' + arr_name + '] create success', 'SR.Sync');
												//UTIL.safeCall(onDone, true);
											},
											function (r) {
												LOG.error('array [' + arr_name + '] create fail', 'SR.Sync');
										  		//UTIL.safeCall(onDone, false);
											});
						}
						else {
							LOG.sys('array [' + arr_name + '] exists', 'SR.Sync');
							LOG.warn(result);
							//UTIL.safeCall(onDone, true);										
						}
					}, 
					function (result) {
						//UTIL.safeCall(onDone, false);
					}, 
					{name: arr_name});		

	return true;
	
	// TODO: consider config's effect
}
940635
function execute (configs, fn, ...args) {
  if ('verbose' in configs && configs.verbose) {
    const isoDate = (new Date()).toISOString()
    console.error(COLOR_FG_YELLOW + '[' + isoDate + '] Start mongo.execute: ' + JSON.stringify([configs, fn, args]) + COLOR_RESET)
  }
  const dbConfigs = util.getDeepCopiedObject(configs)
  const mongoUrl = 'mongoUrl' in dbConfigs ? dbConfigs.mongoUrl : ''
  const dbOption = 'dbOption' in dbConfigs ? dbConfigs.dbOption : {}
  const options = 'options' in dbConfigs ? dbConfigs.options : {}
  const collectionName = 'collectionName' in dbConfigs ? dbConfigs.collectionName : ''
  delete dbConfigs.mongoUrl
  delete dbConfigs.dbOption
  delete dbConfigs.collectionName
  let manager
  // wrap last argument in newCallback
  const callback = args[args.length - 1]
  const newCallback = (error, result) => {
    if ('verbose' in configs && configs.verbose) {
      const isoDate = (new Date()).toISOString()
      console.error(COLOR_FG_YELLOW + '[' + isoDate + '] Finish mongo.execute: ' + JSON.stringify([configs, fn, args]) + COLOR_RESET)
    }
    manager.close()
    callback(error, result)
  }
  args[args.length - 1] = newCallback
  manager = getCompleteManager(mongoUrl, dbOption, options, (error, manager) => {
    if (error) {
      return newCallback(error)
    }
    const collection = getCompleteCollection(manager, collectionName, dbConfigs)
    try {
      return collection[fn](...args)
    } catch (error) {
      return newCallback(error)
    }
  })
}
506969
public static int update(String sql, Object... args) {
		int result = 0;
		Connection con = getconnnection();
		PreparedStatement ps = null;
		try {
			ps = con.prepareStatement(sql);
			if (args != null) {
				for (int i = 0; i < args.length; i++) {
					ps.setObject((i + 1), args[i]);
				}
			}
			result = ps.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			close(ps, con);
		}

		return result;
	}
1223509
async function tryExample () {

  // Migration scripts
  const migrations = {

    // Called only if no migration has ever executed
    async 'none' (db) {
      const {User} = db.resources

      // Migration scripts
      await User.each(async (user) => {
        const {username} = user
        await user.update({name: username, username: null})
      })
      /* ... */

      await db.updateVersion('1.0.0') // Update to next version
    },

    async '1.0.0' (db) {
      /* ... */
      await db.updateVersion('1.0.1')
    }
  }
  await db.migrate(migrations)
}
1197038
function modelItem(data, model) {
    var res = {};

    utils.defineProperties(res, {
        _isModelItem: { value: true },

        model: { value: model.value },

        update: { value: function(data, sync) {
            if (sync == null) sync = true;

            return update(res, model, data).then(function() {
                if (!sync) return;
                return res.save();
            });
        } },

        save: { value: function() {
            if (_.has(res, 'id')) {
                var props = serverProperties(res, model);
                return utils.socketPost(model.io, model.url + '/update/' + res.id, props.properties).then(function() {
                    return Promise.all(_.map(props.refresh, function(item) {
                        return item.refresh();
                    }));
                });
            }
            return create(res, model);
        } },

        refresh: { value: function() {
            if (!_.has(res, 'id')) return create(res, model);

            return utils.socketGet(model.io, model.url + '/' + res.id).then(function(data) {
                return update(res, model, data, { noRefresh: true });
            });
        } },

        delete: { value: function() {
            model._removeItem(res);
            return utils.socketDelete(model.io, model.url, { id: res.id });
        } },

        matches: { value: function(query) {
            return utils.socketGet(model.io, model.url, query).then(function(r) {
                for (var i = 0; i < r.length; i++) {
                    if (r[i].id === res.id) return true;
                }
                return false;
            });
        } },

        then: { value: function() {
            return res.ready.then.apply(res.ready, arguments);
        } },

        catch: { value: function() {
            return res.ready.catch.apply(res.ready, arguments);
        } }
    });

    res.ready = Promise.resolve();

    update(res, model, data || {});

    return res;
}
598819
function (args) {
            args = argsToArray(arguments);
            if (this.__fired) {
                throw new Error("Already fired!");
            }
            this.__results = args;
            this.__resolve();
            return this.promise();
        }
337058
function () {
            var q = this._getPrimaryKeyQuery(), changed = this.__changed;
            var modelStatic = this._static,
                ctiColumns = modelStatic.__ctiColumns,
                tables = modelStatic.__ctiTables,
                self = this;
            return new PromiseList(tables.map(function (table) {
                var cols = ctiColumns[table], update = {};
                cols.forEach(function (c) {
                    if (!comb.isUndefined(changed[c])) {
                        update[c] = changed[c];
                    }
                });
                return comb.isEmpty(update) ? new Promise().callback() : self.db.from(table).filter(q).update(update);
            }), true)
                .chain(function () {
                    return self._updateReload();
                })
                .promise();
        }
94847
function argReq (method, path) {
  return async function (args, data) {
    // `args` can either be a single value or an array
    if (Array.isArray(args)) {
      args = args.join('/')
    }
    return await this.request(method, `${path}/${args}`, data)
  }
}
171811
public static void update(String sql, Object... arg) {
        Connection connection = JDBCUtils.getConnection();
        PreparedStatement ps = null;
        try {
            ps = connection.prepareStatement(sql);
            for (int i = 0; i < arg.length; i++) {
                ps.setObject(i + 1, arg[i]);
            }
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        JDBCUtils.release(ps, connection);
    }
506449
async function one2one (source, model, args = {}, t) {
  let sourceId = `${this.name}Id`
  let previous = await this.models[model].findOne({
    where: {[sourceId]: source.id},
    transaction: t
  })

  if (!args.hasOwnProperty(sourceId)) {
    args[sourceId] = source.id
  }
  let insert = await util.insertOrUpdate(this.models[model], args, t)

  if (insert) {
    await previous.update({[sourceId]: null}, {transaction: t})
  }
}
927635
function runTool(platform, args, done) {
  var inputFile1 = args[0];
  var inputFile2 = args[1];
  var filterString = args[2];
  if (!inputFile1 || !inputFile2) {
    console.log('usage: diff.js file1.wtf-trace file2.wtf-trace [filter]');
    done(1);
    return;
  }
  console.log('Diffing ' + inputFile1 + ' and ' + inputFile2 + '...');
  console.log('');

  var filter = null;
  if (filterString) {
    filter = new wtf.db.Filter(filterString);
  }

  // Create databases for querying.
  var db1 = null;
  var db2 = null;
  wtf.db.load(inputFile1, function(db) {
    if (db instanceof Error) {
      console.log('ERROR: unable to open ' + inputFile1, db);
      done(1);
      return;
    }

    db1 = db;
    if (db1 && db2) {
      diffDatabases(db1, db2, filter);
      done(0);
    }
  });
  wtf.db.load(inputFile2, function(db) {
    if (db instanceof Error) {
      console.log('ERROR: unable to open ' + inputFile2, db);
      done(1);
      return;
    }

    db2 = db;
    if (db1 && db2) {
      diffDatabases(db1, db2, filter);
      done(0);
    }
  });
}
769555
function refreshSyncers(keys) {
	if (typeof keys === 'string') {
		keys = [keys]
	}
	if (!keys) {
		keys = Object.keys(this._syncers)
	}
	return Promise.all(keys.map(key => {
		return this._syncers[key].refresh()
	}))
}
1284561
function schema (args) {
    // get args object
    args = requireValidOptionalObject(args)
    // get colunmn and index information from database
    return Promise.all([
        this.mysql().query(sql.describe(this)),
        this.mysql().query(sql.showCreateTable(this)),
        this.mysql().query(sql.showIndexes(this)),
    ])
    // build schema from database response
    .then(res => {
        // get columns and indexes from describe and show index queries
        var columns = res[0][0]
        var createTable = res[1][0]
        var indexes = res[2][0]
        // schema data
        var schema = {
            columns: {},
            indexes: [],
        }
        // get first and only create table record
        createTable = _.get(createTable, "[0]['Create Table']", '')
        // get engine and charset from create table sql
        var engine = createTable.match(/ENGINE=(\w+)/)
        schema.engine = engine && engine[1] || ''
        var charset = createTable.match(/DEFAULT CHARSET=(\w+)/)
        schema.charset = charset && charset[1] || ''
        // build column data
        _.each(columns, dbColumn => {
            var column = schema.columns[dbColumn.Field] = {}
            // check unsigned
            if (dbColumn.Type.match(/unsigned$/)) {
                column.unsigned = true
                dbColumn.Type = dbColumn.Type.replace(/ unsigned/, '')
            }
            // char id column
            if (dbColumn.Type === 'char(32)') {
                // model must not be set for binary ids
                assert.ok(this.binaryIds === false, 'binaryIds must be disabled for char id columns')
                // set type
                column.type = 'id'
            }
            // binary id column
            else if (dbColumn.Type === 'binary(16)') {
                // model must be set for binary ids
                assert.ok(this.binaryIds === true, 'binaryIds must be enabled for binary id columns')
                // set type
                column.type = 'id'
            }
            // all other column types
            else  {
                // require valid type
                assert.ok(sql.columnTypesInverse[dbColumn.Type], 'unrecognized column type '+dbColumn.Type)
                // map database to internal type
                column.type = sql.columnTypesInverse[dbColumn.Type]
            }
            // is column nullable
            if (dbColumn.Null === 'NO') {
                column.null = false
            }
            // set default if not null
            if (dbColumn.Default) {
                column.default = dbColumn.Default
                // convert boolean
                if (column.type === 'boolean') {
                    column.default = column.default === '1' ? true : false
                }
            }
        })
        // map of indexes by key name since keys may cover multiple columns
        var indexesByKey = {}
        // build map of indexes by key name
        _.each(indexes, dbIndex => {
            // create entry for index if it does not already exist
            if (!indexesByKey[dbIndex.Key_name]) {
                indexesByKey[dbIndex.Key_name] = {
                    columns: {}
                }
            }
            // get entry for index
            var index = indexesByKey[dbIndex.Key_name]
            // add column with sequence in index
            index.columns[dbIndex.Column_name] = parseInt(dbIndex.Seq_in_index)
            // add unique flag if true
            if (dbIndex.Non_unique === '0') {
                index.unique = true
            }
        })
        // add indexes to schema
        _.each(indexesByKey, (index, name) => {
            var indexColumns = _.keys(index.columns)
            // multi-column index
            if (indexColumns.length > 1) {
                // sort index columns by the Seq_in_index value - these may
                // always be in order so this may not be needed
                indexColumns = _.sortBy(indexColumns, indexColumn => index.columns[indexColumn])
                // create schema index entry
                var schemaIndex = {
                    columns: indexColumns,
                }
                // set unique flag
                if (index.unique) {
                    schemaIndex.unique = true
                }
                // add index to schema
                schema.indexes.push(schemaIndex)
            }
            // single column index
            else {
                // get first and only column
                var indexColumn = indexColumns[0]
                // PRIMARY KEY
                if (name === 'PRIMARY') {
                    schema.columns[indexColumn].primary = true
                }
                // unique index
                else if (index.unique) {
                    schema.columns[indexColumn].unique = true
                }
                // non-unique index
                else {
                    schema.columns[indexColumn].index = true
                }
            }
        })
        // resolve with schema
        return schema
    })
    .catch(err => {
        // reject on anything besides a table does not exist error
        // if table does not exist resolve with undefined
        if (err.errno !== 1146) {
            throw err
        }
    })
}
1316200
async function run () {
  const {host, port, database, username: user, password, idleTimeoutMillis} = config()
  const client = new Client({host, port, database: 'postgres', user, password, idleTimeoutMillis})

  await client.connect()
  await client.query(`DROP DATABASE IF EXISTS ${database}`)
  await client.query(`CREATE DATABASE ${database}`)
  await client.end()
  console.log(`\x1b[32m\u2714 Database \x1b[1m${database}\x1b[22m created successfully!\x1b[0m`)
}
513697
async function validateDeleted (args) {
    try {
        var deletedTable = await this.mysql().query(
            sql.showCreateTable({name: `${this.name}Delete`}), {}, {}, args.session
        )
    }
    // exception will be thrown if table does not exist
    catch (err) {
        return
    }
    // get deleted records
    const [ results ] = await this.mysql().query(sql.selectDeleted(this))
    debug(`checking ${results.length} deleted records`)
    // check each record and delete if needed
    for (const result of results) {
        // load current record
        var record = await this.query({
            allow: true,
            cache: false,
            current: true,
            one: true,
            session: args.session,
            where: { id: result.id }
        })
        // skip if record not found
        if (!defined(record)) {
            continue
        }
        // skip if id does not match
        if (record.id !== result.id) {
            continue
        }
        // skip if record already deleted
        if (record.isDeleted) {
            continue
        }
        debug(`deleting ${record.id}`)
        // delete record
        await record.delete({allow: true, cache: false})
    }
}
429089
function runTool(platform, args, done) {
  if (args.length < 1) {
    console.log('usage: query.js file.wtf-trace "[query string]"');
    done(1);
    return;
  }

  var inputFile = args[0];
  var exprArgs = args.slice(1);
  var expr = exprArgs.join(' ').trim();

  console.log('Querying ' + inputFile + '...');

  // Create database for querying.
  var loadStart = wtf.now();
  wtf.db.load(inputFile, function(db) {
    if (db instanceof Error) {
      console.log('ERROR: unable to open ' + inputFile, db);
      done(1);
      return;
    }

    var loadDuration = wtf.now() - loadStart;
    console.log('Database loaded in ' + loadDuration.toFixed(3) + 'ms');
    console.log('');

    queryDatabase(db, expr);

    done(0);
  });
}