4. 업무용 클라이언트 만들기
4-1. DML 생성 함수
각 폼마다 일일이 모든 코드를 새로 작성해도 되지만 공용으로 사용되는 코드들을 모아서 부모폼을 만들고 상속받아서 사용하면 코딩해아할 양을 많이 줄일 수 있다.
TBufDataset의 경우 따로 SQL을 넣어둘 속성이 없기때문에 일일이 조회용과 데이터 처리용 SQL을 만들어줘야한다. 본 예제에서는 간단하게 TField의 ProviderFlags를 활용해서 자동으로 데이터 처리용 SQL 구문을 생성한다. 일종의 편법이라고 볼 수도 있겠지만 어렵고 복잡하게 만드는걸 별로 좋아하지 않아서...^^
규칙은 간단하다. ProviderFlags의 pfInWhere가 설정되어있으면 등록가능한 필드, pfInUpdate가 설정되어있으면 수정가능한 필드, 그리고 pfInKey가 설정되어있으면 수정이나 삭제시 사용되는 WHERE 조건의 키값이 되는 것이다.
상속용 부모폼에서 사용할 수 있게 DataModule에 DML 생성 함수 추가한다. 그리고 메인화면의 버튼과 각 폼을 생성할 때 권한 처리용 변수도 DataModule에 추가한다.
TdmSIMLaz = class(TDataModule)
:
:
public
:
:
u_auth_n, // 등록권한
u_auth_m, // 수정권한
u_auth_d, // 삭제권한
u_auth_p, // 인쇄권한
u_auth_a, // 전체권한
u_btn_v, // 조회버튼
u_btn_n, // 등록버튼
u_btn_d, // 삭제버튼
u_btn_s: Boolean; // 저장버튼
function UF_SIMLazDML(ADataSet: TCustomBufDataset; AName: string; AType: TUpdateKind): string;
:
:
// DML 생성
function TdmSIMLaz.UF_SIMLazDML(ADataSet: TCustomBufDataset; AName: string; AType: TUpdateKind): string;
function LF_Value(AField: TField; AIsOld: Boolean = False): string;
begin
if AField.IsNull then Result := 'NULL'
else
begin
case AField.DataType of
ftDate:
if AIsOld then Result := QuotedStr(FormatDateTime('yyyy-mm-dd', AField.OldValue))
else Result := QuotedStr(FormatDateTime('yyyy-mm-dd', AField.AsDateTime));
ftTime:
if AIsOld then Result := QuotedStr(FormatDateTime('hh:nn:ss', AField.OldValue))
else Result := QuotedStr(FormatDateTime('hh:nn:ss', AField.AsDateTime));
ftDateTime, ftTimeStamp: //, ftOraTimeStamp
if AIsOld then Result := QuotedStr(FormatDateTime('yyyy-mm-dd hh:nn:ss', AField.OldValue))
else Result := QuotedStr(FormatDateTime('yyyy-mm-dd hh:nn:ss', AField.AsDateTime));
ftSmallint, ftInteger, ftLargeInt:
if AIsOld then Result := IntToStr(AField.OldValue)
else Result := IntToStr(AField.Value);
ftFloat, ftCurrency, ftBCD:
if AIsOld then Result := FloatToStr(AField.OldValue)
else Result := FloatToStr(AField.Value);
else
if AIsOld then Result := QuotedStr(AField.OldValue)
else Result := QuotedStr(AField.AsString);
end;
end;
end;
var
i: Int32;
l_ValueFlag, l_KeyFlag: Boolean;
l_Values, l_Keys, t, l_Fields, l_FieldName: string;
begin
Result := '';
if AName = '' then Exit;
l_Keys := '';
l_Fields := '';
l_Values := '';
l_KeyFlag := False;
l_ValueFlag := False;
with ADataSet do
begin
for i := 0 to Fields.Count - 1 do
begin
l_FieldName := LowerCase(Fields[i].FieldName);
if (pfInWhere in Fields[i].ProviderFlags) and (AType = ukInsert) then
begin
if l_ValueFlag then t := ',' else t := ' ';
l_Fields := l_Fields + t + l_FieldName;
l_Values := l_Values + t + LF_Value(Fields[i]);
l_ValueFlag := True;
end
else if (pfInUpdate in Fields[i].ProviderFlags) and (AType = ukModify) then
begin
if Fields[i].OldValue <> Fields[i].Value then
begin
if l_ValueFlag then t := ',' else t := ' ';
l_Values := l_Values + t + l_FieldName + ' = ' + LF_Value(Fields[i]);
l_ValueFlag := True;
end;
end;
if (pfInKey in Fields[i].ProviderFlags) and (AType in [ukDelete, ukModify]) then
begin
if l_KeyFlag then t := ' AND ' else t := ' ';
l_Keys := l_Keys + t + l_FieldName + ' = ' + LF_Value(Fields[i], True);
l_KeyFlag := True;
end;
end;
end;
case AType of
ukInsert: Result := 'INSERT INTO ' + AName + ' (' + l_Fields + ' ) VALUES (' + l_Values + ' )';
ukDelete: Result := 'DELETE FROM ' + AName + ' WHERE' + l_Keys;
ukModify: if l_Values <> '' then Result := 'UPDATE ' + AName + ' SET' + l_Values + ' WHERE' + l_Keys;
end;
end;