判断是否存在关联数据
@access public
@param  mixed $data  数据 可以使用关联模型对象 或者 关联对象的主键
@return Pivot
@throws Exception
171480
public function attached($data)
    {
        if ($data instanceof Model) {
            $id = $data->getKey();
        } else {
            $id = $data;
        }

        $pivot = $this->pivot
            ->where($this->localKey, $this->parent->getKey())
            ->where($this->foreignKey, $id)
            ->find();

        return $pivot ?: false;
    }
1239098
protected function transform($data)
    {
        if (!$data instanceof GetSchema\Schema) {
            throw new Exception('Data is not a Schema.');
        }

        $definition = $data->getTableDefinition($this->table);
        $defSchema = $definition->getSchema();

        $returnData = [];
        $row = [
            self::KEY_TABLE => $definition->getName(),
            0 => $definition->getName(),
            self::KEY_CREATE_TABLE => $defSchema,
            1 => $defSchema,
        ];
        $returnData[] = $row;

        return $returnData;
    }
179418
public function savePermission($data = [])
    {
        if (!empty($data)) {
            $this->data($data);
        }
        $validate = new \gmars\rbac\validate\Permission();
        if (!$validate->check($this)) {
            throw new Exception($validate->getError());
        }
        $data = $this->getData();
        if (isset($data['id']) && !empty($data['id'])) {
            $this->isUpdate(true);
        }
        $this->save();
        return $this;
    }
855379
public function update(array $data = [])
    {
        $options = $this->parseExpress();
        $data    = array_merge($options['data'], $data);
        $pk      = $this->getPk($options);
        $where   = [];
        if (isset($options['cache']) && is_string($options['cache']['key'])) {
            $key = $options['cache']['key'];
        }

        if (empty($options['where'])) {
            // 如果存在主键数据 则自动作为更新条件
            if (is_string($pk) && isset($data[$pk])) {
                $where[$pk] = $data[$pk];
                if (!isset($key)) {
                    $key = 'think:' . $options['table'] . '|' . $data[$pk];
                }
                unset($data[$pk]);
            } elseif (is_array($pk)) {
                // 增加复合主键支持
                foreach ($pk as $field) {
                    if (isset($data[$field])) {
                        $where[$field] = $data[$field];
                    } else {
                        // 如果缺少复合主键数据则不执行
                        throw new Exception('miss complex primary data');
                    }
                    unset($data[$field]);
                }
            }
            if (!isset($where)) {
                // 如果没有任何更新条件则不执行
                throw new Exception('miss update condition');
            } else {
                $options['where']['AND'] = $where;
            }
        } elseif (!isset($key) && is_string($pk) && isset($options['where']['AND'][$pk])) {
            $key = $this->getCacheKey($options['where']['AND'][$pk], $options, $this->bind);
        }

        //过滤无效字段
        $this->filter($data);

        // 生成UPDATE SQL语句
        $sql = $this->builder->update($data, $options);
        // 获取参数绑定
        $bind = $this->getBind();
        if ($options['fetch_sql']) {
            // 获取实际执行的SQL语句
            return $this->connection->getRealSql($sql, $bind);
        } else {
            // 执行操作
            $result = '' == $sql ? 0 : $this->execute($sql, $bind);
            if ($result) {
                if (is_string($pk) && isset($where[$pk])) {
                    $data[$pk] = $where[$pk];
                } elseif (is_string($pk) && isset($key) && strpos($key, '|')) {
                    list($a, $val) = explode('|', $key);
                    unset($a);
                    $data[$pk]     = $val;
                }
                $options['data'] = $data;
                $this->trigger('after_update', $options);
            }
            return $result;
        }
    }
1081906
public function addIndex(array $data)
    {
        if (!is_array($data)) {
            throw new \Exception('你的索引参数不是一个数组');
        }
        if (isset($data[0]) && is_array($data[0])) {
            // 多维数组
            foreach ($data as $v) {
                $this->getIndex()->add(new \XSDocument($v));
            }
        } else {
            // 一维数组
            $this->getIndex()->add(new \XSDocument($data));
        }
        //索引是否立即生效
        if ($this->flush_index) {
            $this->getIndex()->flushIndex();
        }
        return $this->getIndex();
    }
652650
final public function setData($data) {
        if ((is_object($data) && !is_a($data, 'Object')) || (!is_object($data) && !is_array($data)))
            throw new \Exception('Data must be either an array or an object that extends Object: ' . gettype($data));
        $data = is_array($data) ? $data : $data->toArray();
        foreach ($data as $attr => $value) {
            if ($this->elements[$attr]) {
                $this->elements[$attr]->setData($value);
            } else
                $this->data[$attr] = $value;
        }
        $this->valid = null;
        return $this;
    }
