92 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| namespace nulib\db\_private;
 | |
| 
 | |
| use nulib\cl;
 | |
| use nulib\ValueException;
 | |
| 
 | |
| class _insert extends _common {
 | |
|   const SCHEMA = [
 | |
|     "prefix" => "?string",
 | |
|     "into" => "?string",
 | |
|     "schema" => "?array",
 | |
|     "cols" => "?array",
 | |
|     "values" => "?array",
 | |
|     "suffix" => "?string",
 | |
|   ];
 | |
| 
 | |
|   static function isa(string $sql): bool {
 | |
|     return preg_match("/^insert\b/i", $sql);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * parser une chaine de la forme
 | |
|    * "insert [into] [TABLE] [(COLS)] [values (VALUES)]"
 | |
|    */
 | |
|   static function parse(array $query, ?array &$bindings=null): string {
 | |
|     # fusionner d'abord toutes les parties séquentielles
 | |
|     $usersql = $tmpsql = self::merge_seq($query);
 | |
| 
 | |
|     ### vérifier la présence des parties nécessaires
 | |
|     $sql = [];
 | |
|     if (($prefix = $query["prefix"] ?? null) !== null) $sql[] = $prefix;
 | |
| 
 | |
|     ## insert
 | |
|     self::consume('(insert(?:\s+or\s+(?:ignore|replace))?)\s*', $tmpsql, $ms);
 | |
|     $sql[] = $ms[1];
 | |
| 
 | |
|     ## into
 | |
|     self::consume('into\s*', $tmpsql);
 | |
|     $sql[] = "into";
 | |
|     $into = $query["into"] ?? null;
 | |
|     if (self::consume('([a-z_][a-z0-9_]*)\s*', $tmpsql, $ms)) {
 | |
|       if ($into === null) $into = $ms[1];
 | |
|       $sql[] = $into;
 | |
|     } elseif ($into !== null) {
 | |
|       $sql[] = $into;
 | |
|     } else {
 | |
|       throw new ValueException("expected table name: $usersql");
 | |
|     }
 | |
| 
 | |
|     ## cols & values
 | |
|     $usercols = [];
 | |
|     $uservalues = [];
 | |
|     if (self::consume('\(([^)]*)\)\s*', $tmpsql, $ms)) {
 | |
|       $usercols = array_merge($usercols, preg_split("/\s*,\s*/", $ms[1]));
 | |
|     }
 | |
|     $cols = cl::withn($query["cols"] ?? null);
 | |
|     $values = cl::withn($query["values"] ?? null);
 | |
|     $schema = $query["schema"] ?? null;
 | |
|     if ($cols === null) {
 | |
|       if ($usercols) {
 | |
|         $cols = $usercols;
 | |
|       } elseif ($values) {
 | |
|         $cols = array_keys($values);
 | |
|         $usercols = array_merge($usercols, $cols);
 | |
|       } elseif ($schema && is_array($schema)) {
 | |
|         #XXX implémenter support AssocSchema
 | |
|         $cols = array_keys($schema);
 | |
|         $usercols = array_merge($usercols, $cols);
 | |
|       }
 | |
|     }
 | |
|     if (self::consume('values\s+\(\s*(.*)\s*\)\s*', $tmpsql, $ms)) {
 | |
|       if ($ms[1]) $uservalues[] = $ms[1];
 | |
|     }
 | |
|     if ($cols !== null && !$uservalues) {
 | |
|       if (!$usercols) $usercols = $cols;
 | |
|       foreach ($cols as $col) {
 | |
|         $uservalues[] = ":$col";
 | |
|         $bindings[$col] = $values[$col] ?? null;
 | |
|       }
 | |
|     }
 | |
|     $sql[] = "(" . implode(", ", $usercols) . ")";
 | |
|     $sql[] = "values (" . implode(", ", $uservalues) . ")";
 | |
| 
 | |
|     ## suffixe
 | |
|     if (($suffix = $query["suffix"] ?? null) !== null) $sql[] = $suffix;
 | |
| 
 | |
|     ## fin de la requête
 | |
|     self::check_eof($tmpsql, $usersql);
 | |
|     return implode(" ", $sql);
 | |
|   }
 | |
| }
 |