1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace LeKoala\Uuid; |
4
|
|
|
|
5
|
|
|
use SilverStripe\ORM\DB; |
6
|
|
|
use SilverStripe\ORM\FieldType\DBField; |
7
|
|
|
use Tuupola\Base62Proxy; |
8
|
|
|
use Ramsey\Uuid\Uuid; |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* A uuid field that stores Uuid in binary formats |
12
|
|
|
* |
13
|
|
|
* Some knowledge... |
14
|
|
|
* |
15
|
|
|
* @link https://paragonie.com/blog/2015/09/comprehensive-guide-url-parameter-encryption-in-php |
16
|
|
|
* @link https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/ |
17
|
|
|
* @link https://mariadb.com/kb/en/library/guiduuid-performance/ |
18
|
|
|
* @link https://stackoverflow.com/questions/28251144/inserting-and-selecting-uuids-as-binary16 |
19
|
|
|
*/ |
20
|
|
|
class DBUuid extends DBField |
21
|
|
|
{ |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* An expression to use in your custom queries |
25
|
|
|
* |
26
|
|
|
* @link https://stackoverflow.com/questions/37168797/how-to-format-uuid-string-from-binary-column-in-mysql-mariadb |
27
|
|
|
* @return string |
28
|
|
|
*/ |
29
|
|
|
public static function sqlFormatExpr() |
30
|
|
|
{ |
31
|
|
|
$sql = <<<SQL |
32
|
|
|
LOWER(CONCAT( |
33
|
|
|
SUBSTR(HEX(Uuid), 1, 8), '-', |
34
|
|
|
SUBSTR(HEX(Uuid), 9, 4), '-', |
35
|
|
|
SUBSTR(HEX(Uuid), 13, 4), '-', |
36
|
|
|
SUBSTR(HEX(Uuid), 17, 4), '-', |
37
|
|
|
SUBSTR(HEX(Uuid), 21) |
38
|
|
|
)) AS UuidFormatted |
39
|
|
|
SQL; |
40
|
|
|
return $sql; |
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
public function requireField() |
44
|
|
|
{ |
45
|
|
|
// Use direct sql statement here |
46
|
|
|
$sql = "binary(16)"; |
47
|
|
|
// In postgres, it's bytea, there is also an uuid but we would need some postgres specific logic |
48
|
|
|
// @link https://stackoverflow.com/questions/26990559/convert-mysql-binary-to-postgresql-bytea |
49
|
|
|
$class = strtolower(get_class(DB::get_conn())); |
50
|
|
|
if (strpos($class, 'postgres') !== false) { |
51
|
|
|
$sql = 'bytea'; |
52
|
|
|
} |
53
|
|
|
DB::require_field($this->tableName, $this->name, $sql); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* @return string A uuid identifier like 0564a64ecdd4a2-7731-3233-3435-7cea2b |
58
|
|
|
*/ |
59
|
|
|
public function Nice() |
60
|
|
|
{ |
61
|
|
|
if (!$this->value) { |
62
|
|
|
return $this->nullValue(); |
|
|
|
|
63
|
|
|
} |
64
|
|
|
return Uuid::fromBytes($this->value)->toString(); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* Return raw value since we store binary(16) representation |
69
|
|
|
* |
70
|
|
|
* @return string The binary representation like b"\x05d¦NÍÔ¢w12345|ê+ |
71
|
|
|
*/ |
72
|
|
|
public function Bytes() |
73
|
|
|
{ |
74
|
|
|
if (!$this->value) { |
75
|
|
|
return $this->nullValue(); |
|
|
|
|
76
|
|
|
} |
77
|
|
|
return $this->value; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Perfect for urls or html usage |
82
|
|
|
* |
83
|
|
|
* @return string A base62 representation like 6a630O1jrtMjCrQDyG3D3O |
84
|
|
|
*/ |
85
|
|
|
public function Base62() |
86
|
|
|
{ |
87
|
|
|
if (!$this->value) { |
88
|
|
|
return $this->nullValue(); |
|
|
|
|
89
|
|
|
} |
90
|
|
|
return Base62Proxy::encode($this->value); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
public function scaffoldFormField($title = null, $params = null) |
94
|
|
|
{ |
95
|
|
|
return false; |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
public function nullValue() |
99
|
|
|
{ |
100
|
|
|
return null; |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
public function setValue($value, $record = null, $markChanged = true) |
104
|
|
|
{ |
105
|
|
|
if ($value && strlen($value) !== 16) { |
106
|
|
|
$value = Uuid::fromString($value)->getBytes(); |
107
|
|
|
} |
108
|
|
|
return parent::setValue($value, $record, $markChanged); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
public function prepValueForDB($value) |
112
|
|
|
{ |
113
|
|
|
if (!$value) { |
114
|
|
|
return $this->nullValue(); |
|
|
|
|
115
|
|
|
} |
116
|
|
|
// Uuid in string format have 36 chars |
117
|
|
|
// Strlen 16 = already binary |
118
|
|
|
if (strlen($value) === 16) { |
119
|
|
|
return $value; |
120
|
|
|
} |
121
|
|
|
return Uuid::fromString($value)->getBytes(); |
122
|
|
|
} |
123
|
|
|
} |
124
|
|
|
|
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()
can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.