353 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			353 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| namespace nulib\db\sqlite;
 | |
| 
 | |
| use nulib\cl;
 | |
| use nulib\db\Capacitor;
 | |
| use nulib\db\CapacitorChannel;
 | |
| use nulib\tests\TestCase;
 | |
| 
 | |
| class SqliteStorageTest extends TestCase {
 | |
|   static function Txx(...$values): void {
 | |
|     foreach ($values as $value) {
 | |
|       var_export($value);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   function _testChargeStrings(SqliteStorage $storage, ?string $channel) {
 | |
|     $storage->reset($channel);
 | |
|     $storage->charge($channel, "first");
 | |
|     $storage->charge($channel, "second");
 | |
|     $storage->charge($channel, "third");
 | |
|     $items = cl::all($storage->discharge($channel, false));
 | |
|     self::assertSame(["first", "second", "third"], $items);
 | |
|   }
 | |
| 
 | |
|   function _testChargeArrays(SqliteStorage $storage, ?string $channel) {
 | |
|     $storage->reset($channel);
 | |
|     $storage->charge($channel, ["id" => 10, "name" => "first"]);
 | |
|     $storage->charge($channel, ["name" => "second", "id" => 20]);
 | |
|     $storage->charge($channel, ["name" => "third", "id" => "30"]);
 | |
|   }
 | |
| 
 | |
|   function testChargeStrings() {
 | |
|     $storage = new SqliteStorage(__DIR__.'/capacitor.db');
 | |
|     $this->_testChargeStrings($storage, null);
 | |
|     $storage->close();
 | |
|   }
 | |
| 
 | |
|   function testChargeArrays() {
 | |
|     $storage = new SqliteStorage(__DIR__.'/capacitor.db');
 | |
|     $storage->addChannel(new class extends CapacitorChannel {
 | |
|       const NAME = "arrays";
 | |
|       const COLUMN_DEFINITIONS = ["id" => "integer"];
 | |
| 
 | |
|       function getItemValues($item): ?array {
 | |
|         return ["id" => $item["id"] ?? null];
 | |
|       }
 | |
|     });
 | |
| 
 | |
|     $this->_testChargeStrings($storage, "strings");
 | |
|     $this->_testChargeArrays($storage, "arrays");
 | |
|     $storage->close();
 | |
|   }
 | |
| 
 | |
|   function testEach() {
 | |
|     $storage = new SqliteStorage(__DIR__.'/capacitor.db');
 | |
|     $capacitor = new Capacitor($storage, new class extends CapacitorChannel {
 | |
|       const NAME = "each";
 | |
|       const COLUMN_DEFINITIONS = [
 | |
|         "age" => "integer",
 | |
|         "done" => "integer default 0",
 | |
|       ];
 | |
| 
 | |
|       function getItemValues($item): ?array {
 | |
|         return [
 | |
|           "age" => $item["age"],
 | |
|         ];
 | |
|       }
 | |
|     });
 | |
| 
 | |
|     $capacitor->reset();
 | |
|     $capacitor->charge(["name" => "first", "age" => 5]);
 | |
|     $capacitor->charge(["name" => "second", "age" => 10]);
 | |
|     $capacitor->charge(["name" => "third", "age" => 15]);
 | |
|     $capacitor->charge(["name" => "fourth", "age" => 20]);
 | |
| 
 | |
|     $setDone = function ($row, $suffix=null) {
 | |
|       $item = $row["item"];
 | |
|       $updates = ["done" => 1];
 | |
|       if ($suffix !== null) {
 | |
|         $item["name"] .= $suffix;
 | |
|         $updates["item"] = $item;
 | |
|       }
 | |
|       return $updates;
 | |
|     };
 | |
|     $capacitor->each(["age" => [">", 10]], $setDone, ["++"]);
 | |
|     $capacitor->each(["done" => 0], $setDone);
 | |
| 
 | |
|     self::Txx(cl::all($capacitor->discharge(false)));
 | |
|     $capacitor->close();
 | |
|     self::assertTrue(true);
 | |
|   }
 | |
| 
 | |
|   function testPrimayKey() {
 | |
|     $storage = new SqliteStorage(__DIR__.'/capacitor.db');
 | |
|     $capacitor = new Capacitor($storage, new class extends CapacitorChannel {
 | |
|       const NAME = "pk";
 | |
|       const COLUMN_DEFINITIONS = [
 | |
|         "id_" => "varchar primary key",
 | |
|         "done" => "integer default 0",
 | |
|       ];
 | |
| 
 | |
|       function getItemValues($item): ?array {
 | |
|         return [
 | |
|           "id_" => $item["numero"],
 | |
|         ];
 | |
|       }
 | |
|     });
 | |
| 
 | |
|     $capacitor->charge(["numero" => "a", "name" => "first", "age" => 5]);
 | |
|     $capacitor->charge(["numero" => "b", "name" => "second", "age" => 10]);
 | |
|     $capacitor->charge(["numero" => "c", "name" => "third", "age" => 15]);
 | |
|     $capacitor->charge(["numero" => "d", "name" => "fourth", "age" => 20]);
 | |
|     sleep(2);
 | |
|     $capacitor->charge(["numero" => "b", "name" => "second", "age" => 100]);
 | |
|     $capacitor->charge(["numero" => "d", "name" => "fourth", "age" => 200]);
 | |
| 
 | |
|     $capacitor->close();
 | |
|     self::assertTrue(true);
 | |
|   }
 | |
| 
 | |
|   function testSum() {
 | |
|     $storage = new SqliteStorage(__DIR__.'/capacitor.db');
 | |
|     $capacitor = new Capacitor($storage, new class extends CapacitorChannel {
 | |
|       const NAME = "sum";
 | |
|       const COLUMN_DEFINITIONS = [
 | |
|         "a__" => "varchar",
 | |
|         "b__" => "varchar",
 | |
|         "b__sum_" => "sersum",
 | |
|       ];
 | |
| 
 | |
|       function getItemValues($item): ?array {
 | |
|         return [
 | |
|           "a" => $item["a"],
 | |
|           "b" => $item["b"],
 | |
|         ];
 | |
|       }
 | |
|     });
 | |
| 
 | |
|     $capacitor->reset();
 | |
|     $capacitor->charge(["a" => null, "b" => null]);
 | |
|     $capacitor->charge(["a" => "first", "b" => "second"]);
 | |
| 
 | |
|     self::Txx("=== all");
 | |
|     /** @var Sqlite $sqlite */
 | |
|     $sqlite = $capacitor->getStorage()->db();
 | |
|     self::Txx(cl::all($sqlite->all([
 | |
|       "select",
 | |
|       "from" => $capacitor->getChannel()->getTableName(),
 | |
|     ])));
 | |
|     self::Txx("=== each");
 | |
|     $capacitor->each(null, function ($row) {
 | |
|       self::Txx($row);
 | |
|     });
 | |
| 
 | |
|     $capacitor->close();
 | |
|     self::assertTrue(true);
 | |
|   }
 | |
| 
 | |
|   function testEachValues() {
 | |
|     # tester que values contient bien toutes les valeurs de la ligne
 | |
|     $storage = new SqliteStorage(__DIR__.'/capacitor.db');
 | |
|     $capacitor = new Capacitor($storage, new class extends CapacitorChannel {
 | |
|       const NAME = "each_values";
 | |
|       const COLUMN_DEFINITIONS = [
 | |
|         "name" => "varchar primary key",
 | |
|         "age" => "integer",
 | |
|         "done" => "integer default 0",
 | |
|         "notes" => "text",
 | |
|       ];
 | |
| 
 | |
|       function getItemValues($item): ?array {
 | |
|         return [
 | |
|           "name" => $item["name"],
 | |
|           "age" => $item["age"],
 | |
|         ];
 | |
|       }
 | |
|     });
 | |
| 
 | |
|     $capacitor->reset();
 | |
|     $capacitor->charge(["name" => "first", "age" => 5], function($item, ?array $row, ?array $prow) {
 | |
|       self::assertSame("first", $item["name"]);
 | |
|       self::assertSame(5, $item["age"]);
 | |
|       self::assertnotnull($row);
 | |
|       self::assertSame(["name", "age", "item", "item__sum_", "created_", "modified_"], array_keys($row));
 | |
|       self::assertSame([
 | |
|         "name" => "first",
 | |
|         "age" => 5,
 | |
|         "item" => $item,
 | |
|       ], cl::select($row, ["name", "age", "item"]));
 | |
|       self::assertNull($prow);
 | |
|     });
 | |
|     $capacitor->charge(["name" => "first", "age" => 10], function($item, ?array $row, ?array $prow) {
 | |
|       self::assertSame("first", $item["name"]);
 | |
|       self::assertSame(10, $item["age"]);
 | |
|       self::assertnotnull($row);
 | |
|       self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($row));
 | |
|       self::assertSame([
 | |
|         "name" => "first",
 | |
|         "age" => 10,
 | |
|         "done" => 0,
 | |
|         "notes" => null,
 | |
|         "item" => $item,
 | |
|       ], cl::select($row, ["name", "age", "done", "notes", "item"]));
 | |
|       self::assertNotNull($prow);
 | |
|       self::assertSame([
 | |
|         "name" => "first",
 | |
|         "age" => 5,
 | |
|         "done" => 0,
 | |
|         "notes" => null,
 | |
|         "item" => ["name" => "first", "age" => 5],
 | |
|       ], cl::select($prow, ["name", "age", "done", "notes", "item"]));
 | |
|     });
 | |
| 
 | |
|     $capacitor->each(null, function(array $row) {
 | |
|       $item = $row["item"];
 | |
|       self::assertSame("first", $item["name"]);
 | |
|       self::assertSame(10, $item["age"]);
 | |
|       self::assertnotnull($row);
 | |
|       self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($row));
 | |
|       self::assertSame([
 | |
|         "name" => "first",
 | |
|         "age" => 10,
 | |
|         "done" => 0,
 | |
|         "notes" => null,
 | |
|         "item" => $item,
 | |
|       ], cl::select($row, ["name", "age", "done", "notes", "item"]));
 | |
|       return [
 | |
|         "done" => 1,
 | |
|         "notes" => "modified",
 | |
|       ];
 | |
|     });
 | |
|     $capacitor->charge(["name" => "first", "age" => 10], function($item, ?array $row, ?array $prow) {
 | |
|       self::assertSame("first", $item["name"]);
 | |
|       self::assertSame(10, $item["age"]);
 | |
|       self::assertnotnull($row);
 | |
|       self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($row));
 | |
|       self::assertSame([
 | |
|         "name" => "first",
 | |
|         "age" => 10,
 | |
|         "done" => 1,
 | |
|         "notes" => "modified",
 | |
|         "item" => $item,
 | |
|       ], cl::select($row, ["name", "age", "done", "notes", "item"]));
 | |
|       self::assertNotNull($prow);
 | |
|       self::assertSame([
 | |
|         "name" => "first",
 | |
|         "age" => 10,
 | |
|         "done" => 1,
 | |
|         "notes" => "modified",
 | |
|         "item" => $item,
 | |
|       ], cl::select($prow, ["name", "age", "done", "notes", "item"]));
 | |
|     });
 | |
| 
 | |
|     $capacitor->charge(["name" => "first", "age" => 20], function($item, ?array $row, ?array $prow) {
 | |
|       self::assertSame("first", $item["name"]);
 | |
|       self::assertSame(20, $item["age"]);
 | |
|       self::assertnotnull($row);
 | |
|       self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($row));
 | |
|       self::assertSame([
 | |
|         "name" => "first",
 | |
|         "age" => 20,
 | |
|         "done" => 1,
 | |
|         "notes" => "modified",
 | |
|         "item" => $item,
 | |
|       ], cl::select($row, ["name", "age", "done", "notes", "item"]));
 | |
|       self::assertNotNull($prow);
 | |
|       self::assertSame([
 | |
|         "name" => "first",
 | |
|         "age" => 10,
 | |
|         "done" => 1,
 | |
|         "notes" => "modified",
 | |
|         "item" => ["name" => "first", "age" => 10],
 | |
|       ], cl::select($prow, ["name", "age", "done", "notes", "item"]));
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   function testSetItemNull() {
 | |
|     # tester le forçage de $îtem à null pour économiser la place
 | |
|     $storage = new SqliteStorage(__DIR__.'/capacitor.db');
 | |
|     $capacitor = new Capacitor($storage, new class extends CapacitorChannel {
 | |
|       const NAME = "set_item_null";
 | |
|       const COLUMN_DEFINITIONS = [
 | |
|         "name" => "varchar primary key",
 | |
|         "age" => "integer",
 | |
|         "done" => "integer default 0",
 | |
|         "notes" => "text",
 | |
|       ];
 | |
| 
 | |
|       function getItemValues($item): ?array {
 | |
|         return [
 | |
|           "name" => $item["name"],
 | |
|           "age" => $item["age"],
 | |
|         ];
 | |
|       }
 | |
|     });
 | |
| 
 | |
|     $capacitor->reset();
 | |
|     $nbModified = $capacitor->charge(["name" => "first", "age" => 5], function ($item, ?array $row, ?array $prow) {
 | |
|       self::assertSame([
 | |
|         "name" => "first", "age" => 5,
 | |
|         "item" => $item,
 | |
|       ], cl::select($row, ["name", "age", "item"]));
 | |
|       return ["item" => null];
 | |
|     });
 | |
|     self::assertSame(1, $nbModified);
 | |
|     sleep(1);
 | |
|     # nb: on met des sleep() pour que la date de modification soit systématiquement différente
 | |
| 
 | |
|     $nbModified = $capacitor->charge(["name" => "first", "age" => 10], function ($item, ?array $row, ?array $prow) {
 | |
|       self::assertSame([
 | |
|         "name" => "first", "age" => 10,
 | |
|         "item" => $item, "item__sum_" => "9181336dfca20c86313d6065d89aa2ad5070b0fc",
 | |
|       ], cl::select($row, ["name", "age", "item", "item__sum_"]));
 | |
|       self::assertSame([
 | |
|         "name" => "first", "age" => 5,
 | |
|         "item" => null, "item__sum_" => null,
 | |
|       ], cl::select($prow, ["name", "age", "item", "item__sum_"]));
 | |
|       return ["item" => null];
 | |
|     });
 | |
|     self::assertSame(1, $nbModified);
 | |
|     sleep(1);
 | |
| 
 | |
|     # pas de modification ici
 | |
|     $nbModified = $capacitor->charge(["name" => "first", "age" => 10], function ($item, ?array $row, ?array $prow) {
 | |
|       self::assertSame([
 | |
|         "name" => "first", "age" => 10,
 | |
|         "item" => $item, "item__sum_" => "9181336dfca20c86313d6065d89aa2ad5070b0fc",
 | |
|       ], cl::select($row, ["name", "age", "item", "item__sum_"]));
 | |
|       self::assertSame([
 | |
|         "name" => "first", "age" => 10,
 | |
|         "item" => null, "item__sum_" => null,
 | |
|       ], cl::select($prow, ["name", "age", "item", "item__sum_"]));
 | |
|       return ["item" => null];
 | |
|     });
 | |
|     self::assertSame(0, $nbModified);
 | |
|     sleep(1);
 | |
| 
 | |
|     $nbModified = $capacitor->charge(["name" => "first", "age" => 20], function ($item, ?array $row, ?array $prow) {
 | |
|       self::assertSame([
 | |
|         "name" => "first", "age" => 20,
 | |
|         "item" => $item, "item__sum_" => "001b91982b4e0883b75428c0eb28573a5dc5f7a5",
 | |
|       ], cl::select($row, ["name", "age", "item", "item__sum_"]));
 | |
|       self::assertSame([
 | |
|         "name" => "first", "age" => 10,
 | |
|         "item" => null, "item__sum_" => null,
 | |
|       ], cl::select($prow, ["name", "age", "item", "item__sum_"]));
 | |
|       return ["item" => null];
 | |
|     });
 | |
|     self::assertSame(1, $nbModified);
 | |
|     sleep(1);
 | |
|   }
 | |
| }
 |