dbmsv4 init...3

This commit is contained in:
최준흠 2025-12-16 13:15:48 +09:00
parent 9a0b2eee5a
commit 45a8b92528
28 changed files with 39 additions and 84 deletions

File diff suppressed because one or more lines are too long

View File

@ -116,7 +116,7 @@ abstract class CommonForm
return $this->_batchjobButtons; return $this->_batchjobButtons;
} }
//Validation용 //Validation용
final public function validate(array $formDatas): bool final public function validate(array $formDatas): void
{ {
if ($this->_validation === null) { if ($this->_validation === null) {
throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생: Validation 서비스가 초기화되지 않았습니다."); throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생: Validation 서비스가 초기화되지 않았습니다.");
@ -134,7 +134,7 @@ abstract class CommonForm
} }
// setRules의 세 번째 인자로 레이블 전달 // setRules의 세 번째 인자로 레이블 전달
$this->_validation->setRules($dynamicRules, [], $dynamicLabels); $this->_validation->setRules($dynamicRules, [], $dynamicLabels);
if ($this->_validation->run($formDatas)) { if (!$this->_validation->run($formDatas)) {
throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 데이터 검증 오류발생: " . var_export($this->_validation->getErrors(), true)); throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 데이터 검증 오류발생: " . var_export($this->_validation->getErrors(), true));
} }
} catch (\Throwable $e) { } catch (\Throwable $e) {
@ -177,7 +177,7 @@ abstract class CommonForm
break; break;
case "code": case "code":
// a-zA-Z → 영문 대소문자,0-9 → 숫자,가-힣 → 한글 완성형,\- → 하이픈 // a-zA-Z → 영문 대소문자,0-9 → 숫자,가-힣 → 한글 완성형,\- → 하이픈
$rule = sprintf("required|regex_match[/^[a-zA-Z0-9가-힣\-]+$/]|min_length[4]|max_length[20]%s", in_array($action, ["create"]) ? "|is_unique[{$this->getAttribute('table')}.{$field}]" : ""); $rule = sprintf("required|regex_match[/^[a-zA-Z0-9가-힣\-\_]+$/]|min_length[4]%s", in_array($action, ["create"]) ? "|is_unique[{$this->getAttribute('table')}.{$field}]" : "");
break; break;
case "user_uid": case "user_uid":
$rule = "required|numeric"; $rule = "required|numeric";

View File

@ -20,7 +20,6 @@ class BoardModel extends CommonModel
"title", "title",
"content", "content",
"status", "status",
"updated_at",
]; ];
public function __construct() public function __construct()
{ {

View File

@ -14,9 +14,17 @@ abstract class CommonModel extends Model
protected $useSoftDeletes = false; protected $useSoftDeletes = false;
protected $protectFields = true; protected $protectFields = true;
protected $allowedFields = []; protected $allowedFields = [];
// $allowEmptyInserts = false (기본값): 삽입할 데이터가 전혀 없는 경우, CI4는 오류를 발생시키며 쿼리 실행을 막습니다. (보안 및 데이터 무결성 목적)
// $allowEmptyInserts = true: 삽입할 데이터가 없어도 INSERT INTO table_name () VALUES () 같은 빈 쿼리 실행을 허용합니다 (극히 드문 경우에 사용).
protected bool $allowEmptyInserts = false; protected bool $allowEmptyInserts = false;
protected bool $updateOnlyChanged = true; protected bool $updateOnlyChanged = true;
// protected $useEmptyStringIfNull = true; (기본값)
// 이 기본 설정 때문에 PHP의 null 값이 데이터베이스로 전달될 때 실제 SQL의 NULL 키워드가 아닌 **빈 문자열 ('')**로 변환되고 있습니다.
// 그리고 데이터베이스(MySQL 등)의 설정에 따라 빈 문자열이 업데이트 쿼리에서 무시되거나, 해당 컬럼의 기존 값이 유지되는 현상이 발생합니다.
protected $useEmptyStringIfNull = false; //NULL값도 넣을려면 false
protected array $casts = []; protected array $casts = [];
protected array $castHandlers = []; protected array $castHandlers = [];
@ -35,9 +43,9 @@ abstract class CommonModel extends Model
// Callbacks // Callbacks
protected $allowCallbacks = true; protected $allowCallbacks = true;
protected $beforeInsert = ['_cleanNullsForDefaults']; //Field 값이 NULL일 경우 DB Default값 적용용 protected $beforeInsert = []; //Field 값이 NULL일 경우 DB Default값 적용용
protected $afterInsert = []; protected $afterInsert = [];
protected $beforeUpdate = ['_cleanNullsForDefaults']; //Field 값이 NULL일 경우 DB Default값 적용용 protected $beforeUpdate = []; //Field 값이 NULL일 경우 DB Default값 적용용
protected $afterUpdate = []; protected $afterUpdate = [];
protected $beforeFind = []; protected $beforeFind = [];
protected $afterFind = []; protected $afterFind = [];
@ -63,24 +71,8 @@ abstract class CommonModel extends Model
{ {
return $this->useAutoIncrement; return $this->useAutoIncrement;
} }
final public function getAllowedFields(): array
// 이 훅은 save() 메서드 실행 시 자동으로 호출됩니다.
protected function _cleanNullsForDefaults(array $data): array
{ {
// $data['data'] 배열에 실제 INSERT/UPDATE 될 데이터가 들어있습니다. return $this->allowedFields;
if (!isset($data['data']) || !is_array($data['data'])) {
return $data;
}
// 데이터 배열을 순회하며 값이 null인 필드를 제거합니다.
foreach ($data['data'] as $key => $value) {
// 이 필드가 Primary Key가 아니면서 (PK는 Update 시 필요)
// 값이 null이면 DB에 명시하지 않도록 배열에서 제거합니다.
if ($key !== $this->primaryKey && $value === null) {
unset($data['data'][$key]);
}
}
return $data;
} }
} }

