package com.yanzuoguang.dao;


import com.yanzuoguang.dao.impl.TableSqlCache;
import com.yanzuoguang.util.vo.DataDaoVo;
import com.yanzuoguang.util.vo.PageSizeData;
import com.yanzuoguang.util.vo.PageSizeReqVo;

import java.util.Collection;
import java.util.List;

/**
 * 数据基本操作接口
 *
 * @author 颜佐光
 */
public interface BaseDao {

    /**
     * 获取表结构
     *
     * @return 表结构
     */
    TableSqlCache getTable();

    /**
     * 创建数据,当不传入了主键时,则会自动生成主键,传入时不会生成。
     *
     * @param model 需要创建的数据
     * @return 创建的主键编号
     */
    String create(Object model);

    /**
     * 主键存在则更新,否则替换
     *
     * @param model
     * @return
     */
    String replace(Object model);

    /**
     * 修改数据
     *
     * @param model 需要修改的数据
     * @return 删除的主键编号
     */
    String update(Object model);

    /**
     * 保存数据,有主键时修改,无主键时创建
     *
     * @param model 需要保存的数据
     * @return 保存的主键编号
     */
    String save(Object model);

    /**
     * 删除数据,可以用于父子表删除,如通过订单删除游客信息 visitorDao.remove({orderId:1});
     * int field;
     *
     * @param model 需要删除的数据,可以是主键字符串(Int),或者是包含主键的实体,或者是包含其他非主键的实体完全匹配.
     * @return 删除的记录数量
     */
    int remove(Object model);

    /**
     * 加载数据,可以用于父子表删除,如通过订单删除游客信息 visitorDao.load({orderId:1});
     *
     * @param model       加载数据的请求参数,可以是主键字符串(Int),或者是包含主键的实体,或者是包含其他非主键的实体完全匹配.
     * @param resultClass 需要加载的数据的类型
     * @param <T>         返回数据的类型
     * @return 需要返回的数据
     */
    <T> T load(Object model, Class<T> resultClass);

    /**
     * 加载数据,可以用于父子表删除,如通过订单删除游客信息 visitorDao.load({orderId:1});
     *
     * @param model       加载数据的请求参数,可以是主键字符串(Int),或者是包含主键的实体,或者是包含其他非主键的实体完全匹配.
     * @param resultClass 需要加载的数据的类型
     * @param queryPara   查询参数
     * @param <T>         返回数据的类型
     * @return 需要返回的数据
     */
    <T> T load(Object model, Class<T> resultClass, QueryPara queryPara);


    /**
     * 加载列表数据,可以用于父子表删除,如通过订单删除游客信息 visitorDao.loadList({orderId:1});
     *
     * @param model       加载数据的请求参数,可以是主键字符串(Int),或者是包含主键的实体,或者是包含其他非主键的实体完全匹配.
     * @param resultClass 需要加载的数据的类型
     * @param <T>         返回数据的类型
     * @return 需要返回的数据
     */
    <T> List<T> loadList(Object model, Class<T> resultClass);

    /**
     * 加载列表数据,可以用于父子表删除,如通过订单删除游客信息 visitorDao.loadList({orderId:1});
     *
     * @param model       加载数据的请求参数,可以是主键字符串(Int),或者是包含主键的实体,或者是包含其他非主键的实体完全匹配.
     * @param resultClass 需要加载的数据的类型
     * @param queryPara   查询参数
     * @param <T>         返回数据的类型
     * @return 需要返回的数据
     */
    <T> List<T> loadList(Object model, Class<T> resultClass, QueryPara queryPara);

    /**
     * 加载分页数据
     *
     * @param model       加载数据的请求参数,可以是主键字符串(Int),或者是包含主键的实体,或者是包含其他非主键的实体完全匹配.
     * @param resultClass 需要加载的数据的类型
     * @param <T>         返回数据的类型
     * @return 需要返回的数据
     */
    <T> PageSizeData<T> loadPage(PageSizeReqVo model, Class<T> resultClass);

    /**
     * 加载分页数据
     *
     * @param model       加载数据的请求参数,可以是主键字符串(Int),或者是包含主键的实体,或者是包含其他非主键的实体完全匹配.
     * @param resultClass 需要加载的数据的类型
     * @param queryPara   查询参数
     * @param <T>         返回数据的类型
     * @return 需要返回的数据
     */
    <T> PageSizeData<T> loadPage(PageSizeReqVo model, Class<T> resultClass, QueryPara queryPara);

    /**
     * 加载分页数据
     *
     * @param pageReq     分页数据信息
     * @param model       加载数据的请求参数,可以是主键字符串(Int),或者是包含主键的实体,或者是包含其他非主键的实体完全匹配.
     * @param resultClass 需要加载的数据的类型
     * @param <T>         返回数据的类型
     * @return 需要返回的数据
     */
    <T> PageSizeData<T> loadPage(PageSizeReqVo pageReq, Object model, Class<T> resultClass);

    /**
     * 加载分页数据
     *
     * @param pageReq     分页数据信息
     * @param model       加载数据的请求参数,可以是主键字符串(Int),或者是包含主键的实体,或者是包含其他非主键的实体完全匹配.
     * @param resultClass 需要加载的数据的类型
     * @param queryPara   查询参数
     * @param <T>         返回数据的类型
     * @return 需要返回的数据
     */
    <T> PageSizeData<T> loadPage(PageSizeReqVo pageReq, Object model, Class<T> resultClass, QueryPara queryPara);