525076
public function copyFrom($data)
    {
        if (is_array($data) || $data instanceof \Traversable) {
            if ($this->getCount() > 0) {
                $this->clear();
            }
            if ($data instanceof CMap) {
                $data = $data->_data;
            }
            foreach ($data as $key => $value) {
                $this->add($key, $value);
            }
        } elseif ($data !== null) {
            throw new Exception('实例化列表参数必须是数组或可遍历的对象', 100100601);
        }
    }
811182
public function execute($data = null)
    {
        if (!isset($data->db) || !$data->db instanceof AbstractDatabaseDriver) {
            return $this->next->execute($data);
        }

        if ($data->debug) {
            $this->logger->log(LogLevel::DEBUG, 'Executed: {sql}', ['sql' => $data->sql]);
        }

        try {
            $result = $this->next->execute($data);
        } catch (\RuntimeException $e) {
            // Throw the normal query exception.
            $this->logger->log(
                LogLevel::ERROR,
                'Database query failed (error #{code}): {message}',
                ['code' => $e->getCode(), 'message' => $e->getMessage()]
            );

            throw new $e();
        }

        return $result;
    }
460187
public function createFromImportedData($data)
    {
        $group = new Group($data['name'], $data['include_pattern'], $data['exclude_pattern']);
        if (isset($data['type'])) {
            $group->setType($data['type']);
        }
        $group->setOrdering($data['ordering']);
        foreach ($data['classes'] as $className => $classData) {
            $group->addClass($this->getGroupClassFactory()->createFromImportedData($className, $classData));
        }
        return $group;
    }
1187522
protected function fieldSet(array $data)
    {
        if (!$this->tableSchema['field']) {
            throw new Exception('请在' . get_class($this) . '构造函数中调用父类的构造函数');
        }
        return \wf\db\QueryBuilder::buildSqlSet($data, $this->tableSchema['field'], $this->lockedFields);
    }
1301451
public function setDataLinked(array &$data) {
		$this->_data   = [];
		$this->_models = [];
		
		$modelClass = $this->getModel();
		
		foreach ($data as $key => &$item) {
			if (is_object($item)) {
				if (! $item instanceof $modelClass) {
					throw new Exception('Model must be an instance of "' . $modelClass . '"');
				}
				
				$this->_data[$key]   = &$item->getDataLinked();
				$this->_models[$key] = $item;
			}
			elseif (is_array($item)) {
				$this->_data[$key] = &$item;
			}
			else {
				throw new Exception('Unknown type of item: "' . gettype($item) . '"');
			}
		}
		unset($item);
		
		$this->_pointer = 0;
		$this->_map     = array_keys($this->_data);
		
		return $this;
	}
1123272
public function delete($data = null)
    {
        // 分析查询表达式
        $options = $this->parseExpress();
        $pk      = $this->getPk();
        if (!is_null($data) && true !== $data) {
            if (!is_array($data)) {
                // 缓存标识
                $key = 'mongo:' . $options['table'] . '|' . $data;
            }
            // AR模式分析主键条件
            $this->parsePkWhere($data, $options);
        } elseif (!isset($key) && is_string($pk) && isset($options['where']['$and'][$pk])) {
            $key = $this->getCacheKey($options['where']['$and'][$pk], $options);
        }

        if (true !== $data && empty($options['where'])) {
            // 如果不是强制删除且条件为空 不进行删除操作
            throw new Exception('delete without condition');
        }

        // 生成bulkWrite对象
        $bulk         = $this->builder->delete($options);
        $writeConcern = isset($options['writeConcern']) ? $options['writeConcern'] : null;
        // 执行操作
        $writeResult = $this->execute($options['table'], $bulk, $writeConcern);

        $result = $writeResult->getDeletedCount();
        if ($result) {
            if (!is_array($data) && is_string($pk) && isset($key) && strpos($key, '|')) {
                list($a, $val) = explode('|', $key);
                unset($a);
                $item[$pk]     = $val;
                $data          = $item;
            }
            $options['data'] = $data;
            $this->trigger('after_delete', $options);
        }
        return $result;
    }
784811
public function thaw($data)
    {
        try {
            $value = Parser::fromString($data);
        } catch (Exception $e) {
            throw new Exception\TomlThawException($e);
        }

        return $value;
    }
