Skip to content

Commit 3e151d4

Browse files
committed
Type improvements
1 parent cd29577 commit 3e151d4

File tree

8 files changed

+188
-21
lines changed

8 files changed

+188
-21
lines changed

src/Session.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,15 +182,17 @@ public function keepAlive()
182182

183183
/**
184184
* @param Closure $closure
185+
* @return mixed
185186
* @throws Exception
186187
*/
187188
public function transaction(Closure $closure)
188189
{
189190
$this->beginTransaction();
190191
try
191192
{
192-
$closure($this);
193+
$result = $closure($this);
193194
$this->commitTransaction();
195+
return $result;
194196
}
195197
catch (Exception $e)
196198
{

src/Statement.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ protected function checkQueryCache()
145145
*/
146146
protected function detectParams()
147147
{
148-
if (preg_match_all('/declare\s+(\$\w+)\s+as\s+(.+?);/i', $this->yql, $matches))
148+
if (preg_match_all('/declare\s+(\$\w+)\s+as\s+(.+?);/is', $this->yql, $matches))
149149
{
150150
foreach ($matches[1] as $i => $param)
151151
{

src/Table.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,12 @@ public function sessionReleased($session)
186186

187187
/**
188188
* @param Closure $closure
189+
* @return mixed
189190
* @throws Exception
190191
*/
191192
public function transaction(Closure $closure)
192193
{
193-
$this->session()->transaction($closure);
194+
return $this->session()->transaction($closure);
194195
}
195196

196197
/**

src/Traits/TypeHelpersTrait.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use YandexCloud\Ydb\Types\DoubleType;
2121
use YandexCloud\Ydb\Types\Uint64Type;
2222
use YandexCloud\Ydb\Types\StringType;
23+
use YandexCloud\Ydb\Types\StructType;
2324
use YandexCloud\Ydb\Types\DecimalType;
2425
use YandexCloud\Ydb\Types\AbstractType;
2526
use YandexCloud\Ydb\Types\DatetimeType;
@@ -428,4 +429,15 @@ public function list($type, $value = null)
428429
->itemType($type);
429430
}
430431

432+
/**
433+
* @param mixed $types
434+
* @param mixed $value
435+
* @return TypeContract
436+
*/
437+
public function struct($types, $value = null)
438+
{
439+
return (new StructType($value))
440+
->itemTypes($types);
441+
}
442+
431443
}

src/Traits/TypeValueHelpersTrait.php

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
use Ydb\Value;
1010
use Ydb\ListType as YdbListType;
1111
use Ydb\TypedValue;
12-
use Ydb\StructType;
12+
use Ydb\StructType as YdbStructType;
1313
use Ydb\StructMember;
1414
use Ydb\Type\PrimitiveTypeId;
1515

@@ -25,6 +25,7 @@
2525
use YandexCloud\Ydb\Types\DoubleType;
2626
use YandexCloud\Ydb\Types\Uint64Type;
2727
use YandexCloud\Ydb\Types\StringType;
28+
use YandexCloud\Ydb\Types\StructType;
2829
use YandexCloud\Ydb\Types\DecimalType;
2930
use YandexCloud\Ydb\Types\DatetimeType;
3031
use YandexCloud\Ydb\Types\TimestampType;
@@ -99,8 +100,8 @@ public function typeValue($value, $type = null)
99100
*/
100101
public function valueOfType($value, $type)
101102
{
102-
$type = strtoupper($type);
103-
switch ($type)
103+
$_type = strtoupper($type);
104+
switch ($_type)
104105
{
105106
case 'BOOL': return new BoolType($value);
106107
case 'TINYINT':
@@ -137,11 +138,16 @@ public function valueOfType($value, $type)
137138
case 'UUID': return new StringType($value);
138139
}
139140

140-
if (substr($type, 0, 4) === 'LIST')
141+
if (substr($_type, 0, 4) === 'LIST')
141142
{
142143
return (new ListType($value))->itemType(trim(substr($type, 5, -1)));
143144
}
144145

146+
else if (substr($_type, 0, 6) === 'STRUCT')
147+
{
148+
return (new StructType($value))->itemTypes(trim(substr($type, 7, -1)));
149+
}
150+
145151
throw new Exception('YDB: Unknown [' . $type . '] type.');
146152
}
147153

@@ -201,7 +207,7 @@ protected function convertBulkRows($rows, $columns_types = [])
201207
{
202208
if (isset($row[$column]))
203209
{
204-
$value = $this->typeValue($row[$column]);
210+
$value = $this->typeValue($row[$column], $columns_types[$column] ?? null);
205211
$item[] = $value->toYdbValue();
206212
}
207213
else
@@ -218,7 +224,7 @@ protected function convertBulkRows($rows, $columns_types = [])
218224
'type' => new Type([
219225
'list_type' => new YdbListType([
220226
'item' => new Type([
221-
'struct_type' => new StructType([
227+
'struct_type' => new YdbStructType([
222228
'members' => array_values($struct_members),
223229
]),
224230
])
@@ -275,8 +281,10 @@ protected function convertType($type)
275281
case 'DYNUMBER': return PrimitiveTypeId::DYNUMBER;
276282

277283
case 'PRIMITIVE_TYPE_ID_UNSPECIFIED':
278-
default:
279284
return PrimitiveTypeId::PRIMITIVE_TYPE_ID_UNSPECIFIED;
285+
286+
default:
287+
return null;
280288
}
281289
}
282290

src/Types/IntType.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,22 @@ public function getYdbType()
5151
{
5252
if ($this->bits === 8)
5353
{
54-
return $this->unsigned ? 'UINT8' : 'INT8';
54+
$this->ydb_type = $this->unsigned ? 'UINT8' : 'INT8';
5555
}
5656
else if ($this->bits === 16)
5757
{
58-
return $this->unsigned ? 'UINT16' : 'INT16';
58+
$this->ydb_type = $this->unsigned ? 'UINT16' : 'INT16';
5959
}
6060
else if ($this->bits === 32)
6161
{
62-
return $this->unsigned ? 'UINT32' : 'INT32';
62+
$this->ydb_type = $this->unsigned ? 'UINT32' : 'INT32';
6363
}
6464
else if ($this->bits === 64)
6565
{
66-
return $this->unsigned ? 'UINT64' : 'INT64';
66+
$this->ydb_type = $this->unsigned ? 'UINT64' : 'INT64';
6767
}
68+
69+
return parent::getYdbType();
6870
}
6971

7072
/**

src/Types/ListType.php

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ protected function normalizeValue($value)
2727
*/
2828
public function itemType($type)
2929
{
30-
$this->itemType = strtoupper($type);
30+
$this->itemType = $type;
3131
return $this;
3232
}
3333

@@ -53,13 +53,27 @@ public function toYdbValue()
5353
*/
5454
public function getYdbType()
5555
{
56-
return new Type([
57-
'list_type' => new YdbListType([
58-
'item' => new Type([
59-
'type_id' => $this->convertType($this->itemType),
56+
$type_id = $this->convertType($this->itemType);
57+
58+
if ($type_id)
59+
{
60+
return new Type([
61+
'list_type' => new YdbListType([
62+
'item' => new Type([
63+
'type_id' => $type_id,
64+
]),
6065
]),
61-
]),
62-
]);
66+
]);
67+
}
68+
else
69+
{
70+
$value = $this->typeValue('', $this->itemType);
71+
return new Type([
72+
'list_type' => new YdbListType([
73+
'item' => $value->getYdbType(),
74+
]),
75+
]);
76+
}
6377
}
6478

6579
/**

src/Types/StructType.php

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<?php
2+
3+
namespace YandexCloud\Ydb\Types;
4+
5+
use Ydb\Type;
6+
use Ydb\Value;
7+
use Ydb\StructType as YdbStructType;
8+
use Ydb\StructMember;
9+
10+
class StructType extends AbstractType
11+
{
12+
/**
13+
* @var array
14+
*/
15+
protected $itemTypes = [];
16+
17+
/**
18+
* @param string|array $types
19+
* @return $this
20+
*/
21+
public function itemTypes($types)
22+
{
23+
if (is_array($types))
24+
{
25+
$this->itemTypes = $types;
26+
}
27+
else
28+
{
29+
$this->itemTypes = [];
30+
$types = array_map('trim', explode(',', $types));
31+
foreach ($types as $type)
32+
{
33+
list($name, $type) = array_map('trim', explode(':', $type));
34+
$this->itemTypes[$name] = $type;
35+
}
36+
}
37+
return $this;
38+
}
39+
40+
/**
41+
* @inherit
42+
*/
43+
public function toYdbValue()
44+
{
45+
if ($this->value === null)
46+
{
47+
return new Value(['items' => []]);
48+
}
49+
50+
return new Value([
51+
'items' => $this->convertValue(),
52+
]);
53+
}
54+
55+
/**
56+
* @inherit
57+
*/
58+
public function getYdbType()
59+
{
60+
return new Type([
61+
'struct_type' => new YdbStructType([
62+
'members' => $this->convertToStructMember(),
63+
]),
64+
]);
65+
}
66+
67+
/**
68+
* @inherit
69+
*/
70+
public function toYdbType()
71+
{
72+
return $this->getYdbType();
73+
}
74+
75+
/**
76+
* @inherit
77+
*/
78+
protected function getYqlString()
79+
{
80+
$value = implode(', ', array_map(function($item) {
81+
return $item->toYqlString();
82+
}, $this->convertValue()));
83+
84+
return '(' . $value . ')';
85+
}
86+
87+
protected function convertToStructMember()
88+
{
89+
$members = [];
90+
91+
foreach ($this->itemTypes as $name => $type)
92+
{
93+
$members[] = new StructMember([
94+
'name' => $name,
95+
'type' => new Type([
96+
'type_id' => $this->convertType($type),
97+
]),
98+
]);
99+
}
100+
101+
return $members;
102+
}
103+
104+
protected function convertValue()
105+
{
106+
if ($this->value)
107+
{
108+
$items = (array)$this->value;
109+
110+
$data = [];
111+
112+
foreach ($this->itemTypes as $name => $type)
113+
{
114+
if (isset($items[$name]))
115+
{
116+
$value = $this->typeValue($items[$name], $type);
117+
$data[$name] = $value->toYdbValue();
118+
}
119+
}
120+
121+
return $data;
122+
}
123+
else
124+
{
125+
return $this->value;
126+
}
127+
}
128+
}

0 commit comments

Comments
 (0)