Answer the question
In order to leave comments, you need to log in
How long can a request be?
Hello colleagues!
The customer requires the implementation of a method that would perform the cloning of some records.
For example:
On the example of gas stations
There is a network of gas stations, their number reaches 61,000 thousand.
Each gas station has a number of services provided.
It is clear that this is the sale of different types of fuel.
Each gas station has its own list of types, it looks like this:
Gas station A - 17
Gas station B - 18
INSERT INTO `features` (`id`, `name`, `type`, `value`, `organization_id`) VALUES
(36, 'Заправка', 'enum', NULL, 17),
(71, 'Заправка', 'enum', NULL, 18);
INSERT INTO `features_values` (`id`, `feature_id`, `name`) VALUES
(111, 71, 'Аи-92'),
(115, 36, 'Аи-95'),
(113, 36, 'Аи-98'),
(112, 71, 'Дт');
/**
* @Rest\Route(
* path="/features.edit",
* methods={"POST"}
* )
* @param ObjectManager $manager
* @param Request $request
* @param RestMessage $restMessage
* @return JsonResponse
* @throws RestException
* @throws DBALException
*/
public function edit(ObjectManager $manager, Request $request, RestMessage $restMessage)
{
/** @var FeatureRepository $features_repository */
$features_repository = $manager->getRepository("App:Feature");
$feature = $features_repository->findOneBy([
"id" => $request->get("feature_id", 0)]
);
if (!is_object($feature)) {
RestError::exception(RestCode::RECORD_NOT_FOUND);
}
switch ($request->get("type", false)) {
case "bool":
{
$feature->setType("bool");
$feature->setName($request->get("name"));
$feature->setValue($request->get("value"));
foreach ($feature->getValues() as $value) {
$manager->remove($value);
$manager->flush();
}
$manager->persist($feature);
break;
}
case "text":
{
$feature->setType("text");
$feature->setName($request->get("name"));
$feature->setValue($request->get("value"));
foreach ($feature->getValues() as $value) {
$manager->remove($value);
$manager->flush();
}
$manager->persist($feature);
break;
}
case "enum":
{
$feature->setType("enum");
$feature->setName($request->get("name"));
$feature->setValue($request->get(null));
/** @var FeatureValue $old_fv */
$not_persist = [];
foreach ($feature->getValues() as $old_fv) {
$remove_old_fv = true;
foreach ($request->get("value", []) as $new_value) {
if ($new_value == $old_fv->getName()) {
$remove_old_fv = false;
$not_persist[] = $new_value;
break;
}
}
if ($remove_old_fv) {
$manager->remove($old_fv);
$manager->flush();
}
}
foreach ($request->get("value", []) as $item) {
foreach ($not_persist as $np) {
if ($item == $np) continue 2;
}
$feature_value = new FeatureValue();
$feature_value->setName($item);
$feature_value->setFeature($feature);
$feature->getValues()->add($feature_value);
$manager->persist($feature_value);
// Дорогой mysql запрос
if ($request->get("cloning", false)) {
$features_repository->cloning($feature->getName(), $item);
}
}
break;
}
default:
{
RestError::exception(RestCode::REQUEST_WITH_INVALID_PARAMETERS);
}
}
$manager->flush();
return $restMessage->success("Ok");
}
/**
* @param string $feature_name
* @param string $feature_value_name
* @throws DBALException
*/
public function cloning(string $feature_name, string $feature_value_name)
{
$conn = $this->getEntityManager()->getConnection();
$sql = "
INSERT IGNORE INTO features_values (`feature_id`, `name`) (
SELECT DISTINCT f.id, :feature_value_name
FROM features f
LEFT JOIN features_values fv
ON f.id = fv.feature_id
WHERE f.name = :feature_name AND f.`type` = :feature_type
);
";
$stmt = $conn->prepare($sql);
$stmt->execute([
"feature_type" => EnumFeatureType::ENUM_TYPE,
"feature_name" => $feature_name,
"feature_value_name" => $feature_value_name
]);
}
Answer the question
In order to leave comments, you need to log in
Why do you need a LEFT JOIN in your query, the result of which is not used anywhere?
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question