<?php
//  ---------------------------------------------------------------------------------
//    _____   _             _                   _   _____
//   |  __ \ | |           | |    /\           (_) |  __ \
//   | |__) || |__    __ _ | |   /  \    _ __   _  | |__) |_ __  ___
//   |  ___/ | '_ \  / _` || |  / /\ \  | '_ \ | | |  ___/| '__|/ _ \
//   | |     | | | || (_| || | / ____ \ | |_) || | | |    | |  | (_) |
//   |_|     |_| |_| \__,_||_|/_/    \_\| .__/ |_| |_|    |_|   \___/
//                                      | |
//                                      |_|
//   PhalApi Pro 专业版
//   广州果创网络科技有限公司
//
//  ---------------------------------------------------------------------------------
//
//   一、协议的许可和权利
//    1. 您可以在完全遵守本协议的基础上，将本软件应用于商业用途；
//    2. 您可以在协议规定的约束和限制范围内修改本产品源代码或界面风格以适应您的要求；
//    3. 您拥有使用本产品中的全部内容资料、商品信息及其他信息的所有权，并独立承担与其内容相关的
//       法律义务；
//    4. 获得商业授权之后，您可以将本软件应用于商业用途，自授权时刻起，在技术支持期限内拥有通过
//       指定的方式获得指定范围内的技术支持服务；
//
//   二、协议的约束和限制
//    1. 未获商业授权之前，禁止将本软件用于商业用途（包括但不限于企业法人经营的产品、经营性产品
//       以及以盈利为目的或实现盈利产品）；
//    2. 未获商业授权之前，禁止在本产品的整体或在任何部分基础上发展任何派生版本、修改版本或第三
//       方版本用于重新开发；
//    3. 如果您未能遵守本协议的条款，您的授权将被终止，所被许可的权利将被收回并承担相应法律责任；
//
//   三、有限担保和免责声明
//    1. 本软件及所附带的文件是作为不提供任何明确的或隐含的赔偿或担保的形式提供的；
//    2. 用户出于自愿而使用本软件，您必须了解使用本软件的风险，在尚未获得商业授权之前，我们不承
//       诺提供任何形式的技术支持、使用担保，也不承担任何因使用本软件而产生问题的相关责任；
//    3. 广州果创网络科技有限公司不对使用本产品构建的商城中的内容信息承担责任，但在不侵犯用户隐
//       私信息的前提下，保留以任何方式获取用户信息及商品信息的权利；
//
//   有关本产品最终用户授权协议、商业授权与技术服务的详细内容，均由广州果创网络科技有限公司独家
//   提供。广州果创网络科技有限公司拥有在不事先通知的情况下，修改授权协议的权力，修改后的协议对
//   改变之日起的新授权用户生效。电子文本形式的授权协议如同双方书面签署的协议一样，具有完全的和
//   等同的法律效力。您一旦开始修改、安装或使用本产品，即被视为完全理解并接受本协议的各项条款，
//   在享有上述条款授予的权力的同时，受到相关的约束和限制。协议许可范围以外的行为，将直接违反本
//   授权协议并构成侵权，我们有权随时终止授权，责令停止损害，并保留追究相关责任的权力。
//
//  ---------------------------------------------------------------------------------

namespace Base\Model;

/**
 * 数据库基类
 * 
 * - 封装更多实用的接口和函数，减轻数据库开发的成本
 * - 更多数据库操作，请见：http://docs.phalapi.net/#/v2.0/database-datamodel
 */
class Base extends \PhalApi\Model\DataModel {

    /**
     * 根据一个字段获取一条数据纪录
     * @param string $field 数据库表字段名
     * @param mixed $value 待精确匹配的字段值
     * @param mixed $default 数据不存在时的默认值
     * @param string $select 需要选择的字段，多个字段用英文逗号分割
     * @return string|mixed 获取成功返回数组，失败返回默认值（未指定默认值时为false）
     */
    public function getBy($field, $value, $default = false, $select = '*') {
        $row = $this->getORM()->select($select)->where($field, $value)->fetchOne();
        return $row ? $row : $default;
    }

    /**
     * 根据条件获取列表数据，支持分页
     * @param array $whereParam where条件，数组格式
     * @param string $select 需要选择的字段，多个字段用英文逗号分割
     * @param int $page 第几页
     * @param int $limit 返回多少条
     * @return array
     */
//     public function getAllBy($whereParam = array(), $select = '*', $page = 1, $limit = 100) {
//         $orm = $this->getORM()->select($select)->page($page, $limit);
//         return !empty($whereParam) ? $orm->where($whereParam)->fetchAll() : $orm->fetchAll();
//     }
    
    /**
     * 获取总数量
     * @return int
     */
    public function getAllNum(){
        return $this->getORM()->count('*');
    }
    