    /**
     * 加载分页数据
     *
     * @param model       加载数据的请求参数
     * @param resultClass 需要加载的数据的类型
     * @param <T>         返回数据的类型
     * @return 需要返回的数据
     */
    <T> List<T> loadPageData(PageSizeReqVo model, Class<T> resultClass);

    /**
     * 加载分页数据
     *
     * @param model       加载数据的请求参数
     * @param resultClass 需要加载的数据的类型
     * @param queryPara   查询参数
     * @param <T>         返回数据的类型
     * @return 需要返回的数据
     */
    <T> List<T> loadPageData(PageSizeReqVo model, Class<T> resultClass, QueryPara queryPara);

    /**
     * 加载分页数据
     *
     * @param model       加载数据的请求参数
     * @param resultClass 需要加载的数据的类型
     * @param <T>         返回数据的类型
     * @return 需要返回的数据
     */
    <T> List<T> loadPageData(PageSizeReqVo pageReq, Object model, Class<T> resultClass);

    /**
     * 加载分页数据
     *
     * @param model       加载数据的请求参数
     * @param resultClass 需要加载的数据的类型
     * @param queryPara   查询参数
     * @param <T>         返回数据的类型
     * @return 需要返回的数据
     */
    <T> List<T> loadPageData(PageSizeReqVo pageReq, Object model, Class<T> resultClass, QueryPara queryPara);

    /**
     * 修改数据
     *
     * @param model 需要修改的数据
     * @return 删除的主键编号
     */
    List<String> updateList(Collection model);

    /**
     * 修改数据
     *
     * @param model 需要修改的数据
     * @return 删除的主键编号
     */
    List<String> updateArray(Object... model);

    /**
     * 创建数据,当不传入了主键时,则会自动生成主键,传入时不会生成。
     *
     * @param model 需要创建的数据
     * @return 创建的主键编号
     */
    List<String> createList(Collection model);

    /**
     * 创建数据,当不传入了主键时,则会自动生成主键,传入时不会生成。
     *
     * @param model 需要创建的数据
     * @return 创建的主键编号
     */
    List<String> createArray(Object... model);

    /**
     * 创建数据,当不传入了主键时,则会自动生成主键,传入时不会生成。
     *
     * @param model 需要创建的数据
     * @return 创建的主键编号
     */
    List<String> replaceList(Collection model);

    /**
     * 创建数据,当不传入了主键时,则会自动生成主键,传入时不会生成。
     *
     * @param model 需要创建的数据
     * @return 创建的主键编号
     */
    List<String> replaceArray(Object... model);

    /**
     * 保存数据,有主键时修改,无主键时创建
     *
     * @param model 需要保存的数据
     * @return 保存的主键编号
     */
    List<String> saveList(Collection model);

    /**
     * 保存数据,有主键时修改,无主键时创建
     *
     * @param model 需要保存的数据
     * @return 保存的主键编号
     */
    List<String> saveArray(Object... model);

    /**
     * 删除数据,可以用于父子表删除,如通过订单删除游客信息 visitorDao.remove({orderId:1});
     * int field;
     *
     * @param model 需要删除的数据,可以是主键字符串(Int),或者是包含主键的实体,或者是包含其他非主键的实体完全匹配.
     * @return 删除的记录数量
     */
    int removeList(Collection model);

    /**
     * 删除数据,可以用于父子表删除,如通过订单删除游客信息 visitorDao.remove({orderId:1});
     * int field;
     *
     * @param model 需要删除的数据,可以是主键字符串(Int),或者是包含主键的实体,或者是包含其他非主键的实体完全匹配.
     * @return 删除的记录数量
     */
    int removeArray(Object... model);

    /***
     * 查询数据是否存在,当存在时修改,否则增加
     * @param cls 需要创建的实体的类型
     * @param requests 前台参数,不能包含主键以及其他不需要修改的字段
     * @return 保存成功,返回保存的ID,保存失败,返回空值
     */
    <T> List<String> saveByLoadArray(Class<T> cls, Object... requests);

    /***
     * 查询数据是否存在,当存在时修改,否则增加
     * @param cls 需要创建的实体的类型
     * @param requests 前台参数,不能包含主键以及其他不需要修改的字段
     * @return 保存成功,返回保存的ID,保存失败,返回空值
     */
    <T> List<String> saveByLoadList(Class<T> cls, List requests);

    /***
     * 查询数据是否存在,当存在时修改,否则增加
     * @param cls 需要创建的实体的类型
     * @param request 前台参数,不能包含主键以及其他不需要修改的字段
     * @return 保存成功,返回保存的ID,保存失败,返回空值
     */
    <T> String saveByLoad(Class<T> cls, Object request);

    /**
     * 设置MD5主键
     *
     * @param model
     * @param <T>
     */
    <T> String setGroupId(T model);

    /**
     * 添加统计数据
     *
     * @param cls   类型
     * @param model 实体
     * @param <T>   泛型类型
     * @return 增加统计的数据编号
     */
    <T> String addGroup(Class<T> cls, T model);


    /**
     * 添加统计数组
     *
     * @param cls    类型
     * @param models 请求实体
     * @param <T>    泛型数据
     * @return 返回列表
     */
    <T> List<String> addGroupList(Class<T> cls, List<T> models);

    /**
     * 添加统计数组
     *
     * @param cls    类型
     * @param models 请求实体
     * @param <T>    泛型数据
     * @return 返回列表
     */
    <T> List<String> addGroupArray(Class<T> cls, T... models);

    /**
     * 对数据据进行集合操作
     *
     * @param daoVo
     * @return
     */
    List<String> dataDao(DataDaoVo daoVo);
}