storage enhancements
[m6w6/pq-gateway] / tests / setup.inc
1 <?php
2
3 use pq\Connection;
4 use pq\Gateway\Table;
5 use pq\Mapper\Map;
6 use pq\Mapper\MapInterface;
7 use pq\Mapper\Mapper;
8 use pq\Query\ExecutorInterface;
9 use pq\Query\Writer;
10
11 ini_set("date.timezone", "UTC");
12 ini_set("error_reporting", E_ALL);
13
14 define("PQ_TEST_DSN", getenv("PQ_TEST_DSN"));
15
16 const PQ_TEST_SETUP_SQL = <<<SQL
17 create extension if not exists hstore;
18
19 drop table if exists test cascade;
20 create table test (
21 id serial primary key,
22 created timestamp,
23 counter int,
24 number decimal,
25 data text,
26 list int[],
27 prop hstore
28 );
29
30 drop table if exists reftest cascade;
31 create table reftest (
32 test_id integer not null references test on delete cascade,
33 another_test_id integer not null references test on delete cascade,
34 primary key(test_id, another_test_id)
35 );
36
37 insert into test values (default, 'yesterday', -1, -1.1, 'yesterday', '{-1,0,1}');
38 insert into test values (default, 'today', 0, 0, 'today', '{0,1,2}');
39 insert into test values (default, 'tomorrow', 1, 1.1, 'tomorrow', '{1,2,3}');
40
41 insert into reftest values (1,3);
42 insert into reftest values (2,2);
43 insert into reftest values (3,1);
44 SQL;
45
46 const PQ_TEST_TEARDOWN_SQL = <<<SQL
47 drop table if exists test cascade;
48 drop table if exists reftest cascade;
49 SQL;
50
51 require_once __DIR__ . "/../vendor/autoload.php";
52
53 function executeInConcurrentTransaction(ExecutorInterface $exec, $sql, array $params = array()) {
54 $conn = $exec->getConnection();
55 $xact = (new Connection(PQ_TEST_DSN))->startTransaction();
56 $exec->setConnection($xact->connection);
57 $exec->execute(new Writer($sql, $params));
58 $exec->setConnection($conn);
59 return $xact;
60 }
61
62 class QueryLogger implements SplObserver
63 {
64 protected $fp;
65
66 function __construct($logfile = null) {
67 if (!isset($logfile)) {
68 $logfile = __DIR__."/query.log";
69 }
70 if (!$this->fp = @fopen($logfile, "a")) {
71 throw new RuntimeException(error_get_last()["message"]);
72 }
73 }
74
75 function __destruct() {
76 if (is_resource($this->fp)) {
77 fclose($this->fp);
78 }
79 }
80
81 function update(SplSubject $executor) {
82 $result = $executor->getResult();
83 if (isset($result)) {
84 fprintf($this->fp, "[%s] R %s\n",
85 date_create()->format("Y-m-d H:i:s"),
86 json_encode($result));
87 } elseif (($query = $executor->getQuery())) {
88 $executor->getConnection()->exec("SELECT pg_backend_pid()")->fetchCol($pid);
89 fprintf($this->fp, "[%s] Q %s %% %s @%d\n",
90 date_create()->format("Y-m-d H:i:s"),
91 preg_replace("/\s+/", " ", $query),
92 json_encode($query->getParams()),
93 $pid);
94 }
95 }
96 }
97
98 class TestModel implements JsonSerializable {
99 private $id, $created, $counter, $number, $data, $list, $prop;
100 private $ref1, $ref2;
101
102 function jsonSerialize() {
103 return get_object_vars($this);
104 }
105
106 function __get($p) {
107 return $this->$p;
108 }
109
110 function __set($p, $v) {
111 $this->$p = $v;
112 }
113
114 /**
115 * @param Mapper $mapper
116 * @return MapInterface
117 */
118 static function mapAs(Mapper $mapper) {
119 return new Map(
120 __CLASS__,
121 new Table("test"),
122 $mapper->mapField("id"),
123 $mapper->mapField("created"),
124 $mapper->mapField("counter"),
125 $mapper->mapField("number"),
126 $mapper->mapField("data"),
127 $mapper->mapField("list"),
128 $mapper->mapField("prop"),
129 $mapper->mapAll("ref1")->to(RefTestModel::class)->by("test"),
130 $mapper->mapAll("ref2")->to(RefTestModel::class)->by("another_test")
131 );
132 }
133 }
134
135 class RefTestModel
136 {
137 private $pk1, $pk2;
138 private $one, $two;
139
140 function __get($p) {
141 return $this->$p;
142 }
143
144 function __set($p, $v) {
145 $this->$p = $v;
146 }
147
148 static function mapAs($mapper) {
149 return new Map(
150 __CLASS__,
151 new Table("reftest"),
152 $mapper->mapField("pk1", "test_id"),
153 $mapper->mapField("pk2", "another_test_id"),
154 $mapper->mapRef("one")->to(TestModel::class)->by("test"),
155 $mapper->mapRef("two")->to(TestModel::class)->by("another_test")
156 );
157 }
158 }