Skip to content

Commit 8528391

Browse files
authored
Merge pull request #182 from Planetbiru/feature/version-3.22.0
MagicObject Version 3.22.0
2 parents a67ca20 + 57982d1 commit 8528391

4 files changed

Lines changed: 89 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,3 +1482,22 @@ The powerful `retrieve()` method, which allows for easy access to nested propert
14821482
```php
14831483
$secretConfig->retrieve('database', 'credentials', 'username');
14841484
```
1485+
1486+
# MagicObject Version 3.22.0
1487+
1488+
## What's New
1489+
1490+
1. **UUID Generator**
1491+
Added a native UUID generator that produces standards-compliant UUID values, suitable for distributed systems and cross-database compatibility.
1492+
1493+
2. **Time-Based ID Generator**
1494+
Introduced a time-based ID generator that creates sortable, time-ordered identifiers, improving indexing performance and data traceability.
1495+
1496+
## What's Changed
1497+
1498+
1. **Default Primary Key Generation**
1499+
The default primary key generation strategy for `VARCHAR` columns has been changed to use the **time-based ID generator**, replacing the previous approach.
1500+
1501+
2. **Improved UUID Implementation**
1502+
Replaced the legacy unique ID generation based on PHP’s `uniqid()` function with a **real UUID implementation**, ensuring better uniqueness guarantees and compliance with UUID standards.
1503+

src/Database/PicoDatabase.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,66 @@ public function generateNewId()
12571257
return sprintf('%s%s', $uuid, $random);
12581258
}
12591259

1260+
/**
1261+
* Generate a random UUID (Universally Unique Identifier) version 4.
1262+
*
1263+
* This function creates a 128-bit UUID using random bytes and applies
1264+
* the proper version (4) and variant (RFC 4122) bits. The result is
1265+
* formatted as a canonical string representation:
1266+
* xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
1267+
*
1268+
* Example output:
1269+
* ad271d69-6c5a-4002-b2d2-3e0f84f7dfa3
1270+
*
1271+
* @return string A UUID v4 string in standard format.
1272+
*/
1273+
public function generateUUID() {
1274+
// Generate 16 bytes (128 bit) random data
1275+
$data = random_bytes(16);
1276+
1277+
// Set versi ke 0100 (UUID v4)
1278+
$data[6] = chr((ord($data[6]) & 0x0f) | 0x40);
1279+
// Set variant ke 10xxxxxx
1280+
$data[8] = chr((ord($data[8]) & 0x3f) | 0x80);
1281+
1282+
// Format ke string UUID
1283+
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
1284+
}
1285+
1286+
/**
1287+
* Generates a unique hexadecimal ID based on the current epoch time in nanoseconds
1288+
* combined with a 3-hex-digit random suffix.
1289+
*
1290+
* The ID consists of:
1291+
* - A 17-character hexadecimal timestamp derived from microtime()
1292+
* - A 3-character hexadecimal random value
1293+
*
1294+
* @return string Unique hexadecimal identifier
1295+
*/
1296+
public function generateTimeBasedId()
1297+
{
1298+
// Get microtime as "microseconds seconds"
1299+
$microtimeParts = explode(' ', microtime());
1300+
1301+
// Format microseconds to 9 decimal places
1302+
$microsecondsFormatted = sprintf('%11.9f', $microtimeParts[0]);
1303+
1304+
// Split seconds and fractional microseconds
1305+
$microsecondsParts = explode('.', $microsecondsFormatted);
1306+
1307+
// Combine seconds and fractional part into a nanosecond-like integer string
1308+
$epochNanoString = sprintf('%d%+9s', $microtimeParts[1], $microsecondsParts[1]);
1309+
1310+
// Convert the timestamp to a fixed-length hexadecimal string
1311+
$timestampHex = sprintf('%017x', (int) $epochNanoString);
1312+
1313+
// Generate a 3-hex-digit random value
1314+
$randomHex = sprintf('%03x', mt_rand(0, 0xFFF));
1315+
1316+
// Concatenate timestamp and random suffix
1317+
return $timestampHex . $randomHex;
1318+
}
1319+
12601320
/**
12611321
* Get the last inserted ID.
12621322
*

src/Database/PicoDatabasePersistence.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,15 @@ private function setGeneratedValue($prop, $strategy, $firstCall)
11431143
$this->generatedValue = true;
11441144
}
11451145
}
1146+
else if(stripos($strategy, "TIMEBASED") !== false)
1147+
{
1148+
if($firstCall && ($this->object->get($prop) == null || $this->object->get($prop) == "") && !$this->generatedValue)
1149+
{
1150+
$generatedValue = $this->database->generateTimeBasedId();
1151+
$this->object->set($prop, $generatedValue);
1152+
$this->generatedValue = true;
1153+
}
1154+
}
11461155
else if(stripos($strategy, "IDENTITY") !== false)
11471156
{
11481157
if($firstCall)

src/Generator/PicoEntityGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public function createProperty($typeMap, $columnMap, $row, $nonupdatables = null
125125
if (!empty($columnKey) && stripos($columnKey, "PRI") === 0) {
126126
$docs[] = "\t * @Id";
127127
if (stripos($columnExtra, "auto_increment") === false) {
128-
$docs[] = "\t * @GeneratedValue(strategy=GenerationType.UUID)";
128+
$docs[] = "\t * @GeneratedValue(strategy=GenerationType.TIMEBASED)";
129129
}
130130
}
131131

0 commit comments

Comments
 (0)