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\Entity\Customer;
use App\Service\UniqueIdGenerator;
use PDO; use PDO;
class SetCustomerGeneratedIdCommand extends Command class SetCustomerGeneratedIdCommand extends Command
@ -23,12 +21,13 @@ class SetCustomerGeneratedIdCommand extends Command
const GENERATED_ID_LENGTH = 40; const GENERATED_ID_LENGTH = 40;
private $em; 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->em = $em;
$this->id_gen = $id_gen;
$this->loadGeneratedIds();
parent::__construct(); parent::__construct();
} }
@ -43,9 +42,7 @@ class SetCustomerGeneratedIdCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output)
{ {
$em = $this->em; $em = $this->em;
$db = $em->getConnection();
$batch_size = 20;
$i = 1;
$em->getConnection()->getConfiguration()->setSQLLogger(null); $em->getConnection()->getConfiguration()->setSQLLogger(null);
@ -58,47 +55,29 @@ class SetCustomerGeneratedIdCommand extends Command
$cust = $row[0]; $cust = $row[0];
$output->writeln('Processing customer ' . $cust->getID()); $output->writeln('Processing customer ' . $cust->getID());
// retry until we get a unique generated id
while (true) 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 // add generated id to hash
$cust->setGeneratedId($generated_id); $this->cust_generated_ids[$generated_id] = $cust;
// reopen in case we get an exception break;
if (!$em->isOpen())
{
$em = $em->create(
$em->getConnection(),
$em->getConfiguration()
);
}
//++$i;
//if (($i % $batch_size) === 0)
//{
$em->flush();
$em->clear();
//}
} }
catch (DBALException $e)
{
error_log($e->getMessage());
// delay one second and try again
sleep(1);
continue;
}
break;
} }
$em->detach($row[0]); $em->detach($row[0]);
} }
//$em->flush();
return 0; return 0;
} }
@ -107,4 +86,29 @@ class SetCustomerGeneratedIdCommand extends Command
return substr(md5(time()), 0, $str_length); 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\Entity
* @ORM\Table(name="customer", indexes={ * @ORM\Table(name="customer",
* @ORM\Index(name="phone_mobile_idx", columns={"phone_mobile"}), * uniqueConstraints={
* @ORM\Index(columns={"first_name"}, flags={"fulltext"}), * @ORM\UniqueConstraint(columns={"generated_id"})
* @ORM\Index(columns={"last_name"}, flags={"fulltext"}), * },
@ORM\Index(name="generated_id_idx", 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 class Customer

View file

@ -9,26 +9,27 @@ use App\Entity\Customer;
class UniqueIdGenerator class UniqueIdGenerator
{ {
protected $em; protected $em;
protected $cust_generated_ids;
public function __construct(EntityManagerInterface $em) public function __construct(EntityManagerInterface $em)
{ {
$this->em = $em; $this->em = $em;
$this->loadGeneratedIds();
} }
public function generateCustomerUniqueId($str_length) public function generateCustomerUniqueId($str_length)
{ {
$em = $this->em; $em = $this->em;
// retry until we find no customer with the generated id // retry until we have no duplicate generated id
while (true) while (true)
{ {
// generate the id // generate the id
$generated_id = $this->generateUniqueId($str_length); $generated_id = $this->generateUniqueId($str_length);
// check if generated id already exists // check if generated id already exists
$cust = $em->getRepository(Customer::class)->findOneBy(['generated_id' => $generated_id]); if (!isset($this->cust_generated_ids[$generated_id]))
if ($cust == null)
return $generated_id; return $generated_id;
sleep(1); sleep(1);
@ -40,4 +41,30 @@ class UniqueIdGenerator
{ {
return substr(md5(time()), 0, $str_length); 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]);
}
}
} }