View File

@ -26,7 +26,6 @@ class ClientModel extends CustomerModel
"coupon_balance", "coupon_balance",
"point_balance", "point_balance",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -32,7 +32,6 @@ class ServiceModel extends CustomerModel
"end_at", "end_at",
"history", "history",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -24,7 +24,6 @@ class AccountModel extends WalletModel
"amount", "amount",
"balance", "balance",
"status", "status",
"updated_at",
]; ];
public function __construct() public function __construct()
{ {

View File

@ -20,7 +20,6 @@ class CouponModel extends WalletModel
"content", "content",
"amount", "amount",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -20,7 +20,6 @@ class PointModel extends WalletModel
"content", "content",
"amount", "amount",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -20,7 +20,6 @@ class CHASSISModel extends EquipmentModel
"used", "used",
"stock", "stock",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -20,7 +20,6 @@ class LineModel extends EquipmentModel
"start_at", "start_at",
"end_at", "end_at",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -28,7 +28,6 @@ class ServerModel extends EquipmentModel
"manufactur_at", "manufactur_at",
"format_at", "format_at",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -24,7 +24,6 @@ class ServerPartModel extends EquipmentModel
"amount", "amount",
"cnt", "cnt",
"extra", "extra",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -18,7 +18,6 @@ class MylogModel extends CommonModel
"title", "title",
"content", "content",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -20,7 +20,6 @@ class CPUModel extends PartModel
"used", "used",
"stock", "stock",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -23,7 +23,6 @@ class CSModel extends PartModel
"domain", "domain",
"price", "price",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -21,7 +21,6 @@ class DISKModel extends PartModel
"stock", "stock",
"format", "format",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -22,7 +22,6 @@ class IPModel extends PartModel
"ip", "ip",
"price", "price",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -20,7 +20,6 @@ class RAMModel extends PartModel
"used", "used",
"stock", "stock",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -20,7 +20,6 @@ class SOFTWAREModel extends PartModel
"used", "used",
"stock", "stock",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -21,7 +21,6 @@ class SWITCHModel extends PartModel
"code", "code",
"price", "price",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -22,11 +22,10 @@ class PaymentModel extends CommonModel
"content", "content",
"amount", "amount",
"billing", "billing",
"billing_at",
"billing_month", "billing_month",
"billing_at",
"pay", "pay",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -21,7 +21,6 @@ class UserModel extends CommonModel
"mobile", "mobile",
"role", "role",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -23,7 +23,6 @@ class UserSNSModel extends CommonModel
"email", "email",
"detail", "detail",
"status", "status",
"updated_at"
]; ];
public function __construct() public function __construct()
{ {

View File

@ -6,10 +6,7 @@ use App\DTOs\CommonDTO;
use App\Entities\CommonEntity; use App\Entities\CommonEntity;
use App\Libraries\AuthContext; use App\Libraries\AuthContext;
use App\Models\CommonModel; use App\Models\CommonModel;
use App\Services\Equipment\ServerService;
use App\Services\Part\IPService;
use CodeIgniter\Database\Exceptions\DatabaseException; use CodeIgniter\Database\Exceptions\DatabaseException;
use CodeIgniter\Validation\Exceptions\ValidationException;
use RuntimeException; use RuntimeException;
/** /**
@ -169,7 +166,8 @@ abstract class CommonService
// INSERT 시 Entity의 PK는 0 또는 NULL이어야 함 (DB가 ID를 생성하도록) // INSERT 시 Entity의 PK는 0 또는 NULL이어야 함 (DB가 ID를 생성하도록)
$initialPK = $entity->getPK(); $initialPK = $entity->getPK();
$result = $this->model->save($entity); $result = $this->model->save($entity);
log_message('debug', $this->model->getLastQuery()); log_message('debug', __FUNCTION__ . ":" . var_export($entity, true));
log_message('debug', __FUNCTION__ . ":" . $this->model->getLastQuery());
// 최종적으로 DB에 반영된 PK를 반환받습니다. (UPDATE이면 기존 PK, INSERT이면 새 PK) // 최종적으로 DB에 반영된 PK를 반환받습니다. (UPDATE이면 기존 PK, INSERT이면 새 PK)
$entity->{$this->getPKField()} = $this->handle_save_result($result, $initialPK); $entity->{$this->getPKField()} = $this->handle_save_result($result, $initialPK);
// handle_save_result에서 확인된 최종 PK를 사용하여 DB에서 최신 엔티티를 가져옴 // handle_save_result에서 확인된 최종 PK를 사용하여 DB에서 최신 엔티티를 가져옴
@ -187,11 +185,7 @@ abstract class CommonService
if (!$entity instanceof $entityClass) { if (!$entity instanceof $entityClass) {
throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생:Return Type은 {$entityClass}만 가능"); throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생:Return Type은 {$entityClass}만 가능");
} }
$entity = $this->save_process($entity); return $this->save_process($entity);
//입력/출력데이터 확인용
// log_message('debug', var_export($formDatas, true));
// log_message('debug', var_export($entity->toArray(), true));
return $entity;
} }
final public function create(array $formDatas): object final public function create(array $formDatas): object
{ {
@ -221,27 +215,20 @@ abstract class CommonService
//수정용 //수정용
protected function modify_process($entity, array $formDatas): object protected function modify_process($entity, array $formDatas): object
{ {
foreach ($this->model->getAllowedFields() as $key) {
$formDatas[$key] = $formDatas[$key] ?? $entity->$key;
}
$fields = array_keys($formDatas); $fields = array_keys($formDatas);
$this->getFormService()->setFormFields($fields); $this->getFormService()->setFormFields($fields);
$this->getFormService()->setFormRules('modify', $fields); $this->getFormService()->setFormRules('modify', $fields);
// 데이터 검증 // 데이터 검증
// var_dump($this->getFormService()->getFormRules());
// dd($formDatas);
$this->getFormService()->validate($formDatas); $this->getFormService()->validate($formDatas);
//PK 추가
$pkField = $this->getPKField();
if (!isset($formDatas[$pkField]) && !empty($entity->getPK())) {
// original에 있는 PK 값을 attributes에 명시적으로 복사합니다.
$formDatas[$pkField] = $entity->getPK();
}
foreach ($formDatas as $key => $value) { foreach ($formDatas as $key => $value) {
if ($value !== null) { $entity->$key = $value;
$entity->$key = $value;
}
} }
$entity = $this->save_process($entity); return $this->save_process($entity);
//입력/출력데이터 확인용
// log_message('debug', var_export($formDatas, true));
// log_message('debug', var_export($entity->toArray(), true));
return $entity;
} }
final public function modify(string|int $uid, array $formDatas): object final public function modify(string|int $uid, array $formDatas): object

View File

@ -4,7 +4,6 @@ namespace App\Services\Customer;
use App\DTOs\Customer\ServiceDTO; use App\DTOs\Customer\ServiceDTO;
use App\Entities\Customer\ServiceEntity; use App\Entities\Customer\ServiceEntity;
use App\Entities\Equipment\ServerEntity;
use App\Forms\Customer\ServiceForm; use App\Forms\Customer\ServiceForm;
use App\Helpers\Customer\ServiceHelper; use App\Helpers\Customer\ServiceHelper;
use App\Models\Customer\ServiceModel; use App\Models\Customer\ServiceModel;

View File

@ -305,12 +305,13 @@ class ServerService extends EquipmentService
service('part_switchservice')->detachFromServer($entity); service('part_switchservice')->detachFromServer($entity);
service('equipment_serverpartservice')->detachFromServer($entity); service('equipment_serverpartservice')->detachFromServer($entity);
//서버정보 초기화 //서버정보 초기화
$formDatas['serviceinfo_uid'] = NULL; $formDatas['serviceinfo_uid'] = null;
$formDatas["clientinfo_uid"] = NULL; $formDatas["clientinfo_uid"] = null;
$formDatas["switchinfo_uid"] = NULL; $formDatas["switchinfo_uid"] = null;
$formDatas["ip"] = NULL; $formDatas["ip"] = null;
$formDatas["switchinfo_uid"] = null;
$formDatas['status'] = $formDatas['status'] ?? STATUS['AVAILABLE']; $formDatas['status'] = $formDatas['status'] ?? STATUS['AVAILABLE'];
$entity = parent::modify_process($entity, $formDatas); parent::modify_process($entity, $formDatas);
throw new RuntimeException(var_export($entity, true)); // throw new RuntimeException(var_export($formDatas, true) . var_export($entity, true));
} }
} }

View File

@ -37,8 +37,6 @@ abstract class PartType3Service extends PartType2Service
$formDatas['status'] = STATUS['AVAILABLE']; $formDatas['status'] = STATUS['AVAILABLE'];
//파트정보가져오기 //파트정보가져오기
$entity = $this->getPartEntityByServer($serverEntity); $entity = $this->getPartEntityByServer($serverEntity);
$entity = parent::modify_process($entity, $formDatas); return parent::modify_process($entity, $formDatas);
// dd($entity);
return $entity;
} }
} }