fields.inc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Michael Van Canneyt, member of the
  5. Free Pascal development team
  6. TFields and related components implementations.
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. PRocedure DumpMem (P : Pointer;Size : Longint);
  14. Type PByte = ^Byte;
  15. Var i : longint;
  16. begin
  17. Write ('Memory dump : ');
  18. For I:=0 to Size-1 do
  19. Write (Pbyte(P)[i],' ');
  20. Writeln;
  21. end;
  22. { ---------------------------------------------------------------------
  23. TFieldDef
  24. ---------------------------------------------------------------------}
  25. Constructor TFieldDef.Create(AOwner: TFieldDefs; const AName: string;
  26. ADataType: TFieldType; ASize: Word; ARequired: Boolean; AFieldNo: Longint);
  27. begin
  28. Inherited Create(AOwner);
  29. FName:=Aname;
  30. FDatatype:=ADatatype;
  31. FSize:=ASize;
  32. FRequired:=ARequired;
  33. FPrecision:=-1;
  34. // Correct sizes.
  35. If FDataType=ftFloat then
  36. begin
  37. If Not (FSize in [4,8,10]) then FSize:=10
  38. end
  39. else If FDataType in [ftWord,ftsmallint,ftinteger] Then
  40. If Not (FSize in [1,2,4]) then FSize:=4;
  41. FFieldNo:=AFieldNo;
  42. AOwner.FItems.Add(Self);
  43. end;
  44. Destructor TFieldDef.Destroy;
  45. Var I : longint;
  46. begin
  47. Inherited destroy;
  48. end;
  49. Function TFieldDef.CreateField(AOwner: TComponent): TField;
  50. Var TheField : TFieldClass;
  51. begin
  52. Writeln ('Creating field');
  53. TheField:=GetFieldClass;
  54. if TheField=Nil then
  55. DatabaseErrorFmt(SUnknownFieldType,[FName]);
  56. Result:=Thefield.Create(AOwner);
  57. Try
  58. Result.Size:=FSize;
  59. Result.Required:=FRequired;
  60. Result.FieldName:=FName;
  61. Result.SetFieldType(DataType);
  62. Writeln ('Trying to set dataset');
  63. Result.Dataset:=TFieldDefs(Owner).FDataset;
  64. If Result is TFloatField then
  65. TFloatField(Result).Precision:=FPrecision;
  66. except
  67. Result.Free;
  68. Raise;
  69. end;
  70. end;
  71. Function TFieldDef.GetFieldClass : TFieldClass;
  72. begin
  73. //!! Should be owner as tdataset but that doesn't work ??
  74. If Assigned(Owner) then
  75. Result:=TFieldDefs(Owner).FDataSet.GetFieldClass(FDataType)
  76. else
  77. Result:=Nil;
  78. end;
  79. { ---------------------------------------------------------------------
  80. TFieldDefs
  81. ---------------------------------------------------------------------}
  82. destructor TFieldDefs.Destroy;
  83. begin
  84. FItems.Free;
  85. // This will destroy all fielddefs since we own them...
  86. Inherited Destroy;
  87. end;
  88. procedure TFieldDefs.Add(const AName: string; ADataType: TFieldType; ASize: Word;
  89. ARequired: Boolean);
  90. begin
  91. Writeln ('Adding fielddef');
  92. If Length(Name)=0 Then
  93. DatabaseError(SNeedFieldName);
  94. // the fielddef will register itself here as a owned component.
  95. // fieldno is 1 based !
  96. FItems.Add(TFieldDef.Create(Self,AName,ADataType,ASize,Arequired,FItems.Count+1));
  97. end;
  98. function TFieldDefs.GetCount: Longint;
  99. begin
  100. Result:=FItems.Count;
  101. end;
  102. function TFieldDefs.GetItem(Index: Longint): TFieldDef;
  103. begin
  104. Result:=TFieldDef(FItems[Index]);
  105. end;
  106. constructor TFieldDefs.Create(ADataSet: TDataSet);
  107. begin
  108. Inherited Create(ADataSet);
  109. FItems:=TList.Create;
  110. FDataset:=ADataset;
  111. end;
  112. procedure TFieldDefs.Assign(FieldDefs: TFieldDefs);
  113. Var I : longint;
  114. begin
  115. Clear;
  116. For i:=1 to FieldDefs.Count-1 do
  117. With FieldDefs[i] do
  118. Add(Name,DataType,Size,Required);
  119. end;
  120. procedure TFieldDefs.Clear;
  121. Var I : longint;
  122. begin
  123. For I:=FItems.Count-1 downto 0 do
  124. TFieldDef(Fitems[i]).Free;
  125. end;
  126. function TFieldDefs.Find(const AName: string): TFieldDef;
  127. Var I : longint;
  128. begin
  129. I:=IndexOf(AName);
  130. If I=-1 Then
  131. DataBaseErrorFmt(SUnknownField,[AName,FDataSet.Name]);
  132. Result:=TFieldDef(Fitems[i]);
  133. end;
  134. function TFieldDefs.IndexOf(const AName: string): Longint;
  135. Var I : longint;
  136. begin
  137. For I:=0 to Fitems.Count-1 do
  138. If AnsiCompareText(TFieldDef(FItems[I]).Name,AName)=0 then
  139. begin
  140. Result:=I;
  141. Exit;
  142. end;
  143. Result:=-1;
  144. end;
  145. procedure TFieldDefs.Update;
  146. begin
  147. FDataSet.UpdateFieldDefs;
  148. end;
  149. { ---------------------------------------------------------------------
  150. TField
  151. ---------------------------------------------------------------------}
  152. Const
  153. SBoolean = 'Boolean';
  154. SDateTime = 'TDateTime';
  155. SFloat = 'Float';
  156. SInteger = 'Integer';
  157. SString = 'String';
  158. constructor TField.Create(AOwner: TComponent);
  159. begin
  160. Inherited Create(AOwner);
  161. FVisible:=True;
  162. FValidChars:=[#0..#155];
  163. end;
  164. destructor TField.Destroy;
  165. begin
  166. IF Assigned(FDataSet) then
  167. begin
  168. FDataSet.Active:=False;
  169. FDataSet.RemoveField(Self);
  170. end;
  171. Inherited Destroy;
  172. end;
  173. function TField.AccessError(const TypeName: string): EDatabaseError;
  174. begin
  175. Result:=EDatabaseError.CreateFmt(SinvalidTypeConversion,[TypeName,FFieldName]);
  176. end;
  177. procedure TField.Assign(Source: TPersistent);
  178. begin
  179. //!! To be implemented
  180. end;
  181. procedure TField.Change;
  182. begin
  183. If Assigned(FOnChange) Then
  184. FOnChange(Self);
  185. end;
  186. procedure TField.CheckInactive;
  187. begin
  188. If Assigned(FDataSet) then
  189. FDataset.CheckInactive;
  190. end;
  191. procedure TField.Clear;
  192. begin
  193. SetData(Nil);
  194. end;
  195. procedure TField.DataChanged;
  196. begin
  197. FDataset.DataEvent(deFieldChange,longint(Self));
  198. end;
  199. procedure TField.FocusControl;
  200. begin
  201. FDataSet.DataEvent(deFocusControl,longint(Self));
  202. end;
  203. procedure TField.FreeBuffers;
  204. begin
  205. // Empty. Provided for backward compatibiliy;
  206. // TDataset manages the buffers.
  207. end;
  208. function TField.GetAsBoolean: Boolean;
  209. begin
  210. AccessError(SBoolean);
  211. end;
  212. function TField.GetAsDateTime: TDateTime;
  213. begin
  214. AccessError(SdateTime);
  215. end;
  216. function TField.GetAsFloat: Extended;
  217. begin
  218. AccessError(SDateTime);
  219. end;
  220. function TField.GetAsLongint: Longint;
  221. begin
  222. AccessError(SInteger);
  223. end;
  224. function TField.GetAsString: string;
  225. begin
  226. AccessError(SString);
  227. end;
  228. function TField.GetCanModify: Boolean;
  229. begin
  230. Result:=Not ReadOnly;
  231. If Result then
  232. begin
  233. Result:=Assigned(DataSet);
  234. If Result then
  235. Result:=Not(DataSet.CanModify);
  236. end;
  237. end;
  238. function TField.GetData(Buffer: Pointer): Boolean;
  239. begin
  240. IF FDataset=Nil then
  241. DatabaseErrorFmt(SNoDataset,[FieldName]);
  242. If FVAlidating then
  243. begin
  244. result:=Not(FValueBuffer=Nil);
  245. If Result then
  246. Move (FValueBuffer^,Buffer^ ,DataSize);
  247. end
  248. else
  249. Result:=FDataset.GetFieldData(Self,Buffer);
  250. end;
  251. function TField.GetDataSize: Word;
  252. begin
  253. Result:=0;
  254. end;
  255. function TField.GetDefaultWidth: Longint;
  256. begin
  257. Result:=10;
  258. end;
  259. function TField.GetDisplayName : String;
  260. begin
  261. If FDisplayLabel<>'' then
  262. result:=FDisplayLabel
  263. else
  264. Result:=FFieldName;
  265. end;
  266. function TField.getIndex : longint;
  267. begin
  268. If Assigned(FDataset) then
  269. Result:=FDataset.FFieldList.IndexOf(Self)
  270. else
  271. Result:=-1;
  272. end;
  273. function TField.GetIsNull: Boolean;
  274. begin
  275. Result:=Not(GetData (Nil));
  276. end;
  277. function TField.GetParentComponent: TComponent;
  278. begin
  279. //!! To be implemented
  280. end;
  281. procedure TField.GetText(var AText: string; ADisplayText: Boolean);
  282. begin
  283. AText:=GetAsString;
  284. end;
  285. function TField.HasParent: Boolean;
  286. begin
  287. HasParent:=True;
  288. end;
  289. function TField.IsValidChar(InputChar: Char): Boolean;
  290. begin
  291. // FValidChars must be set in Create.
  292. Result:=InputChar in FValidChars;
  293. end;
  294. procedure TField.Notification(AComponent: TComponent; Operation: TOperation);
  295. begin
  296. Inherited Notification(AComponent,Operation);
  297. end;
  298. procedure TField.PropertyChanged(LayoutAffected: Boolean);
  299. begin
  300. If (FDataset<>Nil) and (FDataset.Active) then
  301. If LayoutAffected then
  302. FDataset.DataEvent(deLayoutChange,0)
  303. else
  304. FDataset.DataEvent(deDatasetchange,0);
  305. end;
  306. procedure TField.ReadState(Reader: TReader);
  307. begin
  308. //!! To be implemented
  309. end;
  310. procedure TField.SetAsBoolean(AValue: Boolean);
  311. begin
  312. AccessError(SBoolean);
  313. end;
  314. procedure TField.SetAsDateTime(AValue: TDateTime);
  315. begin
  316. AccessError(SDateTime);
  317. end;
  318. procedure TField.SetAsFloat(AValue: Extended);
  319. begin
  320. AccessError(SFloat);
  321. end;
  322. procedure TField.SetAsLongint(AValue: Longint);
  323. begin
  324. AccessError(SInteger);
  325. end;
  326. procedure TField.SetAsString(const AValue: string);
  327. begin
  328. AccessError(SString);
  329. end;
  330. procedure TField.SetData(Buffer: Pointer);
  331. begin
  332. If Not Assigned(FDataset) then
  333. EDatabaseError.CreateFmt(SNoDataset,[FieldName]);
  334. FDataSet.SetFieldData(Self,Buffer);
  335. end;
  336. Procedure TField.SetDataset (Value : TDataset);
  337. begin
  338. Writeln ('Setting dataset');
  339. If Value=FDataset then exit;
  340. If Assigned(FDataset) Then FDataset.CheckInactive;
  341. If Assigned(Value) then
  342. begin
  343. Value.CheckInactive;
  344. // ?? Identifier idents no member ??
  345. Value.FFieldList.CheckFieldName(FFieldName);
  346. end;
  347. If Assigned(FDataset) then
  348. FDataset.FFieldList.Remove(Self);
  349. If Assigned(Value) then
  350. begin
  351. Writeln('Adding field to list..');
  352. Value.FFieldList.Add(Self);
  353. end;
  354. FDataset:=Value;
  355. end;
  356. procedure TField.SetDataType(AValue: TFieldType);
  357. begin
  358. FDataType := AValue;
  359. end;
  360. procedure TField.SetFieldType(AValue: TFieldType);
  361. begin
  362. //!! To be implemented
  363. end;
  364. procedure TField.SetParentComponent(AParent: TComponent);
  365. begin
  366. //!! To be implemented
  367. end;
  368. procedure TField.SetSize(AValue: Word);
  369. begin
  370. CheckInactive;
  371. CheckTypeSize(AValue);
  372. FSize:=AValue;
  373. end;
  374. procedure TField.SetText(const AValue: string);
  375. begin
  376. AsString:=AValue;
  377. end;
  378. procedure TField.Validate(Buffer: Pointer);
  379. begin
  380. If assigned(OnValidate) Then
  381. begin
  382. FValueBuffer:=Buffer;
  383. FValidating:=True;
  384. Try
  385. OnValidate(Self);
  386. finally
  387. FValidating:=False;
  388. end;
  389. end;
  390. end;
  391. class function Tfield.IsBlob: Boolean;
  392. begin
  393. Result:=False;
  394. end;
  395. class procedure TField.CheckTypeSize(AValue: Longint);
  396. begin
  397. If (AValue<>0) and Not IsBlob Then
  398. DatabaseErrorFmt(SInvalidFieldSize,[AValue]);
  399. end;
  400. // TField private methods
  401. function TField.GetDisplayText: String;
  402. begin
  403. SetLength(Result, 0);
  404. if Assigned(OnGetText) then
  405. OnGetText(Self, Result, True)
  406. else
  407. GetText(Result, True);
  408. end;
  409. { ---------------------------------------------------------------------
  410. TStringField
  411. ---------------------------------------------------------------------}
  412. constructor TStringField.Create(AOwner: TComponent);
  413. begin
  414. Inherited Create(AOwner);
  415. SetDataType(ftString);
  416. Size:=20;
  417. end;
  418. class procedure TStringField.CheckTypeSize(AValue: Longint);
  419. begin
  420. If (AValue<1) or (AValue>dsMaxStringSize) Then
  421. databaseErrorFmt(SInvalidFieldSize,[AValue])
  422. end;
  423. function TStringField.GetAsBoolean: Boolean;
  424. Var S : String;
  425. begin
  426. S:=GetAsString;
  427. result := (Length(S)>0) and (Upcase(S[1]) in ['T',YesNoChars[True]]);
  428. end;
  429. function TStringField.GetAsDateTime: TDateTime;
  430. begin
  431. Result:=StrToDateTime(GetAsString);
  432. end;
  433. function TStringField.GetAsFloat: Extended;
  434. begin
  435. Result:=StrToFloat(GetAsString);
  436. end;
  437. function TStringField.GetAsLongint: Longint;
  438. begin
  439. Result:=StrToInt(GetAsString);
  440. end;
  441. function TStringField.GetAsString: string;
  442. begin
  443. If Not GetValue(Result) then
  444. Result:='';
  445. end;
  446. function TStringField.GetDataSize: Word;
  447. begin
  448. Result:=Size+1;
  449. end;
  450. function TStringField.GetDefaultWidth: Longint;
  451. begin
  452. result:=Size;
  453. end;
  454. Procedure TStringField.GetText(var AText: string; ADisplayText: Boolean);
  455. begin
  456. AText:=GetAsString;
  457. end;
  458. function TStringField.GetValue(var AValue: string): Boolean;
  459. Var Buf : TStringFieldBuffer;
  460. begin
  461. Result:=GetData(@Buf);
  462. If Result then
  463. AValue:=Buf;
  464. end;
  465. procedure TStringField.SetAsBoolean(AValue: Boolean);
  466. begin
  467. If AValue Then
  468. SetAsString('T')
  469. else
  470. SetAsString('F');
  471. end;
  472. procedure TStringField.SetAsDateTime(AValue: TDateTime);
  473. begin
  474. SetAsString(DateTimeToStr(AValue));
  475. end;
  476. procedure TStringField.SetAsFloat(AValue: Extended);
  477. begin
  478. SetAsString(FloatToStr(AValue));
  479. end;
  480. procedure TStringField.SetAsLongint(AValue: Longint);
  481. begin
  482. SetAsString(intToStr(AValue));
  483. end;
  484. procedure TStringField.SetAsString(const AValue: string);
  485. Const NullByte : char = #0;
  486. begin
  487. IF Length(AValue)=0 then
  488. SetData(@NullByte)
  489. else
  490. SetData(@AValue[1]);
  491. end;
  492. { ---------------------------------------------------------------------
  493. TNumericField
  494. ---------------------------------------------------------------------}
  495. constructor TNumericField.Create(AOwner: TComponent);
  496. begin
  497. Inherited Create(AOwner);
  498. AlignMent:=taRightJustify;
  499. end;
  500. procedure TNumericField.RangeError(AValue, Min, Max: Extended);
  501. begin
  502. DatabaseErrorFMT(SRangeError,[AValue,Min,Max,FieldName]);
  503. end;
  504. procedure TNumericField.SetDisplayFormat(const AValue: string);
  505. begin
  506. If FDisplayFormat<>AValue then
  507. begin
  508. FDisplayFormat:=AValue;
  509. PropertyChanged(True);
  510. end;
  511. end;
  512. procedure TNumericField.SetEditFormat(const AValue: string);
  513. begin
  514. If FEDitFormat<>AValue then
  515. begin
  516. FEDitFormat:=AVAlue;
  517. PropertyChanged(True);
  518. end;
  519. end;
  520. { ---------------------------------------------------------------------
  521. TLongintField
  522. ---------------------------------------------------------------------}
  523. constructor TLongintField.Create(AOwner: TComponent);
  524. begin
  525. Inherited Create(AOwner);
  526. SetDatatype(ftinteger);
  527. FMinRange:=Low(LongInt);
  528. FMaxRange:=High(LongInt);
  529. FValidchars:=['+','-','0'..'9'];
  530. end;
  531. function TLongintField.GetAsFloat: Extended;
  532. begin
  533. Result:=GetAsLongint;
  534. end;
  535. function TLongintField.GetAsLongint: Longint;
  536. begin
  537. If Not GetValue(Result) then
  538. Result:=0;
  539. end;
  540. function TLongintField.GetAsString: string;
  541. Var L : Longint;
  542. begin
  543. If GetValue(L) then
  544. Result:=IntTostr(L)
  545. else
  546. Result:='';
  547. end;
  548. function TLongintField.GetDataSize: Word;
  549. begin
  550. Result:=SizeOf(Longint);
  551. end;
  552. procedure TLongintField.GetText(var AText: string; ADisplayText: Boolean);
  553. var l : longint;
  554. fmt : string;
  555. begin
  556. Atext:='';
  557. If Not GetData(@l) then exit;
  558. If ADisplayText or (FEditFormat='') then
  559. fmt:=FDisplayFormat
  560. else
  561. fmt:=FEditFormat;
  562. { // no formatFloat yet
  563. If length(fmt)<>0 then
  564. AText:=FormatFloat(fmt,L)
  565. else
  566. }
  567. Str(L,AText);
  568. end;
  569. function TLongintField.GetValue(var AValue: Longint): Boolean;
  570. Type
  571. PSmallint = ^SmallInt;
  572. PLongint = ^Longint;
  573. PWord = ^Word;
  574. Var L : Longint;
  575. P : PLongint;
  576. begin
  577. P:=@L;
  578. Result:=GetData(P);
  579. If Result then
  580. Case Datatype of
  581. ftInteger,ftautoinc : AValue:=Plongint(P)^;
  582. ftword : Avalue:=Pword(P)^;
  583. ftsmallint : AValue:=PSmallint(P)^;
  584. end;
  585. end;
  586. procedure TLongintField.SetAsFloat(AValue: Extended);
  587. begin
  588. SetAsLongint(Round(Avalue));
  589. end;
  590. procedure TLongintField.SetAsLongint(AValue: Longint);
  591. begin
  592. If CheckRange(AValue) then
  593. SetData(@AValue)
  594. else
  595. RangeError(Avalue,FMinrange,FMaxRange);
  596. end;
  597. procedure TLongintField.SetAsString(const AValue: string);
  598. Var L,Code : longint;
  599. begin
  600. If length(AValue)=0 then
  601. Clear
  602. else
  603. begin
  604. Val(AVAlue,L,Code);
  605. If Code=0 then
  606. SetAsLongint(L)
  607. else
  608. DatabaseErrorFMT(SNotAnInteger,[Avalue]);
  609. end;
  610. end;
  611. Function TLongintField.CheckRange(AValue : longint) : Boolean;
  612. begin
  613. if FMaxValue=0 Then
  614. Result:=(AValue<=FMaxRange) and (AValue>=FMinRange)
  615. else
  616. Result:=(AValue<=FMaxValue) and (AValue>=FMinValue);
  617. end;
  618. Procedure TLongintField.SetMaxValue (AValue : longint);
  619. begin
  620. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  621. FMaxValue:=AValue
  622. else
  623. RangeError(AValue,FMinRange,FMaxRange);
  624. end;
  625. Procedure TLongintField.SetMinValue (AValue : longint);
  626. begin
  627. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  628. FMinValue:=AValue
  629. else
  630. RangeError(AValue,FMinRange,FMaxRange);
  631. end;
  632. { TSmallintField }
  633. function TSmallintField.GetDataSize: Word;
  634. begin
  635. Result:=SizeOf(SmallInt);
  636. end;
  637. constructor TSmallintField.Create(AOwner: TComponent);
  638. begin
  639. inherited Create(AOwner);
  640. SetDataType(ftSmallInt);
  641. FMinRange:=-32768;
  642. FMaxRange:=32767;
  643. end;
  644. { TWordField }
  645. function TWordField.GetDataSize: Word;
  646. begin
  647. Result:=SizeOf(Word);
  648. end;
  649. constructor TWordField.Create(AOwner: TComponent);
  650. begin
  651. inherited Create(AOwner);
  652. SetDataType(ftWord);
  653. FMinRange:=0;
  654. FMaxRange:=65535;
  655. FValidchars:=['+','0'..'9'];
  656. end;
  657. { TAutoIncField }
  658. constructor TAutoIncField.Create(AOwner: TComponent);
  659. begin
  660. Inherited Create(AOWner);
  661. SetDataType(ftAutoInc);
  662. end;
  663. Procedure TAutoIncField.SetAsLongint(AValue : Longint);
  664. begin
  665. DataBaseError(SCantSetAutoIncfields);
  666. end;
  667. { TFloatField }
  668. function TFloatField.GetAsFloat: Extended;
  669. begin
  670. If Not GetData(@Result) Then
  671. Result:=0.0;
  672. end;
  673. function TFloatField.GetAsLongint: Longint;
  674. begin
  675. Result:=Round(GetAsFloat);
  676. end;
  677. function TFloatField.GetAsString: string;
  678. Var R : Extended;
  679. begin
  680. If GetData(@R) then
  681. Result:=FloatToStr(R)
  682. else
  683. Result:='';
  684. end;
  685. function TFloatField.GetDataSize: Word;
  686. begin
  687. Result:=SizeOf(Extended);
  688. end;
  689. procedure TFloatField.GetText(var TheText: string; ADisplayText: Boolean);
  690. Var
  691. fmt : string;
  692. E : Extended;
  693. begin
  694. text:='';
  695. If Not GetData(@E) then exit;
  696. If ADisplayText or (Length(FEditFormat) = 0) Then
  697. Fmt:=FDisplayFormat
  698. else
  699. Fmt:=FEditFormat;
  700. { // No formatfloat yet
  701. If fmt<>'' then
  702. TheText:=FormatFloat(fmt,E)
  703. else
  704. }
  705. Text:=FloatToStrF(E,ffgeneral,FPrecision,0);
  706. end;
  707. procedure TFloatField.SetAsFloat(AValue: Extended);
  708. begin
  709. If CheckRange(AValue) then
  710. SetData(@Avalue)
  711. else
  712. RangeError(AValue,FMinValue,FMaxValue);
  713. end;
  714. procedure TFloatField.SetAsLongint(AValue: Longint);
  715. begin
  716. SetAsFloat(Avalue);
  717. end;
  718. procedure TFloatField.SetAsString(const AValue: string);
  719. Var R : Extended;
  720. Code : longint;
  721. begin
  722. Val(AVAlue,R,Code);
  723. If Code<>0 then
  724. DatabaseErrorFmt(SNotAFloat,[AVAlue])
  725. Else
  726. SetAsFloat(R);
  727. end;
  728. constructor TFloatField.Create(AOwner: TComponent);
  729. begin
  730. Inherited Create(AOwner);
  731. SetDatatype(ftfloat);
  732. end;
  733. Function TFloatField.CheckRange(AValue : Extended) : Boolean;
  734. begin
  735. If (FMinValue<>0) or (FmaxValue<>0) then
  736. Result:=(AValue>=FMinValue) and (AVAlue<=FMAxValue)
  737. else
  738. Result:=True;
  739. end;
  740. { TBooleanField }
  741. function TBooleanField.GetAsBoolean: Boolean;
  742. begin
  743. If not GetData(@Result) then
  744. Result:=False;
  745. end;
  746. function TBooleanField.GetAsString: string;
  747. Var B : boolean;
  748. begin
  749. If Getdata(@B) then
  750. Result:=FDisplays[False,B]
  751. else
  752. result:='';
  753. end;
  754. function TBooleanField.GetDataSize: Word;
  755. begin
  756. Result:=SizeOf(Boolean);
  757. end;
  758. function TBooleanField.GetDefaultWidth: Longint;
  759. begin
  760. Result:=Length(FDisplays[false,false]);
  761. If Result<Length(FDisplays[false,True]) then
  762. Result:=Length(FDisplays[false,True]);
  763. end;
  764. procedure TBooleanField.SetAsBoolean(AValue: Boolean);
  765. begin
  766. SetData(@AValue);
  767. end;
  768. procedure TBooleanField.SetAsString(const AValue: string);
  769. Var Temp : string;
  770. begin
  771. Temp:=UpperCase(AValue);
  772. If Temp=FDisplays[True,True] Then
  773. SetAsBoolean(True)
  774. else If Temp=FDisplays[True,False] then
  775. SetAsBoolean(False)
  776. else
  777. DatabaseErrorFmt(SNotABoolean,[AValue]);
  778. end;
  779. constructor TBooleanField.Create(AOwner: TComponent);
  780. begin
  781. Inherited Create(AOwner);
  782. SetDataType(ftBoolean);
  783. DisplayValues:='True;False';
  784. end;
  785. Procedure TBooleanField.SetDisplayValues(AValue : String);
  786. Var I : longint;
  787. begin
  788. If FDisplayValues<>AValue then
  789. begin
  790. I:=Pos(';',AValue);
  791. If (I<2) or (I=Length(AValue)) then
  792. DatabaseErrorFmt(SInvalidDisplayValues,[AValue]);
  793. FdisplayValues:=AValue;
  794. // Store display values and their uppercase equivalents;
  795. FDisplays[False,True]:=Copy(AValue,1,I-1);
  796. FDisplays[True,True]:=UpperCase(FDisplays[False,True]);
  797. FDisplays[False,False]:=Copy(AValue,I+1,Length(AValue)-i);
  798. FDisplays[True,False]:=UpperCase(FDisplays[False,False]);
  799. PropertyChanged(True);
  800. end;
  801. end;
  802. { TDateTimeField }
  803. function TDateTimeField.GetAsDateTime: TDateTime;
  804. begin
  805. If Not GetData(@Result) then
  806. Result:=0;
  807. end;
  808. function TDateTimeField.GetAsFloat: Extended;
  809. begin
  810. Result:=GetAsdateTime;
  811. end;
  812. function TDateTimeField.GetAsString: string;
  813. begin
  814. GetText(Result,False);
  815. end;
  816. function TDateTimeField.GetDataSize: Word;
  817. begin
  818. Result:=SizeOf(TDateTime);
  819. end;
  820. procedure TDateTimeField.GetText(var TheText: string; ADisplayText: Boolean);
  821. Var R : TDateTime;
  822. F : String;
  823. begin
  824. If Not Getdata(@R) then
  825. TheText:=''
  826. else
  827. begin
  828. If (ADisplayText) and (Length(FDisplayFormat)<>0) then
  829. F:=FDisplayFormat
  830. else
  831. Case DataType of
  832. ftTime : F:=ShortTimeFormat;
  833. ftDate : F:=ShortDateFormat;
  834. else
  835. F:='c'
  836. end;
  837. TheText:=FormatDateTime(F,R);
  838. end;
  839. end;
  840. procedure TDateTimeField.SetAsDateTime(AValue: TDateTime);
  841. begin
  842. SetData(@Avalue);
  843. end;
  844. procedure TDateTimeField.SetAsFloat(AValue: Extended);
  845. begin
  846. SetAsDateTime(AValue);
  847. end;
  848. procedure TDateTimeField.SetAsString(const AValue: string);
  849. Var R : TDateTime;
  850. begin
  851. R:=StrToDateTime(AVAlue);
  852. SetData(@R);
  853. end;
  854. constructor TDateTimeField.Create(AOwner: TComponent);
  855. begin
  856. Inherited Create(AOwner);
  857. SetDataType(ftDateTime);
  858. end;
  859. { TDateField }
  860. function TDateField.GetDataSize: Word;
  861. begin
  862. Result:=SizeOf(TDateTime);
  863. end;
  864. constructor TDateField.Create(AOwner: TComponent);
  865. begin
  866. Inherited Create(AOwner);
  867. SetDataType(ftDate);
  868. end;
  869. { TTimeField }
  870. function TTimeField.GetDataSize: Word;
  871. begin
  872. Result:=SizeOf(TDateTime);
  873. end;
  874. constructor TTimeField.Create(AOwner: TComponent);
  875. begin
  876. Inherited Create(AOwner);
  877. SetDataType(ftTime);
  878. end;
  879. { TBinaryField }
  880. class procedure TBinaryField.CheckTypeSize(AValue: Longint);
  881. begin
  882. // Just check for really invalid stuff; actual size is
  883. // dependent on the record...
  884. If AValue<1 then
  885. DatabaseErrorfmt(SInvalidFieldSize,[Avalue]);
  886. end;
  887. function TBinaryField.GetAsString: string;
  888. begin
  889. Setlength(Result,DataSize);
  890. GetData(Pointer(Result));
  891. end;
  892. procedure TBinaryField.GetText(var TheText: string; ADisplayText: Boolean);
  893. begin
  894. TheText:=GetAsString;
  895. end;
  896. procedure TBinaryField.SetAsString(const AValue: string);
  897. Var Buf : PChar;
  898. Allocated : Boolean;
  899. begin
  900. Allocated:=False;
  901. If Length(AVAlue)=DataSize then
  902. Buf:=PChar(Avalue)
  903. else
  904. begin
  905. GetMem(Buf,DataSize);
  906. Move(Pchar(Avalue)[0],Buf^,DataSize);
  907. Allocated:=True;
  908. end;
  909. SetData(Buf);
  910. If Allocated then
  911. FreeMem(Buf,DataSize);
  912. end;
  913. procedure TBinaryField.SetText(const AValue: string);
  914. begin
  915. SetAsString(Avalue);
  916. end;
  917. constructor TBinaryField.Create(AOwner: TComponent);
  918. begin
  919. Inherited Create(AOwner);
  920. end;
  921. { TBytesField }
  922. function TBytesField.GetDataSize: Word;
  923. begin
  924. Result:=Size;
  925. end;
  926. constructor TBytesField.Create(AOwner: TComponent);
  927. begin
  928. Inherited Create(AOwner);
  929. SetDataType(ftBytes);
  930. Size:=16;
  931. end;
  932. { TVarBytesField }
  933. function TVarBytesField.GetDataSize: Word;
  934. begin
  935. Result:=Size+2;
  936. end;
  937. constructor TVarBytesField.Create(AOwner: TComponent);
  938. begin
  939. INherited Create(AOwner);
  940. SetDataType(ftvarbytes);
  941. Size:=16;
  942. end;
  943. { TBCDField }
  944. class procedure TBCDField.CheckTypeSize(AValue: Longint);
  945. begin
  946. //!! To be implemented
  947. end;
  948. function TBCDField.GetAsFloat: Extended;
  949. begin
  950. //!! To be implemented
  951. end;
  952. function TBCDField.GetAsLongint: Longint;
  953. begin
  954. //!! To be implemented
  955. end;
  956. function TBCDField.GetAsString: string;
  957. begin
  958. //!! To be implemented
  959. end;
  960. function TBCDField.GetDataSize: Word;
  961. begin
  962. //!! To be implemented
  963. end;
  964. function TBCDField.GetDefaultWidth: Longint;
  965. begin
  966. //!! To be implemented
  967. end;
  968. procedure TBCDField.GetText(var TheText: string; ADisplayText: Boolean);
  969. begin
  970. //!! To be implemented
  971. end;
  972. procedure TBCDField.SetAsFloat(AValue: Extended);
  973. begin
  974. //!! To be implemented
  975. end;
  976. procedure TBCDField.SetAsLongint(AValue: Longint);
  977. begin
  978. //!! To be implemented
  979. end;
  980. procedure TBCDField.SetAsString(const AValue: string);
  981. begin
  982. //!! To be implemented
  983. end;
  984. constructor TBCDField.Create(AOwner: TComponent);
  985. begin
  986. DatabaseError('BCD fields not supported yet. Sorry !');
  987. end;
  988. { TBlobField }
  989. procedure TBlobField.AssignTo(Dest: TPersistent);
  990. begin
  991. //!! To be implemented
  992. end;
  993. Function TBlobField.GetBlobStream(Mode : TBlobStreamMode) : TStream;
  994. begin
  995. Result:=FDataset.CreateBlobStream(Self,Mode);
  996. end;
  997. procedure TBlobField.FreeBuffers;
  998. begin
  999. end;
  1000. function TBlobField.GetAsString: string;
  1001. begin
  1002. With GetBlobStream(bmRead) do
  1003. try
  1004. SetLength(Result,Size);
  1005. ReadBuffer(Pointer(Result)^,Size);
  1006. finally
  1007. Free
  1008. end;
  1009. end;
  1010. function TBlobField.GetBlobSize: Longint;
  1011. begin
  1012. With GetBlobStream(bmread) do
  1013. try
  1014. Result:=Size;
  1015. finally
  1016. Free;
  1017. end;
  1018. end;
  1019. function TBlobField.GetIsNull: Boolean;
  1020. begin
  1021. If Not Modified then
  1022. result:= inherited GetIsnull
  1023. else
  1024. With GetBlobStream(bmread) do
  1025. try
  1026. Result:=(Size=0);
  1027. Finally
  1028. Free;
  1029. end;
  1030. end;
  1031. procedure TBlobField.GetText(var TheText: string; ADisplayText: Boolean);
  1032. begin
  1033. TheText:=GetAsString;
  1034. end;
  1035. procedure TBlobField.SetAsString(const AValue: string);
  1036. begin
  1037. With GetBlobStream(bmwrite) do
  1038. try
  1039. WriteBuffer(Pointer(Avalue)^,Length(Avalue));
  1040. finally
  1041. Free;
  1042. end;
  1043. end;
  1044. procedure TBlobField.SetText(const AValue: string);
  1045. begin
  1046. SetAsString(AValue);
  1047. end;
  1048. constructor TBlobField.Create(AOwner: TComponent);
  1049. begin
  1050. Inherited Create(AOWner);
  1051. SetDataType(ftBlob);
  1052. end;
  1053. procedure TBlobField.Assign(Source: TPersistent);
  1054. begin
  1055. //!! To be implemented
  1056. end;
  1057. procedure TBlobField.Clear;
  1058. begin
  1059. GetBlobStream(bmWrite).free;
  1060. end;
  1061. class function TBlobField.IsBlob: Boolean;
  1062. begin
  1063. Result:=True;
  1064. end;
  1065. procedure TBlobField.LoadFromFile(const FileName: string);
  1066. Var S : TFileStream;
  1067. begin
  1068. S:=TFileStream.Create(FileName,fmOpenRead);
  1069. try
  1070. LoadFromStream(S);
  1071. finally
  1072. S.Free;
  1073. end;
  1074. end;
  1075. procedure TBlobField.LoadFromStream(Stream: TStream);
  1076. begin
  1077. With GetBlobStream(bmWrite) do
  1078. Try
  1079. CopyFrom(Stream,0);
  1080. finally
  1081. Free;
  1082. end;
  1083. end;
  1084. procedure TBlobField.SaveToFile(const FileName: string);
  1085. Var S : TFileStream;
  1086. begin
  1087. S:=TFileStream.Create(FileName,fmCreate);
  1088. try
  1089. SaveToStream(S);
  1090. finally
  1091. S.Free;
  1092. end;
  1093. end;
  1094. procedure TBlobField.SaveToStream(Stream: TStream);
  1095. Var S : TStream;
  1096. begin
  1097. S:=GetBlobStream(bmRead);
  1098. Try
  1099. Stream.CopyFrom(S,0);
  1100. finally
  1101. S.Free;
  1102. end;
  1103. end;
  1104. procedure TBlobField.SetFieldType(AValue: TFieldType);
  1105. begin
  1106. If AValue in [Low(TBlobType)..High(TBlobType)] then
  1107. SetDatatype(Avalue);
  1108. end;
  1109. { TMemoField }
  1110. constructor TMemoField.Create(AOwner: TComponent);
  1111. begin
  1112. Inherited Create(AOwner);
  1113. SetDataType(ftMemo);
  1114. end;
  1115. { TGraphicField }
  1116. constructor TGraphicField.Create(AOwner: TComponent);
  1117. begin
  1118. Inherited Create(AOwner);
  1119. SetDataType(ftGraphic);
  1120. end;
  1121. { TFields }
  1122. Constructor TFields.Create(ADataset : TDataset);
  1123. begin
  1124. FDataSet:=ADataset;
  1125. FFieldList:=TList.Create;
  1126. FValidFieldKinds:=[fkData..fkInternalcalc];
  1127. end;
  1128. Destructor TFields.Destroy;
  1129. begin
  1130. FFieldList.Free;
  1131. end;
  1132. Procedure Tfields.Changed;
  1133. begin
  1134. If Assigned(FOnChange) then
  1135. FOnChange(Self);
  1136. end;
  1137. Procedure TFields.CheckfieldKind(Fieldkind : TFieldKind; Field : TField);
  1138. begin
  1139. If Not (FieldKind in ValidFieldKinds) Then
  1140. DatabaseErrorFmt(SInvalidFieldKind,[Field.FieldName]);
  1141. end;
  1142. Function Tfields.GetCount : Longint;
  1143. begin
  1144. Result:=FFieldList.Count;
  1145. end;
  1146. Function TFields.GetField (Index : longint) : TField;
  1147. begin
  1148. Result:=Tfield(FFieldList[Index]);
  1149. end;
  1150. Procedure TFields.SetFieldIndex (Field : TField;Value : Integer);
  1151. Var Old : Longint;
  1152. begin
  1153. Old := FFieldList.indexOf(Field);
  1154. If Old=-1 then
  1155. Exit;
  1156. // Check value
  1157. If Value<FFieldList.Count Then Value:=0;
  1158. If Value>=Count then Value:=Count-1;
  1159. If Value<>Old then
  1160. begin
  1161. FFieldList.Delete(Old);
  1162. FFieldList.Insert(Value,Field);
  1163. Field.PropertyChanged(True);
  1164. Changed;
  1165. end;
  1166. end;
  1167. Procedure TFields.Add(Field : TField);
  1168. begin
  1169. CheckFieldName(Field.FieldName);
  1170. FFieldList.Add(Field);
  1171. Field.FFields:=Self;
  1172. Changed;
  1173. end;
  1174. Procedure TFields.CheckFieldName (Const Value : String);
  1175. Var I : longint;
  1176. S : String;
  1177. begin
  1178. If FindField(Value)<>Nil then
  1179. begin
  1180. S:=UpperCase(Value);
  1181. For I:=0 To FFieldList.Count-1 do
  1182. If S=UpperCase(TField(FFieldList[i]).FieldName) Then
  1183. DataBaseErrorFmt(SDuplicateFieldName,[Value],FDataset);
  1184. end;
  1185. end;
  1186. Procedure TFields.CheckFieldNames (Const Value : String);
  1187. Var I : longint;
  1188. S,T : String;
  1189. begin
  1190. T:=Value;
  1191. Repeat
  1192. I:=Pos(T,';');
  1193. If I=0 Then I:=Length(T);
  1194. S:=Copy(T,1,I-1);
  1195. Delete(T,1,I);
  1196. // Will raise an error if no such field...
  1197. FieldByName(S);
  1198. Until (T='');
  1199. end;
  1200. Procedure TFields.Clear;
  1201. begin
  1202. end;
  1203. Function TFields.FindField (Const Value : String) : TField;
  1204. Var S : String;
  1205. I : longint;
  1206. begin
  1207. Result:=Nil;
  1208. S:=UpperCase(Value);
  1209. For I:=0 To FFieldList.Count-1 do
  1210. If S=UpperCase(TField(FFieldList[i]).FieldName) Then
  1211. Begin
  1212. {$ifdef dsdebug}
  1213. Writeln ('Found field ',Value);
  1214. {$endif}
  1215. Result:=TField(FFieldList[I]);
  1216. Exit;
  1217. end;
  1218. end;
  1219. Function TFields.FieldByName (Const Value : String) : TField;
  1220. begin
  1221. Result:=FindField(Value);
  1222. If result=Nil then
  1223. DatabaseErrorFmt(SFieldNotFound,[Value],FDataset);
  1224. end;
  1225. Function TFields.FieldByNumber(FieldNo : Integer) : TField;
  1226. Var i : Longint;
  1227. begin
  1228. Result:=Nil;
  1229. For I:=0 to FFieldList.Count-1 do
  1230. If FieldNo=TField(FFieldList[I]).FieldNo then
  1231. begin
  1232. Result:=TField(FFieldList[i]);
  1233. Exit;
  1234. end;
  1235. end;
  1236. Procedure TFields.GetFieldNames (Values : TStrings);
  1237. Var i : longint;
  1238. begin
  1239. Values.Clear;
  1240. For I:=0 to FFieldList.Count-1 do
  1241. Values.Add(Tfield(FFieldList[I]).FieldName);
  1242. end;
  1243. Function TFields.IndexOf(Field : TField) : Longint;
  1244. Var i : longint;
  1245. begin
  1246. Result:=-1;
  1247. For I:=0 To FFieldList.Count-1 do
  1248. If Pointer(Field)=FFieldList[i] Then
  1249. Exit(I);
  1250. end;
  1251. procedure TFields.Remove(Value : TField);
  1252. Var I : longint;
  1253. begin
  1254. I:=IndexOf(Value);
  1255. If I<>0 then
  1256. FFieldList.Delete(I);
  1257. end;
  1258. {
  1259. $Log$
  1260. Revision 1.4 2000-12-24 12:45:19 peter
  1261. * merges from 1.0.x branch
  1262. Revision 1.3 2000/09/02 09:36:36 sg
  1263. * Changed all occurences of TAbstractReader to TReader, as FCL streaming
  1264. is source compatible to VCL streaming now (for quite a while, BTW)
  1265. Revision 1.2 2000/07/13 11:32:56 michael
  1266. + removed logs
  1267. }