<?php

namespace PhpLife\Frame;

class Model
{

    /**
     * 创建单例模式
     * @return Model
     */
    public static function getInstance()
    {
        static $pool;
        $class = get_called_class();
        if (!isset($pool[$class])) {
            $pool[$class] = new $class();
        }
        return $pool[$class];
    }

    /**
     * 强大的批量获取方法,从数据库或者缓存中读取数据
     * 1. 先读取缓存
     * 2. 然后从数据库中读取缓存没有命中的
     * 3. 将没有命中的写入缓存
     * 4. 返回结果
     * @param $idArray
     * @param string $databaseClass 完整数据库类路径, 要求拥有getBatch方法
     * @param string $cacheClass 完整缓存类路径, 要求拥有 getBatch, setBatch 方法
     * @return bool
     */
    public static function getBatchFromDatabaseOrCache($idArray, $databaseClass = '', $cacheClass = '')
    {
        $cachedData = array();
        // 从缓存中读取数据
        if ($cacheClass && class_exists($cacheClass) && method_exists($cacheClass, 'getBatch')) {
            $cachedData = $cacheClass::getBatch($idArray);
        }
        // 取出剩余的ID
        $idLeft = array();
        foreach ($idArray as $id) {
            if (isset($cachedData[$id]) && $cachedData[$id]) {
                continue;
            }
            $idLeft[] = $id;
        }
        // 从数据库取出内容
        $databaseData = array();
        if ($idLeft && $databaseClass && class_exists($databaseClass) && method_exists($databaseClass, 'getBatch')) {
            $databaseData = $databaseClass::getBatch($idLeft);
        }
        // 设置从数据库读取的缓存
        if ($databaseData && $cacheClass && class_exists($cacheClass) && method_exists($cacheClass, 'setBatch')) {
            $cacheClass::setBatch($databaseData);
        }
        // 合并数据
        $data = array();
        foreach ($idArray as $id) {
            if (isset($cachedData[$id]) && $cachedData[$id]) {
                $data[$id] = $cachedData[$id];
            } elseif (isset($databaseData[$id]) && $databaseData[$id]) {
                $data[$id] = $databaseData[$id];
            }
        }
        return $data;
    }

    /**
     * 检查状态位, 如果code是布尔, 则直接返回
     * @param $stat
     * @param $code
     * @return int
     */
    protected static function checkStat($stat, $code)
    {
        if (is_bool($code)) {
            return $code;
        }
        $code = intval($code);
        $result = $stat & $code;
        return $result;
    }

}