24416
public function select($data = null)
    {
        if ($data instanceof Query) {
            return $data->select();
        } elseif ($data instanceof \Closure) {
            call_user_func_array($data, [ & $this]);
            $data = null;
        }
        // 分析查询表达式
        $options = $this->parseExpress();

        if (false === $data) {
            // 用于子查询 不查询只返回SQL
            $options['fetch_sql'] = true;
        } elseif (!is_null($data)) {
            // 主键条件分析
            $this->parsePkWhere($data, $options);
        }

        // 生成查询SQL
        $sql = $this->builder->select($options);
        // 获取参数绑定
        $bind = $this->getBind();
        if ($options['fetch_sql']) {
            // 获取实际执行的SQL语句
            return $this->connection->getRealSql($sql, $bind);
        }

        $options['data'] = $data;
        if ($resultSet = $this->trigger('before_select', $options)) {
        } else {
            // 执行查询操作
            $resultSet = $this->query($sql, $bind, $options['master'], $options['fetch_pdo']);

            if ($resultSet instanceof \PDOStatement) {
                // 返回PDOStatement对象
                return $resultSet;
            }
        }

        // 返回结果处理
        if (!empty($options['fail']) && count($resultSet) == 0) {
            $this->throwNotFound($options);
        }
        return $resultSet;
    }
916227
public function update(array $data)
    {
        $where = [];
        $options = $this->parseExpress();
        $data    = array_merge($options['data'], $data);
        if (isset($options['cache']) && is_string($options['cache']['key'])) {
            $key = $options['cache']['key'];
        }
        $pk = $this->getPk();
        if (empty($options['where'])) {
            // 如果存在主键数据 则自动作为更新条件
            if (is_string($pk) && isset($data[$pk])) {
                $where[$pk] = $data[$pk];
                $key        = 'mongo:' . $options['table'] . '|' . $data[$pk];
                unset($data[$pk]);
            } elseif (is_array($pk)) {
                // 增加复合主键支持
                foreach ($pk as $field) {
                    if (isset($data[$field])) {
                        $where[$field] = $data[$field];
                    } else {
                        // 如果缺少复合主键数据则不执行
                        throw new Exception('miss complex primary data');
                    }
                    unset($data[$field]);
                }
            }
            if (!isset($where)) {
                // 如果没有任何更新条件则不执行
                throw new Exception('miss update condition');
            } else {
                $options['where']['$and'] = $where;
            }
        } elseif (!isset($key) && is_string($pk) && isset($options['where']['$and'][$pk])) {
            $key = $this->getCacheKey($options['where']['$and'][$pk], $options);
        }

        // 生成bulkWrite对象
        $bulk         = $this->builder->update($data, $options);
        $writeConcern = isset($options['writeConcern']) ? $options['writeConcern'] : null;
        $writeResult  = $this->execute($options['table'], $bulk, $writeConcern);

        $result = $writeResult->getModifiedCount();
        if ($result) {
            if (isset($where[$pk])) {
                $data[$pk] = $where[$pk];
            } elseif (is_string($pk) && isset($key) && strpos($key, '|')) {
                list($a, $val) = explode('|', $key);
                unset($a);
                $data[$pk]     = $val;
            }
            $options['data'] = $data;
            $this->trigger('after_update', $options);
        }
        return $result;
    }
446604
public function saveRole($permissionIds = '', $data = [])
    {
        if (!empty($data)) {
            $this->data($data);
        }
        $validate = new \gmars\rbac\validate\Role();
        if (!$validate->check($this)) {
            throw new Exception($validate->getError());
        }
        $data = $this->getData();
        if (isset($data['id']) && !empty($data['id'])) {
            $this->isUpdate(true);
        }
        $this->startTrans();
        $this->save();
        //如果有权限的情况下
        if (empty($permissionIds)) {
            return $this;
        }
        $permissionIdsArr = array_filter(explode(',', $permissionIds));
        if (empty($permissionIdsArr)) {
            return $this;
        }
        //删除原有权限
        $rolePermission = new RolePermission($this->connection);
        if ($rolePermission->where('role_id', $this->id)->delete() === false) {
            $this->rollback();
            throw new Exception('删除原有权限时出错');
        }
        $writeData = [];
        foreach ($permissionIdsArr as $v)
        {
            $writeData[] = [
                'role_id' => $this->id,
                'permission_id' => $v
            ];
        }
        if ($rolePermission->saveAll($writeData) === false) {
            $this->rollback();
            throw new Exception('写入角色权限时出错');
        }
        $this->commit();
        return $this;
    }
438571
public static function hidrateModel($class, $data)
    {
        if ($data instanceof Model) {
            return $data;
        }

        if (!isset($data['pivot'])) {
            throw new \Exception("The 'pivot' attribute in the {$class} is hidden");
        }

        $model = new $class;
        $primaryKey = $model->getKeyName();

        $model->setAttribute($primaryKey, $data[$primaryKey])->setAttribute('name', $data['name']);
        $model->setRelation(
            'pivot',
            MorphPivot::fromRawAttributes($model, $data['pivot'], 'pivot_table')
        );

        return $model;
    }