dsparams.inc 23 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031
  1. { TParams }
  2. Function TParams.GetItem(Index: Integer): TParam;
  3. begin
  4. Result:=(Inherited GetItem(Index)) as TParam;
  5. end;
  6. Function TParams.GetParamValue(const ParamName: string): Variant;
  7. begin
  8. Result:=ParamByName(ParamName).Value;
  9. end;
  10. Procedure TParams.SetItem(Index: Integer; Value: TParam);
  11. begin
  12. Inherited SetItem(Index,Value);
  13. end;
  14. Procedure TParams.SetParamValue(const ParamName: string; const Value: Variant);
  15. begin
  16. ParamByName(ParamName).Value:=Value;
  17. end;
  18. Procedure TParams.AssignTo(Dest: TPersistent);
  19. begin
  20. if (Dest is TParams) then
  21. TParams(Dest).Assign(Self)
  22. else
  23. inherited AssignTo(Dest);
  24. end;
  25. Function TParams.GetDataSet: TDataSet;
  26. begin
  27. If (FOwner is TDataset) Then
  28. Result:=TDataset(FOwner)
  29. else
  30. Result:=Nil;
  31. end;
  32. Function TParams.GetOwner: TPersistent;
  33. begin
  34. Result:=FOwner;
  35. end;
  36. constructor TParams.Create(AOwner: TPersistent);
  37. begin
  38. Inherited Create(TParam);
  39. Fowner:=AOwner;
  40. end;
  41. constructor TParams.Create;
  42. begin
  43. Create(TPersistent(Nil));
  44. end;
  45. Procedure TParams.AddParam(Value: TParam);
  46. begin
  47. Value.Collection:=Self;
  48. end;
  49. Procedure TParams.AssignValues(Value: TParams);
  50. Var
  51. I : Integer;
  52. P,PS : TParam;
  53. begin
  54. For I:=0 to Value.Count-1 do
  55. begin
  56. PS:=Value[i];
  57. P:=FindParam(PS.Name);
  58. If Assigned(P) then
  59. P.Assign(PS);
  60. end;
  61. end;
  62. Function TParams.CreateParam(FldType: TFieldType; const ParamName: string;
  63. ParamType: TParamType): TParam;
  64. begin
  65. Result:=Add as TParam;
  66. With Result do
  67. begin
  68. Name:=ParamName;
  69. DataType:=FldType;
  70. ParamType:=ParamType;
  71. end;
  72. end;
  73. Function TParams.FindParam(const Value: string): TParam;
  74. Var
  75. I : Integer;
  76. begin
  77. Result:=Nil;
  78. I:=Count-1;
  79. While (Result=Nil) and (I>=0) do
  80. If (CompareText(Value,Items[i].Name)=0) then
  81. Result:=Items[i]
  82. else
  83. Dec(i);
  84. end;
  85. Procedure TParams.GetParamList(List: TList; const ParamNames: string);
  86. Function NextName(Var S : String) : String;
  87. Var
  88. P : Integer;
  89. begin
  90. P:=Pos(';',S);
  91. If (P=0) then
  92. P:=Length(S)+1;
  93. Result:=Copy(S,1,P-1);
  94. system.Delete(S,1,P);
  95. end;
  96. Var
  97. L,N : String;
  98. begin
  99. L:=ParamNames;
  100. While (Length(L)>0) do
  101. begin
  102. N:=NextName(L);
  103. List.Add(ParamByName(N));
  104. end;
  105. end;
  106. Function TParams.IsEqual(Value: TParams): Boolean;
  107. Var
  108. I : Integer;
  109. begin
  110. Result:=(Value.Count=Count);
  111. I:=Count-1;
  112. While Result and (I>=0) do
  113. begin
  114. Result:=Items[I].IsEqual(Value[i]);
  115. Dec(I);
  116. end;
  117. end;
  118. Function TParams.ParamByName(const Value: string): TParam;
  119. begin
  120. Result:=FindParam(Value);
  121. If (Result=Nil) then
  122. DatabaseErrorFmt(SParameterNotFound,[Value],Dataset);
  123. end;
  124. Function TParams.ParseSQL(SQL: String; DoCreate: Boolean): String;
  125. var pb : TParamBinding;
  126. rs : string;
  127. begin
  128. Result := ParseSQL(SQL,DoCreate,psInterbase, pb, rs);
  129. end;
  130. Function TParams.ParseSQL(SQL: String; DoCreate: Boolean; ParameterStyle : TParamStyle): String;
  131. var pb : TParamBinding;
  132. rs : string;
  133. begin
  134. Result := ParseSQL(SQL,DoCreate,ParameterStyle,pb, rs);
  135. end;
  136. Function TParams.ParseSQL(SQL: String; DoCreate: Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding): String;
  137. var rs : string;
  138. begin
  139. Result := ParseSQL(SQL,DoCreate,ParameterStyle,ParamBinding, rs);
  140. end;
  141. function SkipComments(var p: PChar; EscapeSlash, EscapeRepeat : Boolean) : Boolean;
  142. var notRepeatEscaped : boolean;
  143. procedure SkipQuotesString(QuoteChar : char);
  144. begin
  145. Inc(p);
  146. Result := True;
  147. repeat
  148. notRepeatEscaped := True;
  149. while not (p^ in [#0, QuoteChar]) do
  150. begin
  151. if EscapeSlash and (p^='\') then Inc(p,2) // make sure we handle \' and \\ correct
  152. else Inc(p);
  153. end;
  154. if p^=QuoteChar then
  155. begin
  156. Inc(p); // skip final '
  157. if (p^=QuoteChar) and EscapeRepeat then // Handle escaping by ''
  158. begin
  159. notRepeatEscaped := False;
  160. inc(p);
  161. end
  162. end;
  163. until notRepeatEscaped;
  164. end;
  165. begin
  166. result := false;
  167. case p^ of
  168. '''': SkipQuotesString(''''); // single quote delimited string
  169. '"': SkipQuotesString('"'); // double quote delimited string
  170. '-': // possible start of -- comment
  171. begin
  172. Inc(p);
  173. if p^='-' then // -- comment
  174. begin
  175. Result := True;
  176. repeat // skip until at end of line
  177. Inc(p);
  178. until p^ in [#10, #0];
  179. end
  180. end;
  181. '/': // possible start of /* */ comment
  182. begin
  183. Inc(p);
  184. if p^='*' then // /* */ comment
  185. begin
  186. Result := True;
  187. repeat
  188. Inc(p);
  189. if p^='*' then // possible end of comment
  190. begin
  191. Inc(p);
  192. if p^='/' then Break; // end of comment
  193. end;
  194. until p^=#0;
  195. if p^='/' then Inc(p); // skip final /
  196. end;
  197. end;
  198. end; {case}
  199. end;
  200. Function TParams.ParseSQL(SQL: String; DoCreate: Boolean; ParameterStyle : TParamStyle; var ParamBinding: TParambinding; var ReplaceString : string): String;
  201. type
  202. // used for ParamPart
  203. TStringPart = record
  204. Start,Stop:integer;
  205. end;
  206. const
  207. ParamAllocStepSize = 8;
  208. var
  209. IgnorePart:boolean;
  210. p,ParamNameStart,BufStart:PChar;
  211. ParamName:string;
  212. QuestionMarkParamCount,ParameterIndex,NewLength:integer;
  213. ParamCount:integer; // actual number of parameters encountered so far;
  214. // always <= Length(ParamPart) = Length(Parambinding)
  215. // Parambinding will have length ParamCount in the end
  216. ParamPart:array of TStringPart; // describe which parts of buf are parameters
  217. NewQueryLength:integer;
  218. NewQuery:string;
  219. NewQueryIndex,BufIndex,CopyLen,i:integer; // Parambinding will have length ParamCount in the end
  220. b:integer;
  221. tmpParam:TParam;
  222. begin
  223. if DoCreate then Clear;
  224. // Parse the SQL and build ParamBinding
  225. ParamCount:=0;
  226. NewQueryLength:=Length(SQL);
  227. SetLength(ParamPart,ParamAllocStepSize);
  228. SetLength(Parambinding,ParamAllocStepSize);
  229. QuestionMarkParamCount:=0; // number of ? params found in query so far
  230. ReplaceString := '$';
  231. if ParameterStyle = psSimulated then
  232. while pos(ReplaceString,SQL) > 0 do ReplaceString := ReplaceString+'$';
  233. p:=PChar(SQL);
  234. BufStart:=p; // used to calculate ParamPart.Start values
  235. repeat
  236. SkipComments(p,ParameterStyle<>psPostgreSQL,ParameterStyle=psPostgreSQL);
  237. case p^ of
  238. ':','?': // parameter
  239. begin
  240. IgnorePart := False;
  241. if p^=':' then
  242. begin // find parameter name
  243. Inc(p);
  244. if p^=':' then // ignore ::, since some databases uses this as a cast (wb 4813)
  245. begin
  246. IgnorePart := True;
  247. Inc(p);
  248. end
  249. else
  250. begin
  251. ParamNameStart:=p;
  252. while not (p^ in (SQLDelimiterCharacters+[#0])) do
  253. Inc(p);
  254. ParamName:=Copy(ParamNameStart,1,p-ParamNameStart);
  255. end;
  256. end
  257. else
  258. begin
  259. Inc(p);
  260. ParamNameStart:=p;
  261. ParamName:='';
  262. end;
  263. if not IgnorePart then
  264. begin
  265. Inc(ParamCount);
  266. if ParamCount>Length(ParamPart) then
  267. begin
  268. NewLength:=Length(ParamPart)+ParamAllocStepSize;
  269. SetLength(ParamPart,NewLength);
  270. SetLength(ParamBinding,NewLength);
  271. end;
  272. if DoCreate then
  273. begin
  274. // Check if this is the first occurance of the parameter
  275. tmpParam := FindParam(ParamName);
  276. // If so, create the parameter and assign the Parameterindex
  277. if not assigned(tmpParam) then
  278. ParameterIndex := CreateParam(ftUnknown, ParamName, ptInput).Index
  279. else // else only assign the ParameterIndex
  280. ParameterIndex := tmpParam.Index;
  281. end
  282. // else find ParameterIndex
  283. else
  284. begin
  285. if ParamName<>'' then
  286. ParameterIndex:=ParamByName(ParamName).Index
  287. else
  288. begin
  289. ParameterIndex:=QuestionMarkParamCount;
  290. Inc(QuestionMarkParamCount);
  291. end;
  292. end;
  293. if ParameterStyle in [psPostgreSQL,psSimulated] then
  294. begin
  295. if ParameterIndex > 8 then
  296. inc(NewQueryLength,2)
  297. else
  298. inc(NewQueryLength,1)
  299. end;
  300. // store ParameterIndex in FParamIndex, ParamPart data
  301. ParamBinding[ParamCount-1]:=ParameterIndex;
  302. ParamPart[ParamCount-1].Start:=ParamNameStart-BufStart;
  303. ParamPart[ParamCount-1].Stop:=p-BufStart+1;
  304. // update NewQueryLength
  305. Dec(NewQueryLength,p-ParamNameStart);
  306. end;
  307. end;
  308. #0:Break;
  309. else
  310. Inc(p);
  311. end;
  312. until false;
  313. SetLength(ParamPart,ParamCount);
  314. SetLength(ParamBinding,ParamCount);
  315. if ParamCount>0 then
  316. begin
  317. // replace :ParamName by ? for interbase and by $x for postgresql/psSimulated
  318. // (using ParamPart array and NewQueryLength)
  319. if (ParameterStyle = psSimulated) and (length(ReplaceString) > 1) then
  320. inc(NewQueryLength,(paramcount)*(length(ReplaceString)-1));
  321. SetLength(NewQuery,NewQueryLength);
  322. NewQueryIndex:=1;
  323. BufIndex:=1;
  324. for i:=0 to High(ParamPart) do
  325. begin
  326. CopyLen:=ParamPart[i].Start-BufIndex;
  327. Move(SQL[BufIndex],NewQuery[NewQueryIndex],CopyLen);
  328. Inc(NewQueryIndex,CopyLen);
  329. case ParameterStyle of
  330. psInterbase : NewQuery[NewQueryIndex]:='?';
  331. psPostgreSQL,
  332. psSimulated : begin
  333. ParamName := IntToStr(ParamBinding[i]+1);
  334. for b := 1 to length(ReplaceString) do
  335. begin
  336. NewQuery[NewQueryIndex]:='$';
  337. Inc(NewQueryIndex);
  338. end;
  339. NewQuery[NewQueryIndex]:= paramname[1];
  340. if length(paramname)>1 then
  341. begin
  342. Inc(NewQueryIndex);
  343. NewQuery[NewQueryIndex]:= paramname[2]
  344. end;
  345. end;
  346. end;
  347. Inc(NewQueryIndex);
  348. BufIndex:=ParamPart[i].Stop;
  349. end;
  350. CopyLen:=Length(SQL)+1-BufIndex;
  351. Move(SQL[BufIndex],NewQuery[NewQueryIndex],CopyLen);
  352. end
  353. else
  354. NewQuery:=SQL;
  355. Result := NewQuery;
  356. end;
  357. Procedure TParams.RemoveParam(Value: TParam);
  358. begin
  359. Value.Collection:=Nil;
  360. end;
  361. { TParam }
  362. Function TParam.GetDataSet: TDataSet;
  363. begin
  364. If Assigned(Collection) and (Collection is TParams) then
  365. Result:=TParams(Collection).GetDataset
  366. else
  367. Result:=Nil;
  368. end;
  369. Function TParam.IsParamStored: Boolean;
  370. begin
  371. Result:=Bound;
  372. end;
  373. Procedure TParam.AssignParam(Param: TParam);
  374. begin
  375. if Not Assigned(Param) then
  376. begin
  377. Clear;
  378. FDataType:=ftunknown;
  379. FParamType:=ptUnknown;
  380. Name:='';
  381. Size:=0;
  382. Precision:=0;
  383. NumericScale:=0;
  384. end
  385. else
  386. begin
  387. FDataType:=Param.DataType;
  388. if Param.IsNull then
  389. Clear
  390. else
  391. FValue:=Param.FValue;
  392. FBound:=Param.Bound;
  393. Name:=Param.Name;
  394. if (ParamType=ptUnknown) then
  395. ParamType:=Param.ParamType;
  396. Size:=Param.Size;
  397. Precision:=Param.Precision;
  398. NumericScale:=Param.NumericScale;
  399. end;
  400. end;
  401. Procedure TParam.AssignTo(Dest: TPersistent);
  402. begin
  403. if (Dest is TField) then
  404. AssignToField(TField(Dest))
  405. else
  406. inherited AssignTo(Dest);
  407. end;
  408. Function TParam.GetAsBoolean: Boolean;
  409. begin
  410. If IsNull then
  411. Result:=False
  412. else
  413. Result:=FValue;
  414. end;
  415. Function TParam.GetAsCurrency: Currency;
  416. begin
  417. If IsNull then
  418. Result:=0.0
  419. else
  420. Result:=FValue;
  421. end;
  422. Function TParam.GetAsDateTime: TDateTime;
  423. begin
  424. If IsNull then
  425. Result:=0.0
  426. else
  427. Result:=FValue;
  428. end;
  429. Function TParam.GetAsFloat: Double;
  430. begin
  431. If IsNull then
  432. Result:=0.0
  433. else
  434. Result:=FValue;
  435. end;
  436. Function TParam.GetAsInteger: Longint;
  437. begin
  438. If IsNull then
  439. Result:=0
  440. else
  441. Result:=FValue;
  442. end;
  443. Function TParam.GetAsLargeInt: LargeInt;
  444. begin
  445. If IsNull then
  446. Result:=0
  447. else
  448. Result:=FValue;
  449. end;
  450. Function TParam.GetAsMemo: string;
  451. begin
  452. If IsNull then
  453. Result:=''
  454. else
  455. Result:=FValue;
  456. end;
  457. Function TParam.GetAsString: string;
  458. begin
  459. If IsNull then
  460. Result:=''
  461. else
  462. Result:=FValue;
  463. end;
  464. Function TParam.GetAsVariant: Variant;
  465. begin
  466. if IsNull then
  467. Result:=Null
  468. else
  469. Result:=FValue;
  470. end;
  471. Function TParam.GetDisplayName: string;
  472. begin
  473. if (FName<>'') then
  474. Result:=FName
  475. else
  476. Result:=inherited GetDisplayName
  477. end;
  478. Function TParam.GetIsNull: Boolean;
  479. begin
  480. Result:= VarIsNull(FValue) or VarIsClear(FValue);
  481. end;
  482. Function TParam.IsEqual(AValue: TParam): Boolean;
  483. begin
  484. Result:=(Name=AValue.Name)
  485. and (IsNull=AValue.IsNull)
  486. and (Bound=AValue.Bound)
  487. and (DataType=AValue.DataType)
  488. and (ParamType=AValue.ParamType)
  489. and (VarType(FValue)=VarType(AValue.FValue))
  490. and (FValue=AValue.FValue);
  491. end;
  492. Procedure TParam.SetAsBlob(const AValue: TBlobData);
  493. begin
  494. FValue:=AValue;
  495. FDataType:=ftBlob;
  496. end;
  497. Procedure TParam.SetAsBoolean(AValue: Boolean);
  498. begin
  499. FValue:=AValue;
  500. FDataType:=ftBoolean;
  501. end;
  502. Procedure TParam.SetAsCurrency(const AValue: Currency);
  503. begin
  504. FValue:=Avalue;
  505. FDataType:=ftCurrency;
  506. end;
  507. Procedure TParam.SetAsDate(const AValue: TDateTime);
  508. begin
  509. FValue:=Avalue;
  510. FDataType:=ftDate;
  511. end;
  512. Procedure TParam.SetAsDateTime(const AValue: TDateTime);
  513. begin
  514. FValue:=AValue;
  515. FDataType:=ftDateTime;
  516. end;
  517. Procedure TParam.SetAsFloat(const AValue: Double);
  518. begin
  519. FValue:=AValue;
  520. FDataType:=ftFloat;
  521. end;
  522. Procedure TParam.SetAsInteger(AValue: Longint);
  523. begin
  524. FValue:=AValue;
  525. FDataType:=ftInteger;
  526. end;
  527. Procedure TParam.SetAsLargeInt(AValue: LargeInt);
  528. begin
  529. FValue:=AValue;
  530. FDataType:=ftLargeint;
  531. end;
  532. Procedure TParam.SetAsMemo(const AValue: string);
  533. begin
  534. FValue:=AValue;
  535. FDataType:=ftMemo;
  536. end;
  537. Procedure TParam.SetAsSmallInt(AValue: LongInt);
  538. begin
  539. FValue:=AValue;
  540. FDataType:=ftSmallInt;
  541. end;
  542. Procedure TParam.SetAsString(const AValue: string);
  543. begin
  544. FValue:=AValue;
  545. FDataType:=ftString;
  546. end;
  547. Procedure TParam.SetAsTime(const AValue: TDateTime);
  548. begin
  549. FValue:=AValue;
  550. FDataType:=ftTime;
  551. end;
  552. Procedure TParam.SetAsVariant(const AValue: Variant);
  553. begin
  554. FValue:=AValue;
  555. FBound:=not VarIsClear(Value);
  556. if FDataType = ftUnknown then
  557. case VarType(Value) of
  558. varBoolean : FDataType:=ftBoolean;
  559. varSmallint,
  560. varShortInt,
  561. varByte : FDataType:=ftSmallInt;
  562. varWord,
  563. varInteger : FDataType:=ftInteger;
  564. varCurrency : FDataType:=ftCurrency;
  565. varLongWord,
  566. varSingle,
  567. varDouble : FDataType:=ftFloat;
  568. varDate : FDataType:=ftDateTime;
  569. varString,
  570. varOleStr : if (FDataType<>ftFixedChar) then
  571. FDataType:=ftString;
  572. varInt64 : FDataType:=ftLargeInt;
  573. else
  574. FDataType:=ftUnknown;
  575. end;
  576. end;
  577. Procedure TParam.SetAsWord(AValue: LongInt);
  578. begin
  579. FValue:=AValue;
  580. FDataType:=ftWord;
  581. end;
  582. Procedure TParam.SetDataType(AValue: TFieldType);
  583. Var
  584. VT : Integer;
  585. begin
  586. FDataType:=AValue;
  587. VT:=FieldTypetoVariantMap[AValue];
  588. If (VT=varError) then
  589. clear
  590. else
  591. if not VarIsEmpty(FValue) then
  592. begin
  593. Try
  594. FValue:=VarAsType(FValue,VT)
  595. except
  596. Clear;
  597. end { try }
  598. end;
  599. end;
  600. Procedure TParam.SetText(const AValue: string);
  601. begin
  602. Value:=AValue;
  603. end;
  604. constructor TParam.Create(ACollection: TCollection);
  605. begin
  606. inherited Create(ACollection);
  607. ParamType:=ptUnknown;
  608. DataType:=ftUnknown;
  609. FValue:=Unassigned;
  610. end;
  611. constructor TParam.Create(AParams: TParams; AParamType: TParamType);
  612. begin
  613. Create(AParams);
  614. ParamType:=AParamType;
  615. end;
  616. Procedure TParam.Assign(Source: TPersistent);
  617. begin
  618. if (Source is TParam) then
  619. AssignParam(TParam(Source))
  620. else if (Source is TField) then
  621. AssignField(TField(Source))
  622. else if (source is TStrings) then
  623. AsMemo:=TStrings(Source).Text
  624. else
  625. inherited Assign(Source);
  626. end;
  627. Procedure TParam.AssignField(Field: TField);
  628. begin
  629. if Assigned(Field) then
  630. begin
  631. // Need TField.Value
  632. AssignFieldValue(Field,Field.Value);
  633. Name:=Field.FieldName;
  634. end
  635. else
  636. begin
  637. Clear;
  638. Name:='';
  639. end
  640. end;
  641. procedure TParam.AssignToField(Field : TField);
  642. begin
  643. if Assigned(Field) then
  644. case FDataType of
  645. ftUnknown : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet);
  646. // Need TField.AsSmallInt
  647. ftSmallint : Field.AsInteger:=AsSmallInt;
  648. // Need TField.AsWord
  649. ftWord : Field.AsInteger:=AsWord;
  650. ftInteger,
  651. ftAutoInc : Field.AsInteger:=AsInteger;
  652. // Need TField.AsCurrency
  653. ftCurrency : Field.asFloat:=AsCurrency;
  654. ftFloat : Field.asFloat:=AsFloat;
  655. ftBoolean : Field.AsBoolean:=AsBoolean;
  656. ftBlob,
  657. ftGraphic..ftTypedBinary,
  658. ftOraBlob,
  659. ftOraClob,
  660. ftString,
  661. ftMemo,
  662. ftAdt,
  663. ftFixedChar: Field.AsString:=AsString;
  664. ftTime,
  665. ftDate,
  666. ftDateTime : Field.AsDateTime:=AsDateTime;
  667. ftBytes,
  668. ftVarBytes : ; // Todo.
  669. else
  670. If not (DataType in [ftCursor, ftArray, ftDataset,ftReference]) then
  671. DatabaseErrorFmt(SBadParamFieldType, [Name], DataSet);
  672. end;
  673. end;
  674. procedure TParam.AssignFromField(Field : TField);
  675. begin
  676. if Assigned(Field) then
  677. begin
  678. FDataType:=Field.DataType;
  679. case Field.DataType of
  680. ftUnknown : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet);
  681. // Need TField.AsSmallInt
  682. ftSmallint : AsSmallint:=Field.AsInteger;
  683. // Need TField.AsWord
  684. ftWord : AsWord:=Field.AsInteger;
  685. ftInteger,
  686. ftAutoInc : AsInteger:=Field.AsInteger;
  687. // Need TField.AsCurrency
  688. ftCurrency : AsCurrency:=Field.asCurrency;
  689. ftFloat : AsFloat:=Field.asFloat;
  690. ftBoolean : AsBoolean:=Field.AsBoolean;
  691. ftBlob,
  692. ftGraphic..ftTypedBinary,
  693. ftOraBlob,
  694. ftOraClob,
  695. ftString,
  696. ftMemo,
  697. ftAdt,
  698. ftFixedChar: AsString:=Field.AsString;
  699. ftTime,
  700. ftDate,
  701. ftDateTime : AsDateTime:=Field.AsDateTime;
  702. ftBytes,
  703. ftVarBytes : ; // Todo.
  704. else
  705. If not (DataType in [ftCursor, ftArray, ftDataset,ftReference]) then
  706. DatabaseErrorFmt(SBadParamFieldType, [Name], DataSet);
  707. end;
  708. end;
  709. end;
  710. Procedure TParam.AssignFieldValue(Field: TField; const AValue: Variant);
  711. begin
  712. If Assigned(Field) then
  713. begin
  714. if (Field.DataType = ftString) and TStringField(Field).FixedChar then
  715. DataType:=ftFixedChar
  716. else if (Field.DataType = ftMemo) and (Field.Size > 255) then
  717. DataType:=ftString
  718. else
  719. DataType:=Field.DataType;
  720. if VarIsNull(AValue) then
  721. Clear
  722. else
  723. Value:=AValue;
  724. Size:=Field.DataSize;
  725. FBound:=True;
  726. end;
  727. end;
  728. Procedure TParam.Clear;
  729. begin
  730. FValue:=UnAssigned;
  731. end;
  732. Procedure TParam.GetData(Buffer: Pointer);
  733. Var
  734. P : Pointer;
  735. S : String;
  736. begin
  737. case FDataType of
  738. ftUnknown : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet);
  739. ftSmallint : PSmallint(Buffer)^:=AsSmallInt;
  740. ftWord : PWord(Buffer)^:=AsWord;
  741. ftInteger,
  742. ftAutoInc : PInteger(Buffer)^:=AsInteger;
  743. ftCurrency : PDouble(Buffer)^:=AsCurrency;
  744. ftFloat : PDouble(Buffer)^:=AsFloat;
  745. ftBoolean : PWordBool(Buffer)^:=AsBoolean;
  746. ftString,
  747. ftMemo,
  748. ftAdt,
  749. ftFixedChar:
  750. begin
  751. S:=AsString;
  752. StrMove(PChar(Buffer),Pchar(S),Length(S)+1);
  753. end;
  754. ftTime : PInteger(Buffer)^:=DateTimeToTimeStamp(AsTime).Time;
  755. ftDate : PInteger(Buffer)^:=DateTimeToTimeStamp(AsTime).Date;
  756. ftDateTime : PDouble(Buffer)^:=TimeStampToMSecs(DateTimeToTimeStamp(AsDateTime));
  757. ftBlob,
  758. ftGraphic..ftTypedBinary,
  759. ftOraBlob,
  760. ftOraClob :
  761. begin
  762. S:=GetAsString;
  763. Move(PChar(S)^, Buffer^, Length(S));
  764. end;
  765. ftBytes, ftVarBytes:
  766. begin
  767. if VarIsArray(FValue) then
  768. begin
  769. P:=VarArrayLock(FValue);
  770. try
  771. Move(P^, Buffer^, VarArrayHighBound(FValue, 1) + 1);
  772. finally
  773. VarArrayUnlock(FValue);
  774. end;
  775. end;
  776. end;
  777. else
  778. If not (DataType in [ftCursor, ftArray, ftDataset,ftReference]) then
  779. DatabaseErrorFmt(SBadParamFieldType, [Name], DataSet);
  780. end;
  781. end;
  782. Function TParam.GetDataSize: Integer;
  783. begin
  784. Result:=0;
  785. case DataType of
  786. ftUnknown : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet);
  787. ftBoolean : Result:=SizeOf(WordBool);
  788. ftInteger,
  789. ftAutoInc : Result:=SizeOf(Integer);
  790. ftSmallint : Result:=SizeOf(SmallInt);
  791. ftWord : Result:=SizeOf(Word);
  792. ftTime,
  793. ftDate : Result:=SizeOf(Integer);
  794. ftDateTime,
  795. ftCurrency,
  796. ftFloat : Result:=SizeOf(Double);
  797. ftString,
  798. ftFixedChar,
  799. ftMemo,
  800. ftADT : Result:=Length(AsString)+1;
  801. ftBytes,
  802. ftVarBytes : if VarIsArray(FValue) then
  803. Result:=VarArrayHighBound(FValue,1)+1
  804. else
  805. Result:=0;
  806. ftBlob,
  807. ftGraphic..ftTypedBinary,
  808. ftOraClob,
  809. ftOraBlob : Result:=Length(AsString);
  810. ftArray,
  811. ftDataSet,
  812. ftReference,
  813. ftCursor : Result:=0;
  814. else
  815. DatabaseErrorFmt(SBadParamFieldType,[Name],DataSet);
  816. end;
  817. end;
  818. Procedure TParam.LoadFromFile(const FileName: string; BlobType: TBlobType);
  819. Var
  820. S : TFileStream;
  821. begin
  822. S:=TFileStream.Create(FileName,fmOpenRead);
  823. Try
  824. LoadFromStream(S,BlobType);
  825. Finally
  826. FreeAndNil(S);
  827. end;
  828. end;
  829. Procedure TParam.LoadFromStream(Stream: TStream; BlobType: TBlobType);
  830. Var
  831. Temp : String;
  832. begin
  833. FDataType:=BlobType;
  834. With Stream do
  835. begin
  836. Position:=0;
  837. SetLength(Temp,Size);
  838. ReadBuffer(Pointer(Temp)^,Size);
  839. FValue:=Temp;
  840. end;
  841. end;
  842. Procedure TParam.SetBlobData(Buffer: Pointer; ASize: Integer);
  843. Var
  844. Temp : String;
  845. begin
  846. SetLength(Temp,ASize);
  847. Move(Buffer^,Temp,ASize);
  848. AsBlob:=Temp;
  849. end;
  850. Procedure TParam.SetData(Buffer: Pointer);
  851. Function FromTimeStamp(T,D : Integer) : TDateTime;
  852. Var TS : TTimeStamp;
  853. begin
  854. TS.Time:=T;
  855. TS.Date:=D;
  856. Result:=TimeStampToDateTime(TS);
  857. end;
  858. begin
  859. case FDataType of
  860. ftUnknown : DatabaseErrorFmt(SUnknownParamFieldType,[Name],DataSet);
  861. ftSmallint : AsSmallInt:=PSmallint(Buffer)^;
  862. ftWord : AsWord:=PWord(Buffer)^;
  863. ftInteger,
  864. ftAutoInc : AsInteger:=PInteger(Buffer)^;
  865. ftCurrency : AsCurrency:= PDouble(Buffer)^;
  866. ftFloat : AsFloat:=PDouble(Buffer)^;
  867. ftBoolean : AsBoolean:=PWordBool(Buffer)^;
  868. ftString,
  869. ftFixedChar: AsString:=StrPas(Buffer);
  870. ftMemo : AsMemo:=StrPas(Buffer);
  871. ftTime : AsTime:=FromTimeStamp(PInteger(Buffer)^,DateDelta);
  872. ftDate : Asdate:=FromTimeStamp(0,PInteger(Buffer)^);
  873. ftDateTime : AsDateTime:=TimeStampToDateTime(MSecsToTimeStamp(trunc(PDouble(Buffer)^)));
  874. ftCursor : FValue:=0;
  875. ftBlob,
  876. ftGraphic..ftTypedBinary,
  877. ftOraBlob,
  878. ftOraClob : SetBlobData(Buffer, StrLen(PChar(Buffer)));
  879. else
  880. DatabaseErrorFmt(SBadParamFieldType,[Name],DataSet);
  881. end;
  882. end;
  883. Procedure TParams.CopyParamValuesFromDataset(ADataset : TDataset; CopyBound : Boolean);
  884. Var
  885. I : Integer;
  886. P : TParam;
  887. F : TField;
  888. begin
  889. If (ADataSet<>Nil) then
  890. For I:=0 to Count-1 do
  891. begin
  892. P:=Items[i];
  893. if CopyBound or (not P.Bound) then
  894. begin
  895. F:=ADataset.FieldByName(P.Name);
  896. P.AssignField(F);
  897. If Not CopyBound then
  898. P.Bound:=False;
  899. end;
  900. end;
  901. end;