<?php
declare(strict_types=1);$base=$argv[1]??'';$candidate=$argv[2]??$base;define('TP_ENV','poc');define('BUSINESS','aizhct');define('ENTERPRISE_NO','10001');require $base.'/vendor/autoload.php';spl_autoload_register(static function($c)use($base,$candidate){foreach(['app\\'=>'app/','cores\\'=>'cores/'] as $p=>$d)if(strpos($c,$p)===0){$r=$d.str_replace('\\','/',substr($c,strlen($p))).'.php';$f=is_file($candidate.'/'.$r)?$candidate.'/'.$r:$base.'/'.$r;if(is_file($f))require $f;}},true,true);
class CompileStatement extends PDOStatement {public function __construct(){}public function fetchColumn($column=0){return 1;}public function fetchAll($how=null,$className=null,$ctorArgs=null){return [];}public function rowCount(){return 0;}}
trait CompileOnly {public static $queries=[];public function getFields(string $table):array{$t=preg_replace('/^yoshop_/','',trim(explode(' ',$table)[0],'`"'));$m=json_decode(file_get_contents(__DIR__.'/structure-B.json'),true)['tables'][$t]['columns']??[];$out=[];foreach($m as $c)$out[$c['column_name']]=['name'=>$c['column_name'],'type'=>$c['column_type'],'notnull'=>$c['is_nullable']==='NO','default'=>$c['column_default'],'primary'=>$c['extra']==='auto_increment','autoinc'=>$c['extra']==='auto_increment'];return $out;}protected function pdoQuery(\think\db\BaseQuery $query,$sql,array $bind=[],bool $master=null):array{$query->parseOptions();if($sql instanceof Closure)$sql=$sql($query);self::$queries[]=['sql'=>$sql,'bind'=>$query->getBind()?:$bind];return strpos($sql,'think_count')!==false?[['think_count'=>1]]:[];}public function getPDOStatement(string $sql,array $bind=[],bool $master=false,bool $procedure=false):PDOStatement{self::$queries[]=['sql'=>$sql,'bind'=>$bind];return new CompileStatement;}}
class CompileMysql extends \think\db\connector\Mysql {use CompileOnly;public function getBuilderClass():string{return \think\db\builder\Mysql::class;}}
class CompileDm extends \app\common\database\Dm {use CompileOnly;}
$app=new \think\App($base);$app->setEnvName('poc');$app->setRuntimePath(__DIR__.'/private/compile-runtime/');$app->initialize();require $base.'/app/store/common.php';\think\App::$store_id=2147001111;$checks=0;$fail=[];$all=[];
foreach(['mysql'=>'\\CompileMysql','dm'=>'\\CompileDm'] as $engine=>$type){$cfg=$app->config->get('database');$conn=$cfg['connections']['mysql'];$conn['type']=$type;$conn['database']='NOT_CONNECTED';$conn['trigger_sql']=false;$cfg['default']='mysql';$cfg['connections']=['mysql'=>$conn];$app->config->set($cfg,'database');$app->db->setConfig($app->config);$app->db->connect('mysql',true);foreach(['store','terminal'] as $m)foreach(['PointsLog','BalanceLog'] as $name){$class='app\\'.$m.'\\model\\user\\'.$name;$connection=$app->db->connect('mysql');$connection::$queries=[];(new $class)->getList(['userId'=>123,'user_id'=>123,'search'=>"甲'乙",'scene'=>10,'betweenTime'=>['2026-10-11','2026-10-11']]);$qs=$connection::$queries;$all[$engine.'/'.$m.'/'.$name]=$qs;$checks++;if(count($qs)!==2)$fail[]=$engine.'/'.$m.'/'.$name.':count/select pair';foreach($qs as $q){$s=str_replace(['`','"'],'',$q['sql']);$tests=['safe_join'=>preg_match('/JOIN yoshop_user u ON u\\.user_id\\s*=\\s*(?:m|log)\\.user_id/',$s)===1,'safe_search'=>strpos($s,'u.nick_name LIKE')!==false,'old_alias_absent'=>strpos($s,'JOIN yoshop_user user ')===false&&strpos($s,'user.nick_name')===false,'bound_search'=>count(array_filter($q['bind'],static function($v){return is_array($v)&&$v[0]==="%甲'乙%";}))===1,'literal_not_interpolated'=>strpos($s,"甲'乙")===false];foreach($tests as $label=>$ok){$checks++;if(!$ok)$fail[]=$engine.'/'.$m.'/'.$name.':'.$label;}}}}
echo json_encode(['assertions'=>$checks,'failures'=>$fail,'actual_models'=>4,'actual_builders'=>2,'compiled_queries'=>array_sum(array_map('count',$all)),'PDO'=>0,'executed_SQL'=>0,'HTTP'=>0,'DML'=>0]),"\n";exit($fail?1:0);
