Created
December 28, 2021 19:57
-
-
Save nrctkno/b8932941cb98d1814d6ccd3307c576a2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Random | |
{ | |
public static function distributed($elements) | |
{ | |
if (array_sum($elements) !== 100) { | |
throw new \Exception('randomWithDistribution: sum of probabilities must be 100'); | |
} | |
$random = rand(1, 100); | |
$tot = 0; | |
foreach ($elements as $id => $weight) { | |
$tot += $weight; | |
if ($random <= $tot) { | |
return $id; | |
} | |
} | |
} | |
} | |
abstract class RandomType | |
{ | |
protected array $settings; | |
function __construct(array $settings) | |
{ | |
$this->settings = $settings; | |
} | |
abstract function craft(array $record); | |
} | |
class FallbackType extends RandomType | |
{ | |
public function craft(array $record) | |
{ | |
return $this->settings['name'] . ' is not implemented'; | |
} | |
} | |
class RangeType extends RandomType | |
{ | |
public function craft(array $record) | |
{ | |
$min = $this->settings[1][0]; | |
$max = $this->settings[1][1]; | |
return rand($min, $max); | |
} | |
} | |
class OptionType extends RandomType | |
{ | |
public function craft(array $record) | |
{ | |
$entries = $this->settings[1]; | |
return $entries[mt_rand(0, count($entries) - 1)]; | |
} | |
} | |
class WeightedOptionType extends RandomType | |
{ | |
public function craft(array $record) | |
{ | |
return Random::distributed($this->settings[1]); | |
} | |
} | |
class DateType extends RandomType | |
{ | |
public function craft(array $record) | |
{ | |
$min = strtotime($this->settings[1][0]); | |
$max = strtotime($this->settings[1][1]); | |
$time = mt_rand($min, $max); | |
return (new \DateTime())->setTimestamp($time); | |
} | |
} | |
class CustomType extends RandomType | |
{ | |
public function craft(array $record) | |
{ | |
$closure = $this->settings[1]; | |
return $closure($record); | |
} | |
} | |
class Seeder | |
{ | |
public static function seed(int $qty, array $rules, Closure $onGenerated): void | |
{ | |
$generators = self::getGenerators($rules); | |
for ($i = 1; $i <= $qty; $i++) { | |
$record = ['__id__' => $i]; | |
foreach ($generators as $field => $g) { | |
$record[$field] = $g->craft($record); | |
} | |
$onGenerated($record); | |
} | |
} | |
private static function getGenerators(array $rules): array | |
{ | |
$generators = []; | |
foreach ($rules as $field => $rule) { | |
$generators[$field] = self::instantiateGenerator($rule); | |
} | |
return $generators; | |
} | |
private static function instantiateGenerator(array $rule): RandomType | |
{ | |
$generatorName = ucfirst($rule[0]) . 'Type'; | |
if (!class_exists($generatorName)) { | |
return new FallbackType(['name' => $rule[0]]); | |
} | |
return new $generatorName($rule); | |
} | |
} | |
/* | |
Usage | |
*/ | |
$output_file = fopen('output.sql', 'w'); | |
Seeder::seed(40000, [ | |
'status' => ['option', ['a']], | |
'cycle' => ['WeightedOption', ['d' => 97, 'm' => 3]], | |
'grouping' => ['range', [0, 2]], | |
'fiscal_id' => ['range', [1, 2000]], | |
'start' => ['date', ['2021-01-01 00:00:00', '2021-12-31 00:00:00']], | |
'end' => ['custom', function ($record) { | |
$end = clone $record['start']; | |
return $end->modify($record['cycle'] == 'm' ? '+ 1 month' : '+ 1 day'); | |
}], | |
], function (array $record) use($output_file) { | |
$query ='insert into myTable (status, cycle, grouping, fiscal_id, start, end) values ' | |
. sprintf( | |
"('%s', '%s', %d, %d, '%s', '%s');\r\n", | |
$record['status'], | |
$record['cycle'], | |
$record['grouping'], | |
$record['fiscal_id'], | |
$record['start']->format('Y-m-d'), | |
$record['end']->format('Y-m-d') | |
); | |
//echo $query . "<br />"; | |
fwrite($output_file, $query); | |
}); | |
fclose($output_file); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment