fields.inc 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774
  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. { ---------------------------------------------------------------------
  401. TStringField
  402. ---------------------------------------------------------------------}
  403. constructor TStringField.Create(AOwner: TComponent);
  404. begin
  405. Inherited Create(AOwner);
  406. SetDataType(ftString);
  407. Size:=20;
  408. end;
  409. class procedure TStringField.CheckTypeSize(AValue: Longint);
  410. begin
  411. If (AValue<1) or (AValue>dsMaxStringSize) Then
  412. databaseErrorFmt(SInvalidFieldSize,[AValue])
  413. end;
  414. function TStringField.GetAsBoolean: Boolean;
  415. Var S : String;
  416. begin
  417. S:=GetAsString;
  418. result := (Length(S)>0) and (Upcase(S[1]) in ['T',YesNoChars[True]]);
  419. end;
  420. function TStringField.GetAsDateTime: TDateTime;
  421. begin
  422. Result:=StrToDateTime(GetAsString);
  423. end;
  424. function TStringField.GetAsFloat: Extended;
  425. begin
  426. Result:=StrToFloat(GetAsString);
  427. end;
  428. function TStringField.GetAsLongint: Longint;
  429. begin
  430. Result:=StrToInt(GetAsString);
  431. end;
  432. function TStringField.GetAsString: string;
  433. begin
  434. If Not GetValue(Result) then
  435. Result:='';
  436. end;
  437. function TStringField.GetDataSize: Word;
  438. begin
  439. Result:=Size+1;
  440. end;
  441. function TStringField.GetDefaultWidth: Longint;
  442. begin
  443. result:=Size;
  444. end;
  445. Procedure TStringField.GetText(var AText: string; DisplayText: Boolean);
  446. begin
  447. AText:=GetAsString;
  448. end;
  449. function TStringField.GetValue(var AValue: string): Boolean;
  450. Var Buf : TStringFieldBuffer;
  451. begin
  452. Result:=GetData(@Buf);
  453. If Result then
  454. AValue:=Buf;
  455. end;
  456. procedure TStringField.SetAsBoolean(AValue: Boolean);
  457. begin
  458. If AValue Then
  459. SetAsString('T')
  460. else
  461. SetAsString('F');
  462. end;
  463. procedure TStringField.SetAsDateTime(AValue: TDateTime);
  464. begin
  465. SetAsString(DateTimeToStr(AValue));
  466. end;
  467. procedure TStringField.SetAsFloat(AValue: Extended);
  468. begin
  469. SetAsString(FloatToStr(AValue));
  470. end;
  471. procedure TStringField.SetAsLongint(AValue: Longint);
  472. begin
  473. SetAsString(intToStr(AValue));
  474. end;
  475. procedure TStringField.SetAsString(const AValue: string);
  476. Const NullByte : char = #0;
  477. begin
  478. IF Length(AValue)=0 then
  479. SetData(@NullByte)
  480. else
  481. SetData(@AValue[1]);
  482. end;
  483. { ---------------------------------------------------------------------
  484. TNumericField
  485. ---------------------------------------------------------------------}
  486. constructor TNumericField.Create(AOwner: TComponent);
  487. begin
  488. Inherited Create(AOwner);
  489. AlignMent:=taRightJustify;
  490. end;
  491. procedure TNumericField.RangeError(AValue, Min, Max: Extended);
  492. begin
  493. DatabaseErrorFMT(SRangeError,[AValue,Min,Max,FieldName]);
  494. end;
  495. procedure TNumericField.SetDisplayFormat(const AValue: string);
  496. begin
  497. If FDisplayFormat<>AValue then
  498. begin
  499. FDisplayFormat:=AValue;
  500. PropertyChanged(True);
  501. end;
  502. end;
  503. procedure TNumericField.SetEditFormat(const AValue: string);
  504. begin
  505. If FEDitFormat<>AValue then
  506. begin
  507. FEDitFormat:=AVAlue;
  508. PropertyChanged(True);
  509. end;
  510. end;
  511. { ---------------------------------------------------------------------
  512. TLongintField
  513. ---------------------------------------------------------------------}
  514. constructor TLongintField.Create(AOwner: TComponent);
  515. begin
  516. Inherited Create(AOwner);
  517. SetDatatype(ftinteger);
  518. FMinRange:=$80000000;
  519. FMaxRange:=$7fffffff;
  520. FValidchars:=['+','-','0'..'9'];
  521. end;
  522. function TLongintField.GetAsFloat: Extended;
  523. begin
  524. Result:=GetAsLongint;
  525. end;
  526. function TLongintField.GetAsLongint: Longint;
  527. begin
  528. If Not GetValue(Result) then
  529. Result:=0;
  530. end;
  531. function TLongintField.GetAsString: string;
  532. Var L : Longint;
  533. begin
  534. If GetValue(L) then
  535. Result:=IntTostr(L)
  536. else
  537. Result:='';
  538. end;
  539. function TLongintField.GetDataSize: Word;
  540. begin
  541. Result:=SizeOf(Longint);
  542. end;
  543. procedure TLongintField.GetText(var AText: string; DisplayText: Boolean);
  544. var l : longint;
  545. fmt : string;
  546. begin
  547. Atext:='';
  548. If Not GetData(@l) then exit;
  549. If DisplayText or (FEditFormat='') then
  550. fmt:=FDisplayFormat
  551. else
  552. fmt:=FEditFormat;
  553. { // no formatFloat yet
  554. If length(fmt)<>0 then
  555. AText:=FormatFloat(fmt,L)
  556. else
  557. }
  558. Str(L,AText);
  559. end;
  560. function TLongintField.GetValue(var AValue: Longint): Boolean;
  561. Type
  562. PSmallint = ^SmallInt;
  563. PLongint = ^Longint;
  564. PWord = ^Word;
  565. Var L : Longint;
  566. P : PLongint;
  567. begin
  568. P:=@L;
  569. Result:=GetData(P);
  570. If Result then
  571. Case Datatype of
  572. ftInteger,ftautoinc : AValue:=Plongint(P)^;
  573. ftword : Avalue:=Pword(P)^;
  574. ftsmallint : AValue:=PSmallint(P)^;
  575. end;
  576. end;
  577. procedure TLongintField.SetAsFloat(AValue: Extended);
  578. begin
  579. SetAsLongint(Round(Avalue));
  580. end;
  581. procedure TLongintField.SetAsLongint(AValue: Longint);
  582. begin
  583. If CheckRange(AValue) then
  584. SetData(@AValue)
  585. else
  586. RangeError(Avalue,FMinrange,FMaxRange);
  587. end;
  588. procedure TLongintField.SetAsString(const AValue: string);
  589. Var L,Code : longint;
  590. begin
  591. If length(AValue)=0 then
  592. Clear
  593. else
  594. begin
  595. Val(AVAlue,L,Code);
  596. If Code=0 then
  597. SetAsLongint(L)
  598. else
  599. DatabaseErrorFMT(SNotAnInteger,[Avalue]);
  600. end;
  601. end;
  602. Function TLongintField.CheckRange(AValue : longint) : Boolean;
  603. begin
  604. if FMaxValue=0 Then
  605. Result:=(AValue<=FMaxRange) and (AValue>=FMinRange)
  606. else
  607. Result:=(AValue<=FMaxValue) and (AValue>=FMinValue);
  608. end;
  609. Procedure TLongintField.SetMaxValue (AValue : longint);
  610. begin
  611. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  612. FMaxValue:=AValue
  613. else
  614. RangeError(AValue,FMinRange,FMaxRange);
  615. end;
  616. Procedure TLongintField.SetMinValue (AValue : longint);
  617. begin
  618. If (AValue>=FMinRange) and (AValue<=FMaxRange) then
  619. FMinValue:=AValue
  620. else
  621. RangeError(AValue,FMinRange,FMaxRange);
  622. end;
  623. { TSmallintField }
  624. function TSmallintField.GetDataSize: Word;
  625. begin
  626. Result:=SizeOf(SmallInt);
  627. end;
  628. constructor TSmallintField.Create(AOwner: TComponent);
  629. begin
  630. inherited Create(AOwner);
  631. SetDataType(ftSmallInt);
  632. FMinRange:=-32768;
  633. FMaxRange:=32767;
  634. end;
  635. { TWordField }
  636. function TWordField.GetDataSize: Word;
  637. begin
  638. Result:=SizeOf(Word);
  639. end;
  640. constructor TWordField.Create(AOwner: TComponent);
  641. begin
  642. inherited Create(AOwner);
  643. SetDataType(ftWord);
  644. FMinRange:=0;
  645. FMaxRange:=65535;
  646. FValidchars:=['+','0'..'9'];
  647. end;
  648. { TAutoIncField }
  649. constructor TAutoIncField.Create(AOwner: TComponent);
  650. begin
  651. Inherited Create(AOWner);
  652. SetDataType(ftAutoInc);
  653. end;
  654. Procedure TAutoIncField.SetAsLongint(AValue : Longint);
  655. begin
  656. DataBaseError(SCantSetAutoIncfields);
  657. end;
  658. { TFloatField }
  659. function TFloatField.GetAsFloat: Extended;
  660. begin
  661. If Not GetData(@Result) Then
  662. Result:=0.0;
  663. end;
  664. function TFloatField.GetAsLongint: Longint;
  665. begin
  666. Result:=Round(GetAsFloat);
  667. end;
  668. function TFloatField.GetAsString: string;
  669. Var R : Extended;
  670. begin
  671. If GetData(@R) then
  672. Result:=FloatToStr(R)
  673. else
  674. Result:='';
  675. end;
  676. function TFloatField.GetDataSize: Word;
  677. begin
  678. Result:=SizeOf(Extended);
  679. end;
  680. procedure TFloatField.GetText(var TheText: string; DisplayText: Boolean);
  681. Var
  682. fmt : string;
  683. E : Extended;
  684. begin
  685. text:='';
  686. If Not GetData(@E) then exit;
  687. If DisplayText or (Length(FEditFormat) = 0) Then
  688. Fmt:=FDisplayFormat
  689. else
  690. Fmt:=FEditFormat;
  691. { // No formatfloat yet
  692. If fmt<>'' then
  693. TheText:=FormatFloat(fmt,E)
  694. else
  695. }
  696. Text:=FloatToStrF(E,ffgeneral,FPrecision,0);
  697. end;
  698. procedure TFloatField.SetAsFloat(AValue: Extended);
  699. begin
  700. If CheckRange(AValue) then
  701. SetData(@Avalue)
  702. else
  703. RangeError(AValue,FMinValue,FMaxValue);
  704. end;
  705. procedure TFloatField.SetAsLongint(AValue: Longint);
  706. begin
  707. SetAsFloat(Avalue);
  708. end;
  709. procedure TFloatField.SetAsString(const AValue: string);
  710. Var R : Extended;
  711. Code : longint;
  712. begin
  713. Val(AVAlue,R,Code);
  714. If Code<>0 then
  715. DatabaseErrorFmt(SNotAFloat,[AVAlue])
  716. Else
  717. SetAsFloat(R);
  718. end;
  719. constructor TFloatField.Create(AOwner: TComponent);
  720. begin
  721. Inherited Create(AOwner);
  722. SetDatatype(ftfloat);
  723. end;
  724. Function TFloatField.CheckRange(AValue : Extended) : Boolean;
  725. begin
  726. If (FMinValue<>0) or (FmaxValue<>0) then
  727. Result:=(AValue>=FMinValue) and (AVAlue<=FMAxValue)
  728. else
  729. Result:=True;
  730. end;
  731. { TBooleanField }
  732. function TBooleanField.GetAsBoolean: Boolean;
  733. begin
  734. If not GetData(@Result) then
  735. Result:=False;
  736. end;
  737. function TBooleanField.GetAsString: string;
  738. Var B : boolean;
  739. begin
  740. If Getdata(@B) then
  741. Result:=FDisplays[False,B]
  742. else
  743. result:='';
  744. end;
  745. function TBooleanField.GetDataSize: Word;
  746. begin
  747. Result:=SizeOf(Boolean);
  748. end;
  749. function TBooleanField.GetDefaultWidth: Longint;
  750. begin
  751. Result:=Length(FDisplays[false,false]);
  752. If Result<Length(FDisplays[false,True]) then
  753. Result:=Length(FDisplays[false,True]);
  754. end;
  755. procedure TBooleanField.SetAsBoolean(AValue: Boolean);
  756. begin
  757. SetData(@AValue);
  758. end;
  759. procedure TBooleanField.SetAsString(const AValue: string);
  760. Var Temp : string;
  761. begin
  762. Temp:=UpperCase(AValue);
  763. If Temp=FDisplays[True,True] Then
  764. SetAsBoolean(True)
  765. else If Temp=FDisplays[True,False] then
  766. SetAsBoolean(False)
  767. else
  768. DatabaseErrorFmt(SNotABoolean,[AValue]);
  769. end;
  770. constructor TBooleanField.Create(AOwner: TComponent);
  771. begin
  772. Inherited Create(AOwner);
  773. SetDataType(ftBoolean);
  774. DisplayValues:='True;False';
  775. end;
  776. Procedure TBooleanField.SetDisplayValues(AValue : String);
  777. Var I : longint;
  778. begin
  779. If FDisplayValues<>AValue then
  780. begin
  781. I:=Pos(';',AValue);
  782. If (I<2) or (I=Length(AValue)) then
  783. DatabaseErrorFmt(SInvalidDisplayValues,[AValue]);
  784. FdisplayValues:=AValue;
  785. // Store display values and their uppercase equivalents;
  786. FDisplays[False,True]:=Copy(AValue,1,I-1);
  787. FDisplays[True,True]:=UpperCase(FDisplays[False,True]);
  788. FDisplays[False,False]:=Copy(AValue,I+1,Length(AValue)-i);
  789. FDisplays[True,False]:=UpperCase(FDisplays[False,False]);
  790. PropertyChanged(True);
  791. end;
  792. end;
  793. { TDateTimeField }
  794. function TDateTimeField.GetAsDateTime: TDateTime;
  795. begin
  796. If Not GetData(@Result) then
  797. Result:=0;
  798. end;
  799. function TDateTimeField.GetAsFloat: Extended;
  800. begin
  801. Result:=GetAsdateTime;
  802. end;
  803. function TDateTimeField.GetAsString: string;
  804. begin
  805. GetText(Result,False);
  806. end;
  807. function TDateTimeField.GetDataSize: Word;
  808. begin
  809. Result:=SizeOf(TDateTime);
  810. end;
  811. procedure TDateTimeField.GetText(var TheText: string; DisplayText: Boolean);
  812. Var R : TDateTime;
  813. F : String;
  814. begin
  815. If Not Getdata(@R) then
  816. TheText:=''
  817. else
  818. begin
  819. If (DisplayText) and (Length(FDisplayFormat)<>0) then
  820. F:=FDisplayFormat
  821. else
  822. Case DataType of
  823. ftTime : F:=ShortTimeFormat;
  824. ftDate : F:=ShortDateFormat;
  825. else
  826. F:='c'
  827. end;
  828. TheText:=FormatDateTime(F,R);
  829. end;
  830. end;
  831. procedure TDateTimeField.SetAsDateTime(AValue: TDateTime);
  832. begin
  833. SetData(@Avalue);
  834. end;
  835. procedure TDateTimeField.SetAsFloat(AValue: Extended);
  836. begin
  837. SetAsDateTime(AValue);
  838. end;
  839. procedure TDateTimeField.SetAsString(const AValue: string);
  840. Var R : TDateTime;
  841. begin
  842. R:=StrToDateTime(AVAlue);
  843. SetData(@R);
  844. end;
  845. constructor TDateTimeField.Create(AOwner: TComponent);
  846. begin
  847. Inherited Create(AOwner);
  848. SetDataType(ftDateTime);
  849. end;
  850. { TDateField }
  851. function TDateField.GetDataSize: Word;
  852. begin
  853. Result:=SizeOf(TDateTime);
  854. end;
  855. constructor TDateField.Create(AOwner: TComponent);
  856. begin
  857. Inherited Create(AOwner);
  858. SetDataType(ftDate);
  859. end;
  860. { TTimeField }
  861. function TTimeField.GetDataSize: Word;
  862. begin
  863. Result:=SizeOf(TDateTime);
  864. end;
  865. constructor TTimeField.Create(AOwner: TComponent);
  866. begin
  867. Inherited Create(AOwner);
  868. SetDataType(ftTime);
  869. end;
  870. { TBinaryField }
  871. class procedure TBinaryField.CheckTypeSize(AValue: Longint);
  872. begin
  873. // Just check for really invalid stuff; actual size is
  874. // dependent on the record...
  875. If AValue<1 then
  876. DatabaseErrorfmt(SInvalidFieldSize,[Avalue]);
  877. end;
  878. function TBinaryField.GetAsString: string;
  879. begin
  880. Setlength(Result,DataSize);
  881. GetData(Pointer(Result));
  882. end;
  883. procedure TBinaryField.GetText(var TheText: string; DisplayText: Boolean);
  884. begin
  885. TheText:=GetAsString;
  886. end;
  887. procedure TBinaryField.SetAsString(const AValue: string);
  888. Var Buf : PChar;
  889. Allocated : Boolean;
  890. begin
  891. Allocated:=False;
  892. If Length(AVAlue)=DataSize then
  893. Buf:=PChar(Avalue)
  894. else
  895. begin
  896. GetMem(Buf,DataSize);
  897. Move(Pchar(Avalue)[0],Buf^,DataSize);
  898. Allocated:=True;
  899. end;
  900. SetData(Buf);
  901. If Allocated then
  902. FreeMem(Buf,DataSize);
  903. end;
  904. procedure TBinaryField.SetText(const AValue: string);
  905. begin
  906. SetAsString(Avalue);
  907. end;
  908. constructor TBinaryField.Create(AOwner: TComponent);
  909. begin
  910. Inherited Create(AOwner);
  911. end;
  912. { TBytesField }
  913. function TBytesField.GetDataSize: Word;
  914. begin
  915. Result:=Size;
  916. end;
  917. constructor TBytesField.Create(AOwner: TComponent);
  918. begin
  919. Inherited Create(AOwner);
  920. SetDataType(ftBytes);
  921. Size:=16;
  922. end;
  923. { TVarBytesField }
  924. function TVarBytesField.GetDataSize: Word;
  925. begin
  926. Result:=Size+2;
  927. end;
  928. constructor TVarBytesField.Create(AOwner: TComponent);
  929. begin
  930. INherited Create(AOwner);
  931. SetDataType(ftvarbytes);
  932. Size:=16;
  933. end;
  934. { TBCDField }
  935. class procedure TBCDField.CheckTypeSize(AValue: Longint);
  936. begin
  937. //!! To be implemented
  938. end;
  939. function TBCDField.GetAsFloat: Extended;
  940. begin
  941. //!! To be implemented
  942. end;
  943. function TBCDField.GetAsLongint: Longint;
  944. begin
  945. //!! To be implemented
  946. end;
  947. function TBCDField.GetAsString: string;
  948. begin
  949. //!! To be implemented
  950. end;
  951. function TBCDField.GetDataSize: Word;
  952. begin
  953. //!! To be implemented
  954. end;
  955. function TBCDField.GetDefaultWidth: Longint;
  956. begin
  957. //!! To be implemented
  958. end;
  959. procedure TBCDField.GetText(var TheText: string; DisplayText: Boolean);
  960. begin
  961. //!! To be implemented
  962. end;
  963. procedure TBCDField.SetAsFloat(AValue: Extended);
  964. begin
  965. //!! To be implemented
  966. end;
  967. procedure TBCDField.SetAsLongint(AValue: Longint);
  968. begin
  969. //!! To be implemented
  970. end;
  971. procedure TBCDField.SetAsString(const AValue: string);
  972. begin
  973. //!! To be implemented
  974. end;
  975. constructor TBCDField.Create(AOwner: TComponent);
  976. begin
  977. DatabaseError('BCD fields not supported yet. Sorry !');
  978. end;
  979. { TBlobField }
  980. procedure TBlobField.AssignTo(Dest: TPersistent);
  981. begin
  982. //!! To be implemented
  983. end;
  984. Function TBlobField.GetBlobStream(Mode : TBlobStreamMode) : TStream;
  985. begin
  986. Result:=FDataset.CreateBlobStream(Self,Mode);
  987. end;
  988. procedure TBlobField.FreeBuffers;
  989. begin
  990. end;
  991. function TBlobField.GetAsString: string;
  992. begin
  993. With GetBlobStream(bmRead) do
  994. try
  995. SetLength(Result,Size);
  996. ReadBuffer(Pointer(Result)^,Size);
  997. finally
  998. Free
  999. end;
  1000. end;
  1001. function TBlobField.GetBlobSize: Longint;
  1002. begin
  1003. With GetBlobStream(bmread) do
  1004. try
  1005. Result:=Size;
  1006. finally
  1007. Free;
  1008. end;
  1009. end;
  1010. function TBlobField.GetIsNull: Boolean;
  1011. begin
  1012. If Not Modified then
  1013. result:= inherited GetIsnull
  1014. else
  1015. With GetBlobStream(bmread) do
  1016. try
  1017. Result:=(Size=0);
  1018. Finally
  1019. Free;
  1020. end;
  1021. end;
  1022. procedure TBlobField.GetText(var TheText: string; DisplayText: Boolean);
  1023. begin
  1024. TheText:=GetAsString;
  1025. end;
  1026. procedure TBlobField.SetAsString(const AValue: string);
  1027. begin
  1028. With GetBlobStream(bmwrite) do
  1029. try
  1030. WriteBuffer(Pointer(Avalue)^,Length(Avalue));
  1031. finally
  1032. Free;
  1033. end;
  1034. end;
  1035. procedure TBlobField.SetText(const AValue: string);
  1036. begin
  1037. SetAsString(AValue);
  1038. end;
  1039. constructor TBlobField.Create(AOwner: TComponent);
  1040. begin
  1041. Inherited Create(AOWner);
  1042. SetDataType(ftBlob);
  1043. end;
  1044. procedure TBlobField.Assign(Source: TPersistent);
  1045. begin
  1046. //!! To be implemented
  1047. end;
  1048. procedure TBlobField.Clear;
  1049. begin
  1050. GetBlobStream(bmWrite).free;
  1051. end;
  1052. class function TBlobField.IsBlob: Boolean;
  1053. begin
  1054. Result:=True;
  1055. end;
  1056. procedure TBlobField.LoadFromFile(const FileName: string);
  1057. Var S : TFileStream;
  1058. begin
  1059. S:=TFileStream.Create(FileName,fmOpenRead);
  1060. try
  1061. LoadFromStream(S);
  1062. finally
  1063. S.Free;
  1064. end;
  1065. end;
  1066. procedure TBlobField.LoadFromStream(Stream: TStream);
  1067. begin
  1068. With GetBlobStream(bmWrite) do
  1069. Try
  1070. CopyFrom(Stream,0);
  1071. finally
  1072. Free;
  1073. end;
  1074. end;
  1075. procedure TBlobField.SaveToFile(const FileName: string);
  1076. Var S : TFileStream;
  1077. begin
  1078. S:=TFileStream.Create(FileName,fmCreate);
  1079. try
  1080. SaveToStream(S);
  1081. finally
  1082. S.Free;
  1083. end;
  1084. end;
  1085. procedure TBlobField.SaveToStream(Stream: TStream);
  1086. Var S : TStream;
  1087. begin
  1088. S:=GetBlobStream(bmRead);
  1089. Try
  1090. Stream.CopyFrom(S,0);
  1091. finally
  1092. S.Free;
  1093. end;
  1094. end;
  1095. procedure TBlobField.SetFieldType(AValue: TFieldType);
  1096. begin
  1097. If AValue in [Low(TBlobType)..High(TBlobType)] then
  1098. SetDatatype(Avalue);
  1099. end;
  1100. { TMemoField }
  1101. constructor TMemoField.Create(AOwner: TComponent);
  1102. begin
  1103. Inherited Create(AOwner);
  1104. SetDataType(ftMemo);
  1105. end;
  1106. { TGraphicField }
  1107. constructor TGraphicField.Create(AOwner: TComponent);
  1108. begin
  1109. Inherited Create(AOwner);
  1110. SetDataType(ftGraphic);
  1111. end;
  1112. { TFields }
  1113. Constructor TFields.Create(ADataset : TDataset);
  1114. begin
  1115. FDataSet:=ADataset;
  1116. FFieldList:=TList.Create;
  1117. FValidFieldKinds:=[fkData..fkInternalcalc];
  1118. end;
  1119. Destructor TFields.Destroy;
  1120. begin
  1121. FFieldList.Free;
  1122. end;
  1123. Procedure Tfields.Changed;
  1124. begin
  1125. If Assigned(FOnChange) then
  1126. FOnChange(Self);
  1127. end;
  1128. Procedure TFields.CheckfieldKind(Fieldkind : TFieldKind; Field : TField);
  1129. begin
  1130. If Not (FieldKind in ValidFieldKinds) Then
  1131. DatabaseErrorFmt(SInvalidFieldKind,[Field.FieldName]);
  1132. end;
  1133. Function Tfields.GetCount : Longint;
  1134. begin
  1135. Result:=FFieldList.Count;
  1136. end;
  1137. Function TFields.GetField (Index : longint) : TField;
  1138. begin
  1139. Result:=Tfield(FFieldList[Index]);
  1140. end;
  1141. Procedure TFields.SetFieldIndex (Field : TField;Value : Integer);
  1142. Var Old : Longint;
  1143. begin
  1144. Old := FFieldList.indexOf(Field);
  1145. If Old=-1 then
  1146. Exit;
  1147. // Check value
  1148. If Value<FFieldList.Count Then Value:=0;
  1149. If Value>=Count then Value:=Count-1;
  1150. If Value<>Old then
  1151. begin
  1152. FFieldList.Delete(Old);
  1153. FFieldList.Insert(Value,Field);
  1154. Field.PropertyChanged(True);
  1155. Changed;
  1156. end;
  1157. end;
  1158. Procedure TFields.Add(Field : TField);
  1159. begin
  1160. CheckFieldName(Field.FieldName);
  1161. FFieldList.Add(Field);
  1162. Field.FFields:=Self;
  1163. Changed;
  1164. end;
  1165. Procedure TFields.CheckFieldName (Const Value : String);
  1166. Var I : longint;
  1167. S : String;
  1168. begin
  1169. If FindField(Value)<>Nil then
  1170. begin
  1171. S:=UpperCase(Value);
  1172. For I:=0 To FFieldList.Count-1 do
  1173. If S=UpperCase(TField(FFieldList[i]).FieldName) Then
  1174. DataBaseErrorFmt(SDuplicateFieldName,[Value],FDataset);
  1175. end;
  1176. end;
  1177. Procedure TFields.CheckFieldNames (Const Value : String);
  1178. Var I : longint;
  1179. S,T : String;
  1180. begin
  1181. T:=Value;
  1182. Repeat
  1183. I:=Pos(T,';');
  1184. If I=0 Then I:=Length(T);
  1185. S:=Copy(T,1,I-1);
  1186. Delete(T,1,I);
  1187. // Will raise an error if no such field...
  1188. FieldByName(S);
  1189. Until (T='');
  1190. end;
  1191. Procedure TFields.Clear;
  1192. begin
  1193. end;
  1194. Function TFields.FindField (Const Value : String) : TField;
  1195. Var S : String;
  1196. I : longint;
  1197. begin
  1198. Result:=Nil;
  1199. S:=UpperCase(Value);
  1200. For I:=0 To FFieldList.Count-1 do
  1201. If S=UpperCase(TField(FFieldList[i]).FieldName) Then
  1202. Begin
  1203. {$ifdef dsdebug}
  1204. Writeln ('Found field ',Value);
  1205. {$endif}
  1206. Result:=TField(FFieldList[I]);
  1207. Exit;
  1208. end;
  1209. end;
  1210. Function TFields.FieldByName (Const Value : String) : TField;
  1211. begin
  1212. Result:=FindField(Value);
  1213. If result=Nil then
  1214. DatabaseErrorFmt(SFieldNotFound,[Value],FDataset);
  1215. end;
  1216. Function TFields.FieldByNumber(FieldNo : Integer) : TField;
  1217. Var i : Longint;
  1218. begin
  1219. Result:=Nil;
  1220. For I:=0 to FFieldList.Count-1 do
  1221. If FieldNo=TField(FFieldList[I]).FieldNo then
  1222. begin
  1223. Result:=TField(FFieldList[i]);
  1224. Exit;
  1225. end;
  1226. end;
  1227. Procedure TFields.GetFieldNames (Values : TStrings);
  1228. Var i : longint;
  1229. begin
  1230. Values.Clear;
  1231. For I:=0 to FFieldList.Count-1 do
  1232. Values.Add(Tfield(FFieldList[I]).FieldName);
  1233. end;
  1234. Function TFields.IndexOf(Field : TField) : Longint;
  1235. Var i : longint;
  1236. begin
  1237. Result:=-1;
  1238. For I:=0 To FFieldList.Count-1 do
  1239. If Pointer(Field)=FFieldList[i] Then
  1240. Exit(I);
  1241. end;
  1242. procedure TFields.Remove(Value : TField);
  1243. Var I : longint;
  1244. begin
  1245. I:=IndexOf(Value);
  1246. If I<>0 then
  1247. FFieldList.Delete(I);
  1248. end;
  1249. {
  1250. $Log$
  1251. Revision 1.7 2000-01-07 01:24:32 peter
  1252. * updated copyright to 2000
  1253. Revision 1.6 2000/01/06 01:20:32 peter
  1254. * moved out of packages/ back to topdir
  1255. Revision 1.1 2000/01/03 19:33:06 peter
  1256. * moved to packages dir
  1257. Revision 1.4 1999/11/12 22:53:32 michael
  1258. + Added append() insert() tested append. Datetime as string works now
  1259. Revision 1.3 1999/11/11 17:31:09 michael
  1260. + Added Checks for all simple field types.
  1261. + Initial implementation of Insert/Append
  1262. Revision 1.2 1999/10/24 17:07:54 michael
  1263. + Added copyright header
  1264. }