Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions src/Runtime/XSharp.VFP.Tests/CommandTests.prg
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,73 @@ BEGIN NAMESPACE XSharp.VFP.Tests
TRY ; System.IO.Directory.Delete(cTempPath, TRUE) ; CATCH ; END TRY
END TRY
END METHOD

[Fact];
METHOD TestGetFldStateAndSetFldState() AS VOID
VAR cOldDir := System.IO.Directory.GetCurrentDirectory()
VAR oDir := System.IO.Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), ;
"FldStateTest_" + Guid.NewGuid():ToString("N")))
VAR cTempPath := oDir:FullName

TRY
SET DEFAULT TO (cTempPath)

// 3-field table (field count differs from other tests -> fresh state array)
CREATE TABLE FldTest (Id INT, Name C(10), Active L)
INSERT INTO FldTest VALUES (1, "Alice", .T.)
GO TOP

// Default state: 1 for everything (no buffering active yet)
Assert.Equal(1, (INT) GetFldState(0)) // deletion flag
Assert.Equal(1, (INT) GetFldState(1)) // field 1 by number
Assert.Equal(1, (INT) GetFldState("NAME")) // field by name
Assert.Equal("1111", (STRING) GetFldState(-1)) // all: deletion + 3 fields

// SETFLDSTATE roundtrip: mark field 1 as modified (2)
Assert.True(SetFldState(1, 2))
Assert.Equal(2, (INT) GetFldState(1))
Assert.Equal("1211", (STRING) GetFldState(-1))

// SETFLDSTATE by name
Assert.True(SetFldState("ACTIVE", 2))
Assert.Equal(2, (INT) GetFldState("ACTIVE"))
Assert.Equal(2, (INT) GetFldState(3)) // same field by number

// Deletion field (0)
Assert.True(SetFldState(0, 2))
Assert.Equal(2, (INT) GetFldState(0))
Assert.Equal("2212", (STRING) GetFldState(-1)) // deletion=2, Id=2, Name=1, Active=2

// Reset a field back to 1
Assert.True(SetFldState(1, 1))
Assert.Equal(1, (INT) GetFldState(1))

// Alias and workarea number overloads
Assert.True(SetFldState(2, 2))
Assert.Equal(2, (INT) GetFldState(2, "FldTest"))
Assert.Equal(2, (INT) GetFldState(2, Select()))

// Invalid state value -> FALSE
Assert.False(SetFldState(1, 5))
Assert.False(SetFldState(1, 0))

// EOF -> .NULL. (verify as non-NIL, non-numeric — exact NULL type per runtime)
GO BOTTOM
SKIP
Assert.True(Eof())
VAR vNull := GetFldState(1)
Assert.True((OBJECT) vNull IS System.DBNull)

// Non-existent alias -> NIL
Assert.True(GetFldState(1, "NoSuchAlias") == NIL)

FINALLY
XSharp.CoreDb.CloseAll()
SET DEFAULT TO (cOldDir)
System.IO.Directory.SetCurrentDirectory(cOldDir)
TRY ; System.IO.Directory.Delete(cTempPath, TRUE) ; CATCH ; END TRY
END TRY
END METHOD
END CLASS

END NAMESPACE
110 changes: 110 additions & 0 deletions src/Runtime/XSharp.VFP/Cursors/DbFunctions.prg
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,94 @@ FUNCTION Target( nRelationshipNumber , uArea ) AS STRING CLIPPER
FUNCTION Unique(uArea ) AS LOGIC CLIPPER
RETURN _DoInArea(uArea, { => (LOGIC) DbOrderInfo(DBOI_UNIQUE , NIL, NIL) } , FALSE,__FUNCTION__,1)


/// <include file="VFPDocs.xml" path="Runtimefunctions/getfldstate/*" />
[FoxProFunction("GETFLDSTATE", FoxFunctionCategory.CursorAndTable, FoxEngine.WorkArea, FoxFunctionStatus.Partial, FoxCriticality.High)];
FUNCTION GetFldState(uField, uArea) AS USUAL CLIPPER
LOCAL nArea := _AreaFromParam(uArea) AS DWORD
IF nArea == 0
RETURN NIL
ENDIF
VAR nOldArea := RuntimeState.CurrentWorkarea
RuntimeState.CurrentWorkarea := nArea
TRY
IF !Used()
RETURN NIL
ENDIF
IF Eof()
RETURN DBNull.Value
ENDIF
LOCAL nCount := (int)FCount() AS INT
IF IsString(uField)
VAR nFld := CoreDb.CWA(__FUNCTION__):FieldIndex((STRING) uField)
IF nFld == 0
RETURN NIL
ENDIF
RETURN (INT) _GetFldStateFromCargo(nArea, nFld)
ELSEIF IsNumeric(uField)
LOCAL nFldNum := (INT) uField AS INT
DO CASE
CASE nFldNum == -1
VAR sb := System.Text.StringBuilder{}
sb:Append(_GetFldStateFromCargo(nArea, 0):ToString())
FOR VAR j := 1 TO nCount
sb:Append(_GetFldStateFromCargo(nArea, j):ToString())
NEXT
RETURN sb:ToString()
CASE nFldNum == 0
RETURN (INT) _GetFldStateFromCargo(nArea, 0)
CASE nFldNum >= 1 .AND. nFldNum <= nCount
RETURN (INT) _GetFldStateFromCargo(nArea, nFldNum)
ENDCASE
ENDIF
RETURN NIL
FINALLY
RuntimeState.CurrentWorkarea := nOldArea
END TRY

