public function upsert(array $values, $whereColumn = 'id',
            $generateIds = true) {
        if (!is_array($whereColumn)) $whereColumn = array($whereColumn);

        if (!$this->checkExists()) return false;

        $this->current = self::OP_INSERT;
        $this->query = 'INSERT INTO `' . $this->name . '` (';
        $columns = array();
        $noOfColumns = 0;
        $update = '';
        foreach (array_values($values) as $ky => $row) {
            $rowArray = $this->checkModel($row, true);
            if ($ky === 0) $noOfColumns = count($rowArray);

            if (count($rowArray) === 0)
                    throw new Exception('You cannot insert an empty row into table "' . $this->name . '"');

            if ($generateIds) {
                $id = is_string($generateIds) ? $generateIds : 'id';
                if (!array_key_exists($id, $rowArray))
                        $rowArray[$id] = Util::createGUID();
            }

            if ($generateIds) {
                $id = is_string($generateIds) ? $generateIds : 'id';
                if (!array_key_exists($id, $rowArray))
                        $rowArray[$id] = Util::createGUID();
            }

            foreach ($rowArray as $column => &$value) {
                if (empty($value) && $value != 0) continue;

                $column = Util::camelTo_($column);

                if (!$ky && !in_array($column, $whereColumn)) {
                    if ($update) $update .= ', ';
                    $update .= '`' . $column . '`=VALUES(' . $column . ')';
                }

                if (!in_array($column, $columns)) $columns[] = $column;
                $this->values[$ky][':' . $column] = $value;
            }
        }

        $this->query .= '`' . join('`, `', $columns) . '`';
        $this->query .= ') VALUES (';
        $this->query .= ':' . join(', :', $columns);
        $this->query .= ') ON DUPLICATE KEY UPDATE ';
        $this->query .= $update;

        $this->multiple = true;
        $this->doPost = self::OP_INSERT;
        if ($this->delayExecute) {
            return $this;
        }

        return $this->execute();
    }