<?php



class db{
	static $pdo = null;
	static $issqlite = false;
	static $ismysql = false;
	static $listdb = [];
	static $maps = [];
	static function add_map($key,$value="",$dbname=null){
		self::$maps[] = [
			"key" => $key,
			"value" => $value,
			"db" => $dbname
		];
	}
	static function decodeSql($sql){
		foreach (self::$maps as $row) {
			if (is_null($row["db"]) || $row["db"] == self::$dbname) {
				$sql = str_replace($row["key"], $row["value"], $sql);
			}
		}
		return $sql;
	}
	static function add_mysql($name,$host="127.0.0.1",$dbname="base",$user="root",$password=null,$port = null){
		self::$listdb[$name] = [
			"dbname" => $dbname,
			"mysql"  => true,
			"sqlite" => false,
			"pdo"    => self::connect("mysql:host=$host;".(empty($port)?"":"port=$port;")."dbname=$dbname",$user,$password),
		];
	}
	static function add_sqlite($name,$path="database.sqlite"){
		self::$listdb[$name] = [
			"mysql"  => false,
			"sqlite" => true,
			"pdo"    => self::connect("sqlite:$path"),
		];
	}
	static $dbname = null;
	static function db($name){
		if (isset(self::$listdb[$name])) {
			self::$pdo = self::$listdb[$name]["pdo"];
			self::$issqlite = self::$listdb[$name]["sqlite"];
			self::$ismysql = self::$listdb[$name]["mysql"];
			self::$dbname = $name;
			return self::$pdo;
		}
		ob_start();
		trigger_error("Erreur aucun base nomme : $name", E_USER_ERROR);
		clog(ob_get_clean());
		return false;
	}
	static function sqlite($path="database.sqlite"){
		self::$issqlite = true;
		self::$ismysql = false;
		self::$pdo = null;
		self::$dbname = "sqlite";
		self::$pdo = self::connect("sqlite:$path");
		return self::$pdo;
	}
	static function mysql($host="127.0.0.1",$dbname="base",$user="root",$password=null,$port = null){
		self::$issqlite = false;
		self::$ismysql = true;
		self::$pdo = null;
		self::$dbname = "mysql";
		self::$pdo = self::connect("mysql:host=$host;".(empty($port)?"":"port=$port;")."dbname=$dbname",$user,$password);
		return self::$pdo;
	}
	static function connect($str,$user = null,$password = null){
		$db = null;
		try {
			$db = new PDO($str,$user,$password,[PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
			$db->query("SET NAMES utf8;SET time_zone = '+01:00'");
		} catch (Exception $e) {
			$db = null;
			echo "Erreur connection MySQL";
			// echo "Erreur connection : $dbType : $str : ".$e->getMessage();
			exit();
			return false;
		}
		return $db;
	}
	static function closepdo(&$pdo){
		if($pdo!=null){
			$pdo = null;
		}
	}
	static function close(){
		if(self::$pdo){
			self::$pdo=null;
		}
	}
	static function script($name,$callback){

	}
	static function run($name,$callback = null){

	}
	static function stop($name){

	}
	static function query($sql,$data = null,$pdo=null){
		$start = microtime(true);
		//if($_SERVER["HTTP_REMOTE_IP"] == "41.228.104.24"){
			//$hash=hash('md5',$sql);
			/* if(file_exists("reqf10/".$hash.".txt")){
				file_put_contents("reqf10/".$hash.".txt",(date('Y-m-d H:i:s.').gettimeofday()['usec']."\n"),FILE_APPEND);
			}else{
				file_put_contents("reqf10/".$hash.".txt",$sql."\n".(date('Y-m-d H:i:s.').gettimeofday()['usec']."\n"));
			} */
		//}
        if($pdo==null)$pdo=self::$pdo;
		$sql = self::decodeSql($sql);
		try {
			if (!is_null($data) && is_array($data) && !empty($data)) {
				$list = [];
				foreach ($data as $key => $value) {
					if (is_array($value)) {
						$value = json_encode($value);
					}
					if (is_string($key) && !preg_match("/^\:/i",$key)) {
						$list[":$key"] = $value;
					}else{
						$list[$key] = $value;
					}
				}
				//file_put_contents("reqf9/".$hash."-".$start.".sql",$sql);
				$q = $pdo->prepare($sql);
				$q->execute($list);	
				/* $end=microtime(true);
				file_put_contents("reqf9/".round($end-$start).".sql",$sql);
				unlink("reqf9/".$hash."-".$start.".sql"); */
				return $q;
			}
			//file_put_contents("reqf9/".$hash."-".$start.".sql",$sql);
			$rr = $pdo->query($sql);
			/* $end=microtime(true);
			file_put_contents("reqf9/".round($end-$start).".sql",$sql);
			unlink("reqf9/".$hash."-".$start.".sql"); */
			return $rr;
		} catch (Exception $e) {
			clog("db::query Error : ".$e->getMessage()." => SQL :\n-------------\n $sql\n-------------\n ");
			if (!is_dir("logs/".app::$sdom)) {
				mkdir("logs/".app::$sdom, 0775, true);
			}
			file_put_contents("logs/".app::$sdom."/error_".date("Y-m-d-H").".log",date("d/m/Y H:i:s")." => db::query Error : ".$e->getMessage()." => SQL :\n-------------\n $sql\n-------------\n ",FILE_APPEND);
		}	
		return false;
	}
	static function decode($row){
		foreach ($row as $key => $value) {
			if (!in_array($key,["ref","code_barre","score"])) {
				$v = json_decode($value,true);
				if (json_last_error() == JSON_ERROR_NONE) {
				  $row[$key] = $v;
				}
			}elseif($key == "score"){
				$row[$key] = floatval($value);
			}

		}
		if (isset($row["createAt"])) {
			$row["createAtF"] = db::parseDate($row["createAt"],"d/m/Y H:i");
		}
		return $row;
	}
	static function row($sql,$data = null,$pdo=null){
        if($pdo==null)$pdo=self::$pdo;
		if ($q = self::query($sql,$data,$pdo)) {
			if ($row = $q->fetch()) {
				return self::decode($row);
			}
		}
		return null;
	}
	static function table($sql,$data = null,$pdo = null){
		if ($q = self::query($sql,$data,$pdo)) {
			$table = [];
			while ($row = $q->fetch()) {
				$table[] = self::decode($row);
			}
			return $table;
		}
		return [];
	}
	static function val($sql,$data = null,$default = null,$pdo=null){
        if($pdo==null)$pdo=self::$pdo;
		if($row = self::row($sql,$data,$pdo)){
			$keys = array_keys($row);
			if (!empty($keys)) {
				return $row[$keys[0]];
			}
		}
		return $default;
	}
	static function pagination($sql,$data,$dataSql=[],$pdo=null){
        if($pdo==null)$pdo=self::$pdo;
		$page = is_numeric($data["page"])?floatval($data["page"]):1;
		if($page<1) $page = 1;
		$length = is_numeric($data["length"])?floatval($data["length"]):10;
		if($length<1) $length = 10;
		$start = ($page - 1) * $length;
		$total = db::val("SELECT count(*) as total FROM ($sql) t",$dataSql,0);
		if($start>=$total){
			$page  -= 1;
			if($page<1) $page = 1;
			$start = ($page - 1) * $length;
		}
		$rep = [];
		$rep["page"] = $page;
		$rep["length"] = $length;
		$rep["total"] = $total;
		$rep["nbrPage"] = ceil(max($total,1) / $length);
		$rep["data"] = db::table("SELECT * FROM ($sql) tablepagination limit $start,$length",$dataSql,$pdo);
		return $rep;
	}



	static function parseDate($val = null,$format = "",$add=false,$unite="day"){
		date_default_timezone_set('Europe/Paris');
		setlocale(LC_TIME, 'fr_FR.utf8','fra');
		if(is_null($val)) $val = date("Y-m-d H:i:s");
		$val = str_replace("/", "-", $val);
		$val = str_replace("\\", "-", $val);
		$v = preg_match("/(?<day>[0-9]{1,2})-(?<month>[0-9]{1,2})-(?<year>[0-9]{4})\s*((?<heure>[0-9]{1,2}):(?<minute>[0-9]{1,2}))?(:(?<seconde>[0-9]{1,2}))?/i", $val, $r);
		if(!$v) $v = preg_match("/(?<year>[0-9]{4})-(?<month>[0-9]{1,2})-(?<day>[0-9]{1,2})\s*((?<heure>[0-9]{1,2}):(?<minute>[0-9]{1,2}))?(:(?<seconde>[0-9]{1,2}))?/i", $val, $r);
		if($v){
		  if(checkdate(empty($r["month"])?date("m"):$r["month"],empty($r["day"])?date("d"):$r["day"],empty($r["year"])?date("Y"):$r["year"])){
		    $val = mktime(
		      empty($r["heure"])?0:$r["heure"],
		      empty($r["minute"])?0:$r["minute"],
		      empty($r["seconde"])?0:$r["seconde"],
		      empty($r["month"])?date("m"):$r["month"],
		      empty($r["day"])?date("d"):$r["day"],
		      empty($r["year"])?date("Y"):$r["year"]
		      );
		    if(empty($format)){
		      if(!$add) return $val;
		      return strtotime(date("Y-m-d H:i:s",$val)." +$add $unite");
		    }else{
		      if(!$add) return date($format,$val);
		      return date($format,strtotime(date("Y-m-d H:i:s",$val)." +$add $unite"));
		    }
		  }
		}
		return false;
	}




	static $schema = null;
	static function getColsTable($table){
		$table = self::decodeSql($table);
		if (is_null(self::$schema)) {
			self::$schema = [];
			if (self::$ismysql) {
				$prefix = self::decodeSql("¤");
				if($prefix == "¤") $prefix = "";
				$sql = "SELECT * FROM information_schema.columns where `TABLE_SCHEMA`<>'information_schema' and TABLE_NAME like '$prefix%'";
				$list = self::table($sql);
				$tables = [];
				foreach ($list as $key => $row) {
					if(empty($tables[$row["TABLE_NAME"]])) $tables[$row["TABLE_NAME"]] = [];
					if(empty($tables[$row["TABLE_NAME"]]["cols"])) $tables[$row["TABLE_NAME"]]["cols"] = [];
					if(empty($tables[$row["TABLE_NAME"]]["auto"])) $tables[$row["TABLE_NAME"]]["auto"] = [];
					if(empty($tables[$row["TABLE_NAME"]]["default"])) $tables[$row["TABLE_NAME"]]["default"] = [];
					if(empty($tables[$row["TABLE_NAME"]]["nullable"])) $tables[$row["TABLE_NAME"]]["nullable"] = [];
					$tables[$row["TABLE_NAME"]]["dbname"]  = $row["TABLE_SCHEMA"];
					$tables[$row["TABLE_NAME"]]["cols"][$row["COLUMN_NAME"]] = $row["COLUMN_TYPE"];
					if(!is_null($row["COLUMN_DEFAULT"])){
						$tables[$row["TABLE_NAME"]]["default"][$row["COLUMN_NAME"]] = $row["COLUMN_DEFAULT"];
					}
					$tables[$row["TABLE_NAME"]]["nullable"][$row["COLUMN_NAME"]] = $row["IS_NULLABLE"] == "YES";
					if ($row["EXTRA"] == "auto_increment") {
						$tables[$row["TABLE_NAME"]]["auto"][$row["COLUMN_NAME"]] = $row["COLUMN_NAME"];
					}
				}
				foreach ($tables as $tablename=>$tabledata) {
					if(empty($tables[$tablename]["primary"])) $tables[$tablename]["primary"] = [];
					if(empty($tables[$tablename]["index"])) $tables[$tablename]["index"] = [];
					if(empty($tables[$tablename]["unique"])) $tables[$tablename]["unique"] = [];
					$indexs = self::table("SHOW INDEX FROM `$tablename` FROM `".$tabledata["dbname"]."`");
					foreach ($indexs as $idx) {
						if($idx["Key_name"] == "PRIMARY"){
							$tables[$tablename]["primary"][] = $idx["Column_name"];
						}elseif ((bool)$idx["Non_unique"]) {
							if(empty($tables[$tablename]["index"][$idx["Key_name"]])) $tables[$tablename]["index"][$idx["Key_name"]] = [];
							$tables[$tablename]["index"][$idx["Key_name"]][] = $idx["Column_name"];
						}else{
							if(empty($tables[$tablename]["unique"][$idx["Key_name"]])) $tables[$tablename]["unique"][$idx["Key_name"]] = [];
							$tables[$tablename]["unique"][$idx["Key_name"]][] = $idx["Column_name"];
						}
					}
				}
			}else{
				$listtable = self::table("SELECT name FROM sqlite_master WHERE type='table'");
				$tables = [];
				foreach ($listtable as $tbl) {
					$tablename = $tbl["name"];
					$tables[$tablename] = [
						"cols"     => [],
						"default"  => [],
						"nullable" => [],
						"primary"  => [],
						"auto"     => [],
						"index"    => [],
						"unique"   => [],
					];
					$cols = self::table("PRAGMA table_info(`$tablename`)");
					foreach ($cols as $col) {
						$tables[$tablename]["cols"][$col["name"]] = $col["type"];
						$tables[$tablename]["default"][$col["name"]] = $col["dflt_value"];
						$tables[$tablename]["nullable"][$col["name"]] = !(bool)$col["notnull"];
						if ((bool)$col["pk"]) {
							$tables[$tablename]["primary"][] = $col["name"];
							if (self::row("SELECT 'is-autoincrement' as val FROM sqlite_master WHERE tbl_name='$tablename' AND sql LIKE '%AUTOINCREMENT%'")) {
								$tables[$tablename]["auto"][$col["name"]] = $col["name"];
							}
						}
					}
					$indexs = self::table("PRAGMA index_list(`$tablename`)");
					foreach ($indexs as $index) {
						$cols = self::table("PRAGMA index_info(`".$index["name"]."`)");
						if ((bool)$index["unique"]) {
							foreach ($cols as $col) {
								if(empty($tables[$tablename]["unique"][$index["name"]])) $tables[$tablename]["unique"][$index["name"]] = [];
								$tables[$tablename]["unique"][$index["name"]][] = $col["name"];
							}
						}else{
							foreach ($cols as $col) {
								if(empty($tables[$tablename]["index"][$index["name"]])) $tables[$tablename]["index"][$index["name"]] = [];
								$tables[$tablename]["index"][$index["name"]][] = $col["name"];
							}
						}
					}
				}
			}
			self::$schema = $tables;
			// schema
			/*
				self::$schema = [
					"tablename" => [
						"cols"=>[
							"colname"=>"col Type",
							"colname"=>"col Type",
							"colname"=>"col Type",
							...
						],
						"primary" => ["col1","col2" ...],
						"auto"=>[
							"colname"=>"colname",
							"colname"=>"colname",
							"colname"=>"colname",
							...
						],
						"index"=>[
							"indexname"=>["col1","col2" ...],
							"indexname"=>["col1","col2" ...],
							...
						],
						"unique"=>[
							"indexname"=>["col1","col2" ...],
							"indexname"=>["col1","col2" ...],
							...
						]
					]
				]
			*/
		}
		return isset(self::$schema[$table])?self::$schema[$table]:[];
	}
	static function hasCol($table,$col){
		$cols = self::getColsTable($table);
		if($col=="updateAt") return false;
		return isset($cols["cols"][$col]);
	}
	static function getJustColTable($table,$row){
		$list = [];
		foreach ($row as $key => $value) {
			if (self::hasCol($table,$key)) {
				$list[$key] = $value;
			}
		}
		return $list;
	}
	static function insert($table,$data,$pdo=null){
		if($pdo==null)$pdo=self::$pdo;
		$data = self::getJustColTable($table,$data);
		$cols = array_keys($data);
		if(empty($cols)){
			return false;
		}
		$strcolsk = "`".join("`,`",$cols)."`";
		$strcolsv = ":".join(",:",$cols);
		$sql = "INSERT INTO `$table` ($strcolsk) values ($strcolsv)";
		if (self::query($sql,$data)) {
			return $pdo->lastInsertId();
		}
		return null;
	}
	static function update($table,$data,$filter){
		$data = self::getJustColTable($table,$data);
		$filter = self::getJustColTable($table,$filter);
		$cols = array_keys($data);
		if(empty($cols)) return false;
		if(empty($filter)) return false;
		$strcols = [];
		foreach ($cols as $key => $col) {
			$strcols[] = "`$col`=:$col";
		}
		$strcols = join(", ",$strcols);
		$strcolsfilter = [];
		foreach ($filter as $col => $value) {
			$strcolsfilter[] = "`$col`=:filter$col";
			$data[":filter$col"] = $filter[$col];
		}
		$strcolsfilter = join(", ",$strcolsfilter);
		$sql = "UPDATE `$table` set $strcols where $strcolsfilter";
		return self::query($sql,$data);
	}
	static function save($table,$data,$pdo=null){
		if($pdo==null)$pdo=self::$pdo;
		if(empty($data["user_id"])){
			$data["user_id"] = user::get("id")??1;
			$data["user_type"] = user::get("type")??"ET";
			$data["user_name"] = user::get("nom")??"ET";
		}

		$data["ip"] =  app::ip();

		$data = self::getJustColTable($table,$data);
		$cols = array_keys($data);
		if(empty($cols)) return false;
		$strcolsk = "`".join("`,`",$cols)."`";
		$strcolsv = ":".join(",:",$cols);
		$update = [];
		foreach ($cols as $col) {
			$update[] = "`$col`=values(`$col`)";
		}
		$update = join(",",$update);
		if (self::$ismysql) {
			$sql = "INSERT INTO `$table` ($strcolsk) values ($strcolsv) ON DUPLICATE KEY UPDATE $update";
		}else{
			$sql = "INSERT OR REPLACE INTO `$table` ($strcolsk) values ($strcolsv)";
		}	
		if (self::query($sql,$data,$pdo)) {
			return $pdo->lastInsertId();
		}
		return null;
	}
	static $listCreateTable = [];
	static function create($tablename,$callback){
		$table = new self($tablename);
		self::$listCreateTable[$tablename] = $table;
		$fn = $callback->bindTo($table);
		$fn($table);
		return $table;
	}
	static function getCreateSchema($force = false,$checkupdate = false){
		$sql = [];
		foreach (self::$listCreateTable as $table) {
			if ($s = $table->install($force,true,false,$checkupdate)) {
				if (!empty($s)) {
					$sql[] = $s ;
				}
			}
		}
		return join("\n\n\n",$sql);
	}
	var $name = "";
	function __construct($tablename){
		$this->name = $tablename;
	}
	var $cols = [];
	function __call($name,$args){
		switch ($name) {
			case "createAt":
				return $this->timestamp("createAt")->notNull()->def("CURRENT_TIMESTAMP");
			break;
			case "updateAt":
				return $this->datetime("updateAt")->def("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP");
			break;
			case "id":
				return $this->int("id")->notNull()->pri()->auto();
			break;
			case "user":
				$c = $this->int("user_id")->notNull();
				$this->string("user_type");
				$this->string("user_name");
				return $c;
			break;
			case "ip":
				$this->string("ip");
				return $c;
			break;
			default:
				$this->cols[$args[0]] = new ldbCol($this,$args[0],$name);
				return $this->cols[$args[0]];
			break;
		}
	}
	static $typemap =  [
		"int"       => ["INT(11)","INTEGER"],
		"string"    => ["VARCHAR(255)","TEXT"],
		"double"    => ["DOUBLE","DOUBLE"],
		"date"      => ["date","date"],
		"datetime" => ["DATETIME","DATETIME"],
		"timestamp" => ["TIMESTAMP","TIMESTAMP"],
		"text"      => ["TEXT","TEXT"],
		"longtext"  => ["LONGTEXT","TEXT"],
		"json"  	=> ["TEXT"],
		"longjson"  => ["LONGTEXT"],
	];
	static function getphptype($type){
		foreach (self::$typemap as $key => $value) {
			$tt =strtolower(explode("(", $value[0])[0]);
			if ($tt == strtolower(trim(explode("(", $type)[0]))) {
				return $key;
			}
		}
		foreach (self::$typemap as $key => $value) {
			$tt =strtolower(explode("(", $value[1])[0]);
			if ($tt == strtolower(trim(explode("(", $type)[0]))) {
				return $key;
			}
		}
		return "string";
	}
	static function genphp(){
		self::getColsTable("");
		$str = "";
		foreach (self::$schema as $tablename=>$table) {
			$str .= "db::create(\"$tablename\",function(\$table){\n";
			foreach ($table["cols"] as $colname => $coltype) {
				$typename = self::getphptype($coltype);
				$str .= "\t\$table->$typename(\"$colname\")";
				if (!$table["nullable"][$colname]) {
					$str .= "->notnull()";
				}
				if (!empty($table["default"][$colname])) {
					if ($typename == "int") {
						$str .= "->default(".$table["default"][$colname].")";
					}elseif(in_array(strtolower($table["default"][$colname]),["current_timestamp"]) || preg_match("/\(/i",$table["default"][$colname])){
						$str .= "->default(\"".$table["default"][$colname]."\")";
					}else{
						$str .= "->default(\"'".$table["default"][$colname]."'\")";
					}
				}
				if (in_array($colname,$table["primary"])) {
					$str .= "->pri()";
				}
				if (in_array($colname,$table["auto"])) {
					$str .= "->auto()";
				}
				foreach ($table["index"] as $indexname => $cols) {
					if (in_array($colname,$cols)) {
						$str .= "->index(\"$indexname\")";
					}
				}
				foreach ($table["unique"] as $indexname => $cols) {
					if (in_array($colname,$cols)) {
						$str .= "->unique(\"$indexname\")";
					}
				}
				$str .= ";\n";
			}
			$str .= "});\n";
		}
		return $str;
	}
	function install($force = false,$returnschema = false,$returnasarray = false,$checkupdate = true){
		$schema = self::getColsTable($this->name);
		$sql = [];
		if (!empty($schema) && $checkupdate) {
			$insertcol = [];
			$updatecol = [];
			$deletecol = [];
			foreach ($this->cols as $colname => $col) {
				if (empty($schema["cols"][$colname])) {
					$insertcol[] = $col;
				}else{
					if (self::getphptype($schema["cols"][$colname]) != strtolower(trim($col->type))) {
						clog(self::getphptype($schema["cols"][$colname]));
						clog(strtolower(trim($col->type)));
						$updatecol[] = $col;
					}
				}
			}
			foreach ($schema["cols"] as $colname => $coltype) {
				$find = false;
				foreach ($this->cols as $cn => $col) {
					if ($cn == $colname) {
						$find = true;
						break;
					}
				}
				if (!$find) {
					$deletecol[] = $colname;
				}
			}
			$sql = [];
			if (self::$ismysql) {
				foreach ($deletecol as $key => $value) {
					$sql[] = "ALTER TABLE `".$this->name."` DROP COLUMN `$value`";
				}
				foreach ($insertcol as $key => $col) {
					$sql[] = "ALTER TABLE `".$this->name."` ADD COLUMN ".$col->sql(self::$ismysql);
				}
				foreach ($updatecol as $key => $col) {
					$sql[] = "ALTER TABLE `".$this->name."` MODIFY COLUMN ".$col->sql(self::$ismysql);
				}
			}else{
				if (empty($deletecol) && empty($updatecol)) {
					foreach ($insertcol as $key => $col) {
						$sql[] = "ALTER TABLE `".$this->name."` ADD ".$col->sql(self::$ismysql);
					}
				}else{
					$newname = $this->name."_".uniqid();
					$sql[] = "ALTER TABLE `".$this->name."` RENAME TO `$newname`";
					$sql = array_merge($sql,$this->install(false,true,true,false));
					$listcol = [];
					foreach ($this->cols as $colname => $value) {
						if (isset($schema["cols"][$colname])) {
							$listcol[] = $colname;
						}
					}
					$listcol = "`".join("`,`",$listcol)."`";
					$sql[] = "INSERT INTO `".$this->name."` ($listcol) SELECT $listcol FROM $newname";
				}
			}
		}else{
			if ($force) $sql[] = "DROP TABLE IF EXISTS `$this->name`";
			$list = [];
			foreach ($this->cols as $key => $col) $col->getIndexList($list,self::$ismysql);
			$ss  = "CREATE TABLE IF NOT EXISTS `$this->name` (";
			$v = false;
			foreach ($this->cols as $key => $col) {
				if($v) $ss .=",";
				$ss .= "\n\t".$col->sql(self::$ismysql);
				$v = true;
			}
			if (!empty($list["primary"])) {
				$ss .= ",\n\tPRIMARY KEY (`".join("`,`",$list["primary"])."`)";
			}
			$ss .= "\n)";
			if (self::$ismysql) $ss .= " ENGINE=MyISAM CHARSET=utf8 AUTO_INCREMENT=1";
			$sql[] = $ss;
			if (!empty($list["index"])) {
				foreach ($list["index"] as $indexname => $cols) {
					if (!self::$ismysql){
						foreach (self::$schema as $tablename => $value) {
							if(strtolower($indexname) == strtolower($tablename)) $indexname = "index_$indexname";
						}
					}
					$sql[] = "CREATE INDEX".(self::$ismysql?"":" IF NOT EXISTS")." `$indexname` ON `$this->name` (`".join("`,`",$cols)."`)";
				}
			}
			if (!empty($list["unique"])) {
				foreach ($list["unique"] as $indexname => $cols) {
					if (!self::$ismysql) if(!empty(self::$schema[$indexname])) $indexname = "index_$indexname";
					$sql[] = "CREATE UNIQUE INDEX".(self::$ismysql?"":" IF NOT EXISTS")." `$indexname` ON `$this->name` (`".join("`,`",$cols)."`)";
				}
			}
		}
		if ($returnschema) {
			if ($returnasarray) {
				return $sql;
			}else{
				if (empty($sql)) {
					return "";
				}
				return join(";\n",$sql).";";
			}
		}
		foreach ($sql as $sqlQuery) {
			clog(db::decodeSql($sqlQuery));
			self::query($sqlQuery);
		}
		self::$schema = null;
	}
}
class ldbCol{
	var $name = "";
	var $type = "";
	var $data = [];
	var $parent = null;
	var $indexnames = [];
	var $uniqueindexnames = [];
	function index($name = null){
		if (is_null($name)) $name = "indexCol".ucfirst(strtolower($this->name));
		$this->indexnames[$name] = $name;
		return $this;
	}
	function unique($name = null){
		if (is_null($name)) $name = "indexCol".ucfirst(strtolower($this->name));
		$this->uniqueindexnames[$name] = $name;
		return $this;
	}
	function getIndexList(&$list,$ismysql){
		if ($this->pri || $this->primary) {
			if (empty($list["primary"])) $list["primary"] = [];
			if ($ismysql || (!$this->auto && !$this->autoinc && !$this->auto_increment)) {
				$list["primary"][] = $this->name;
			}
		}
		if (empty($list["index"])) $list["index"] = [];
		foreach ($this->indexnames as $indexname) {
			if (empty($list["index"][$indexname])) $list["index"][$indexname] = [];
			$list["index"][$indexname][] = $this->name;
		}
		if (empty($list["unique"])) $list["unique"] = [];
		foreach ($this->uniqueindexnames as $indexname) {
			if (empty($list["unique"][$indexname])) $list["unique"][$indexname] = [];
			$list["unique"][$indexname][] = $this->name;
		}
	}
	function __construct($parent,$colName,$type){
		$this->name = $colName;
		$this->type = $type;
		$this->parent = $parent;
	}
	function __call($name,$args){
		if (empty($args)) {
			$args = [true];
		}

		$this->data[$name] = $args[0];
		return $this;
	}
	function __set($name,$value){
		$this->data[$name] = $value;
	}
	function __get($name){
		return $this->data[$name];
	}
	function sql($ismysql){

		$sql = [];
		$sql[] = "`$this->name`";
		switch ($this->type) {
			case 'int':
				if ($ismysql) {
					$sql[] ="int(11)";
				}else{
					$sql[] ="INTEGER";
				}
			break;
			case 'string':
				if ($ismysql) {
					$sql[] ="varchar(255)";
				}else{
					$sql[] ="TEXT";
				}
			break;
			case 'string50':
				if ($ismysql) {
					$sql[] ="varchar(50)";
				}else{
					$sql[] ="TEXT";
				}
			break;
			case 'string64':
				if ($ismysql) {
					$sql[] ="varchar(64)";
				}else{
					$sql[] ="TEXT";
				}
			break;
			case 'string100':
				if ($ismysql) {
					$sql[] ="varchar(100)";
				}else{
					$sql[] ="TEXT";
				}
			break;
			default:
				$sql[] = strtoupper($this->type);
			break;
		}
		if ($this->notnull || $this->NotNull || $this->notNull || $this->pri || $this->primary) {
			$sql[] ="NOT NULL";
		}else{
			$sql[] ="NULL";
		}
		if ($this->def) {
			$sql[] ="DEFAULT ".$this->def;
		}
		if ($this->default) {
			$sql[] ="DEFAULT ".$this->default;
		}
		if ($this->auto || $this->autoinc || $this->auto_increment) {
			if ($ismysql) {
				$sql[] ="AUTO_INCREMENT";
			}else{
				$sql[] ="PRIMARY KEY AUTOINCREMENT";
			}
		}
		return join(" ",$sql);
	}
}