Add unique constraint for generated id. Add hash for generated ids for checking. #638

This commit is contained in:
Korina Cordero 2021-11-12 04:58:52 +00:00
parent 67429113dd
commit cd7b3c9e62
3 changed files with 83 additions and 48 deletions

View file

@ -14,8 +14,6 @@ use Doctrine\DBAL\DBALException;
use App\Entity\Customer;
use App\Service\UniqueIdGenerator;
use PDO;
class SetCustomerGeneratedIdCommand extends Command
@ -23,12 +21,13 @@ class SetCustomerGeneratedIdCommand extends Command
const GENERATED_ID_LENGTH = 40;
private $em;
private $id_gen;
protected $cust_generated_ids;
public function __construct(EntityManagerInterface $em, UniqueIdGenerator $id_gen)
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
$this->id_gen = $id_gen;
$this->loadGeneratedIds();
parent::__construct();
}
@ -43,9 +42,7 @@ class SetCustomerGeneratedIdCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->em;
$batch_size = 20;
$i = 1;
$db = $em->getConnection();
$em->getConnection()->getConfiguration()->setSQLLogger(null);
@ -58,47 +55,29 @@ class SetCustomerGeneratedIdCommand extends Command
$cust = $row[0];
$output->writeln('Processing customer ' . $cust->getID());
// retry until we get a unique generated id
while (true)
{
try
$generated_id = $this->generateUniqueId(self::GENERATED_ID_LENGTH);
if (!isset($this->cust_generated_ids[$generated_id]))
{
$generated_id = $this->generateUniqueId(self::GENERATED_ID_LENGTH);
$update_sql = 'UPDATE customer SET generated_id = :generated_id WHERE id = :cust_id';
$update_stmt = $db->prepare($update_sql);
$update_stmt->execute([
'generated_id' => $generated_id,
'cust_id' => $cust->getID(),
]);
// set generated id
$cust->setGeneratedId($generated_id);
// add generated id to hash
$this->cust_generated_ids[$generated_id] = $cust;
// reopen in case we get an exception
if (!$em->isOpen())
{
$em = $em->create(
$em->getConnection(),
$em->getConfiguration()
);
}
//++$i;
//if (($i % $batch_size) === 0)
//{
$em->flush();
$em->clear();
//}
break;
}
catch (DBALException $e)
{
error_log($e->getMessage());
// delay one second and try again
sleep(1);
continue;
}
break;
}
$em->detach($row[0]);
}
//$em->flush();
return 0;
}
@ -107,4 +86,29 @@ class SetCustomerGeneratedIdCommand extends Command
return substr(md5(time()), 0, $str_length);
}
protected function loadGeneratedIds()
{
error_log('loading generated ids ');
$cust_q = $this->em->createQuery('select c from App\Entity\Customer c where c.generated_id is not null');
$cust_iter = $cust_q->iterate();
$this->cust_generated_ids = [];
foreach ($cust_iter as $row)
{
$customer = $row[0];
$generated_id = $customer->getGeneratedID();
error_log('generated id = ' . $generated_id);
if ($generated_id != null)
{
error_log('generated id is not null ' . $generated_id);
if (!isset($this->cust_generated_ids[$generated_id]))
{
error_log('setting to hash ' . $generated_id);
$this->cust_generated_ids[$generated_id] = $customer;
}
}
$this->em->detach($row[0]);
}
}
}

View file

@ -12,11 +12,15 @@ use App\Ramcar\CustomerClassification;
/**
* @ORM\Entity
* @ORM\Table(name="customer", indexes={
* @ORM\Index(name="phone_mobile_idx", columns={"phone_mobile"}),
* @ORM\Index(columns={"first_name"}, flags={"fulltext"}),
* @ORM\Index(columns={"last_name"}, flags={"fulltext"}),
@ORM\Index(name="generated_id_idx", columns={"generated_id"})
* @ORM\Table(name="customer",
* uniqueConstraints={
* @ORM\UniqueConstraint(columns={"generated_id"})
* },
* indexes={
* @ORM\Index(name="phone_mobile_idx", columns={"phone_mobile"}),
* @ORM\Index(columns={"first_name"}, flags={"fulltext"}),
* @ORM\Index(columns={"last_name"}, flags={"fulltext"}),
@ORM\Index(name="generated_id_idx", columns={"generated_id"})
* })
*/
class Customer

View file

@ -9,26 +9,27 @@ use App\Entity\Customer;
class UniqueIdGenerator
{
protected $em;
protected $cust_generated_ids;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
$this->loadGeneratedIds();
}
public function generateCustomerUniqueId($str_length)
{
$em = $this->em;
// retry until we find no customer with the generated id
// retry until we have no duplicate generated id
while (true)
{
// generate the id
$generated_id = $this->generateUniqueId($str_length);
// check if generated id already exists
$cust = $em->getRepository(Customer::class)->findOneBy(['generated_id' => $generated_id]);
if ($cust == null)
if (!isset($this->cust_generated_ids[$generated_id]))
return $generated_id;
sleep(1);
@ -40,4 +41,30 @@ class UniqueIdGenerator
{
return substr(md5(time()), 0, $str_length);
}
protected function loadGeneratedIds()
{
error_log('loading generated ids ');
$cust_q = $this->em->createQuery('select c from App\Entity\Customer c where c.generated_id is not null');
$cust_iter = $cust_q->iterate();
$this->cust_generated_ids = [];
foreach ($cust_iter as $row)
{
$customer = $row[0];
$generated_id = $customer->getGeneratedID();
error_log('generated id = ' . $generated_id);
if ($generated_id != null)
{
error_log('generated id is not null ' . $generated_id);
if (!isset($this->cust_generated_ids[$generated_id]))
{
error_log('setting to hash ' . $generated_id);
$this->cust_generated_ids[$generated_id] = $customer;
}
}
$this->em->detach($row[0]);
}
}
}