/// <include file="VFPDocs.xml" path="Runtimefunctions/setfldstate/*" />
[FoxProFunction("SETFLDSTATE", FoxFunctionCategory.CursorAndTable, FoxEngine.WorkArea, FoxFunctionStatus.Partial, FoxCriticality.High)];
FUNCTION SetFldState(uField, nFieldState, uArea) AS LOGIC CLIPPER
IF IsNil(nFieldState)
RETURN FALSE
ENDIF
LOCAL nState := (INT) nFieldState AS INT
IF nState < 1 .OR. nState > 4
RETURN FALSE
ENDIF
LOCAL nArea := _AreaFromParam(uArea) AS DWORD
IF nArea == 0
RETURN FALSE
ENDIF
VAR nOldArea := RuntimeState.CurrentWorkarea
RuntimeState.CurrentWorkarea := nArea
TRY
IF !Used()
RETURN FALSE
ENDIF
LOCAL nCount := (int)FCount() AS INT
IF IsString(uField)
VAR nFld := CoreDb.CWA(__FUNCTION__):FieldIndex((STRING) uField)
IF nFld == 0
RETURN FALSE
ENDIF
_SetFldStateInCargo(nArea, nFld, (BYTE) nState)
RETURN TRUE
ELSEIF IsNumeric(uField)
LOCAL nFldNum := (INT) uField AS INT
IF nFldNum == 0
_SetFldStateInCargo(nArea, 0, (BYTE) nState)
RETURN TRUE
ELSEIF nFldNum >= 1 .AND. nFldNum <= nCount
_SetFldStateInCargo(nArea, nFldNum, (BYTE) nState)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
FINALLY
RuntimeState.CurrentWorkarea := nOldArea
END TRY

/// <include file="VFPDocs.xml" path="Runtimefunctions/indexseek/*" />
[FoxProFunction("INDEXSEEK", FoxFunctionCategory.Database, FoxEngine.WorkArea, FoxFunctionStatus.Full, FoxCriticality.High)];
FUNCTION IndexSeek( eExpression , lMovePointer , uArea, uIndex) AS LOGIC CLIPPER
Expand Down Expand Up @@ -265,3 +353,25 @@ INTERNAL FUNCTION _AreaFromParam(uArea AS USUAL) AS DWORD
ENDIF

RETURN 0

INTERNAL FUNCTION _GetFldStateFromCargo(nArea AS DWORD, nField AS INT) AS BYTE
LOCAL cargo AS Dictionary<INT,BYTE>
LOCAL oCargo := RuntimeState.Workareas:GetCargo(nArea) AS OBJECT
IF oCargo IS Dictionary<INT,BYTE> VAR dict
LOCAL b AS BYTE
IF dict:TryGetValue(nField, REF b)
RETURN b
ENDIF
ENDIF
RETURN 1

INTERNAL FUNCTION _SetFldStateInCargo(nArea AS DWORD, nField AS INT, nState AS BYTE) AS VOID
LOCAL oCargo := RuntimeState.Workareas:GetCargo(nArea) AS OBJECT
LOCAL dict AS Dictionary<INT,BYTE>
IF oCargo IS Dictionary<INT,BYTE> VAR existing
dict := existing
ELSE
dict := Dictionary<INT,BYTE>{}
RuntimeState.Workareas:SetCargo(nArea, dict)
ENDIF
dict[nField] := nState
7 changes: 0 additions & 7 deletions src/Runtime/XSharp.VFP/ToDo-G.prg
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@ FUNCTION GetCursorAdapter( cAlias )
THROW NotImplementedException{}
// RETURN NULL

/// <summary>-- todo --</summary>
/// <include file="VFPDocs.xml" path="Runtimefunctions/getfldstate/*" />
[FoxProFunction("GETFLDSTATE", FoxFunctionCategory.CursorAndTable, FoxEngine.WorkArea, FoxFunctionStatus.Stub, FoxCriticality.High)];
FUNCTION GetFldState( uField , uArea) AS USUAL
THROW NotImplementedException{}
// RETURN NIL

/// <summary>-- todo --</summary>
/// <include file="VFPDocs.xml" path="Runtimefunctions/getnextmodified/*" />
[FoxProFunction("GETNEXTMODIFIED", FoxFunctionCategory.CursorAndTable, FoxEngine.WorkArea, FoxFunctionStatus.Stub, FoxCriticality.High)];
Expand Down
7 changes: 0 additions & 7 deletions src/Runtime/XSharp.VFP/ToDo-S.prg
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,6 @@ FUNCTION Scheme( nSchemeNumber , nColorPairNumber) AS STRING
THROW NotImplementedException{}
// RETURN ""

/// <summary>-- todo --</summary>
/// <include file="VFPDocs.xml" path="Runtimefunctions/setfldstate/*" />
[FoxProFunction("SETFLDSTATE", FoxFunctionCategory.CursorAndTable, FoxEngine.WorkArea, FoxFunctionStatus.Stub, FoxCriticality.High)];
FUNCTION SetFldState( uField, nFieldState , uArea) AS LOGIC
THROW NotImplementedException{}
// RETURN FALSE

/// <summary>-- todo --</summary>
/// <include file="VFPDocs.xml" path="Runtimefunctions/setresultset/*" />
[FoxProFunction("SETRESULTSET", FoxFunctionCategory.SQL, FoxEngine.SQL, FoxFunctionStatus.Stub, FoxCriticality.Medium)];
Expand Down
Loading