PgSql typ stlpca array a insert a update

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Balvan
Člen | 30
+
0
-

Helov, narazil som na mensi problem pri pouzivani NetteDB v PgSql a konkretne ide o to ze mam v DB typ stlpca col1 = int[] a a col2 = char[] a potreboval by som spravit insert a updaty tychto stlpcov lenze klasika
$db->exec(„INSERT INTO t1“, $values) kde values je
$values[‚col1‘] = array(1,2);
$values[‚col2‘] = array(‚A‘,‚B‘);
nefunguje resp. vygeneruje mi to zly insert.

Potreboval by som dosiahnut nico taketo

INSERT INTO t1 (col1,col2) VALUES (array[1,2],array[‚A‘, ‚B‘]);

ma niekto na to pekne riesenie alebo plugin + samozrejme escapovanie nad stringamy proste podla typu a podobne dorbnosti

Dakujem

Ot@s
Backer | 476
+
0
-

Ultimátním řešením je dotáhnout drivery Nette\Database i pro „exotické“ databáze (rozuměj ne-MySql). Btw, taky mi dlouhodobě chybí podpora základních fičur jednotlivých (a často používaných) RDBMS. Chápu však, že jen se základem Nette\Database je práce dost. Já osobně si to ošetřuju ve svém „base“ repository (u klasických CRUDových operací). Nevím, jakým způsobem pracuješ s modelem, takže to ber jako obecnou radu.

hrach
Člen | 1838
+
0
-

No, presne jak pise Ot@s, jde o zakladni feature, coz typ sloupce array neni. V ramci ->query to ani nelze detekovat. Protoze neparsujeme query, mnohem zasadnejsi fature v tomto pripade je zajiste multi-insert :)

V ramci Table\Selection by to teoricky detekovat slo, ale jsem spise proti, byl by to zmatek.

Nejvetsim problemem je to, ze neexistuji modifikatory jako v dibi. Mozna by slo neco podobneho vymyslet.

Milo
Nette Core | 1283
+
0
-

Kde to jde, můžeš použít poděděný SqlLiteral. Kde to nejde, pomůže jedna ze statických metod:

class PgArray extends Nette\Database\SqlLiteral
{
	public function __construct(array $arr = NULL)
	{
		parent::__construct(self::toSql($arr));
	}



	final public static function toSql(array $arr = NULL)
	{
		$sql = self::toStringLiteral($arr);
		$sql = self::quoteStringLiteral($sql);
		return $sql;
	}



	final public static function toStringLiteral(array $arr = NULL)
	{
		if ($arr === NULL) {
			return 'NULL';
		}

		$elements = array();
		foreach ($arr as $k => $v) {
			if (is_array($v)) {
				$elements[] = self::toStringLiteral($v);

			} elseif ($v === NULL) {
				$elements[] = 'NULL';

			} elseif (is_int($v)) {
				$elements[] = $v;

			} else {
				$elements[] = self::escapeArrayElement((string) $v);
			}
		}

		return '{' . implode(',', $elements) . '}';
	}



	private static function escapeArrayElement($element)
	{
		return '"' . strtr($element, array('\\' => '\\\\', '"' => '\\"')) . '"';
	}



	private static function quoteStringLiteral($str)
	{
		return "E'" . strtr($str, array('\\' => '\\\\', "'" => "''")) . "'";
	}

}

@hrach Modifikátory by se občas hodily…

Milo
Nette Core | 1283
+
0
-

Mimochodem, verze s INSERT INTO ..... VALUES(ARRAY[?, ?, ?]) by byla daleko lepší, ale pokud vím, PDOStatement::execute() má problémy s bindovanými parametry, protože všechny jsou brány jako string. PostgreSQL pak křičí, že očekává typ int[] ale dostane text[].

hrach
Člen | 1838
+
0
-

@Milo: taky me napadlo neco se SqlLiteral, ale toto je super reseni problemu. Takto se mi to libi a dokazu si predstavit, ze by to bylo v distribuci.

Milo
Nette Core | 1283
+
0
-

Chybí tam konverze pro boolean[], datetime[], double[] a jiné typy. Jinak to používám, sice zřídka, ale bez problému. Také by bylo hezké, kdyby se fetchnuté sloupce typu pole konvertovaly na PHP pole (někde mám zahrabanou NDB která to umí).

Celkově to je ale dost okrajová záležitost. Myslím, že by to bylo hezké jako extension.