    /**
     * 获取分页列表数据，返回总数以及分页的列表数据
     * @param string/array $select 选择的字段，默认*表示全部字段，可以字符串（如：id,name）或数组（如：array('id', 'name')）
     * @param string/array $where WHERE条件，默认不添加任何条件判断，可以是数组或者字符串，详细使用可参考：http://docs.phalapi.net/#/v2.0/database-usage
     * @param array $whereParams WHERE参数部分，可有效防止SQL注入攻击，动态参数建议使用此参数传入，支持索引数组和关联数组两种写法
     * @param string/array $order 排序部分，黑夜为空按数据库默认排序，可能是字符串（如：id ASC）或数组（如：array('id ASC', 'name DESC')）
     * @param number $page 第几页，默认为第1页
     * @param number $perpage 分页数量，每页多少条
     * @return array 返回结构：array('total' => 总数, 'items' => 列表数组, 'page' => 第几页, 'perpage' => 分页数量)
     */
    public function getListEx($where = NULL, $whereParams = array(), $select = '*', $order = NULL, $page = 1, $perpage = 100) {
        $total = 0;
        $items = array();

        $page = intval($page);
        $perpage = intval($perpage);
        
        $orm = $this->getORM();

        // 条件
        if (!empty($where) && !empty($whereParams)) {
            $orm->where($where, $whereParams);
        } else if (!empty($where)) {
            $orm->where($where);
        }

        // 总数
        $total = $orm->count('*');

        if ($total > 0) {
            // 字段选择
            $select = is_array($select) ? implode(',', $select) : $select;
            $orm->select($select);

            // 排序
            $order = is_array($order) ? implode(', ', $order) : $order;
            if (!empty($order)) {
                $orm->order($order);
            }

            // 分页
            $items = $orm->page($page, $perpage)->fetchAll();
        }

        return array('total' => intval($total), 'items' => $items, 'page' => $page, 'perpage' => $perpage);
    }

    /**
     * 获取列表数据，不分页的列表数据
     * @param string/array $select 选择的字段，默认*表示全部字段，可以字符串（如：id,name）或数组（如：array('id', 'name')）
     * @param string/array $where WHERE条件，默认不添加任何条件判断，可以是数组或者字符串，详细使用可参考：http://docs.phalapi.net/#/v2.0/database-usage
     * @param array $whereParams WHERE参数部分，可有效防止SQL注入攻击，动态参数建议使用此参数传入，支持索引数组和关联数组两种写法
     * @param string/array $order 排序部分，黑夜为空按数据库默认排序，可能是字符串（如：id ASC）或数组（如：array('id ASC', 'name DESC')）
     * @param number $page 第几页，默认为第1页
     * @param number $perpage 分页数量，每页多少条
     * @return array 返回结构：array('total' => 总数, 'items' => 列表数组, 'page' => 第几页, 'perpage' => 分页数量)
     */
    public function getAllList($where = NULL, $whereParams = array(), $select = '*', $order = NULL) {
        $items = array();
        $orm = $this->getORM();

        // 条件
        if (!empty($where) && !empty($whereParams)) {
            $orm->where($where, $whereParams);
        } else if (!empty($where)) {
            $orm->where($where);
        }
        // 字段选择
        $select = is_array($select) ? implode(',', $select) : $select;
        $orm->select($select);

        // 排序
        $order = is_array($order) ? implode(', ', $order) : $order;
        if (!empty($order)) {
            $orm->order($order);
        }

        $items = $orm->fetchAll();

        return $items;
    }

    /**
     * 获取列表前面多少条数据，区别在于获取前面N条，并且不会统计全部的总数，减少性能损耗
     * @param string/array $select 选择的字段，默认*表示全部字段，可以字符串（如：id,name）或数组（如：array('id', 'name')）
     * @param string/array $where WHERE条件，默认不添加任何条件判断，可以是数组或者字符串，详细使用可参考：http://docs.phalapi.net/#/v2.0/database-usage
     * @param array $whereParams WHERE参数部分，可有效防止SQL注入攻击，动态参数建议使用此参数传入，支持索引数组和关联数组两种写法
     * @param string/array $order 排序部分，黑夜为空按数据库默认排序，可能是字符串（如：id ASC）或数组（如：array('id ASC', 'name DESC')）
     * @param number $topNum 前面多少条
     * @return array 列表结果集
     */
    public function getTopList($select = '*', $where = '', $whereParams = array(), $order = '', $topNum = 100) {
        $topNum = intval($topNum);
        
        $orm = $this->getORM();
        
        // 条件
        if (!empty($where) && !empty($whereParams)) {
            $orm->where($where, $whereParams);
        } else if (!empty($where)) {
            $orm->where($where);
        }
        
        // 字段选择
        $select = is_array($select) ? implode(',', $select) : $select;
        $orm->select($select);
        
        // 排序
        $order = is_array($order) ? implode(', ', $order) : $order;
        if (!empty($order)) {
            $orm->order($order);
        }
        
        // 分页
        return $orm->page(1, $topNum)->fetchAll();
    }
    /**
     * 根据字段更新数据
     * @param string $field 字段名
     * @param mixed $value 字段值
     * @param array $data 更新数据
     * @return int 更新的条数，false为更新失败，0为无更新，其他正数表示更新的条数
     */
    public function updateBy($field, $value, $data) {
        return $this->getORM()->where($field, $value)->update($data);
    }

    /**
     * 根据字段删除数据
     * @param string $field 字段名
     * @param mixed $value 字段值
     * @return int 删除的条数，false为删除失败，0为无删除，其他正数表示删除的条数
     */
    public function deleteBy($field, $value) {
        return $this->getORM()->where($field, $value)->delete();
    }



}
