eWam vs File System
Beta version
Below APIs are subject to change and are not fully documented. Use it with care and provide us feedback if you use any of those APIs and we will try to keep it retro-compatible
Introduction
What is a file system?
In computing, a file system or filesystem (often abbreviated to fs) controls how data is stored and retrieved. Without a file system, data placed in a storage medium would be one large body of data with no way to tell where one piece of data stops and the next begins. By separating the data into pieces and giving each piece a name, the data is easily isolated and identified. Taking its name from the way paper-based data management system is named, each group of data is called a "file". The structure and logic rules used to manage the groups of data and their names is called a
file system
.
Why is it important?
The goal of this feature is to provide a strategy to map ewam entities also named TGV Units into a corresponding file system representation and matching as much as possible what is expected by the standard, such as metadata and update functionality.
Today eWam Entities are stored in a TGV databases:
W001001.TGV
W003001.TGV
W004001.TGV
Having the entities stored into a database makes it convenient when code is refactored. However it make it incompatible with tradition source code solution such as git.
Implementation
Requirements
It should be possible to:
- Explore eWam Filesystem in a human comprehensible way:
- The number of entities within each folder should not exceed
100
elements - Folder Structure should be corresponding to a logical separation of packages (ie technical vs business, etc...)
- The number of entities within each folder should not exceed
- Access the previous version of a file
- Retrieve metadata information such as:
- last user
- last modification date
TGV Unit // Master Entity
A TGV unit is an element that has not myOwner and that can be shared.
tip
In eWam 7, a new function GetDeliveryOwner can be used to find the master.
Virtual FS Example
- AppFolder
- .installed
System classes and classes installed from third party packages
- .builds
Generated code such as PRBs and wInterface params
- .unpackaged
Entities not yet in bundle
- WFLifeInsurance
Bundle name
- ...
/WFCrossBusiness/Actor/aWFPerson/index.wam
\_____________/\_____/\__________________/
| | |
| | |
Bundle Delivery unit/name
Examples
info
To improve readability, it is possible to hide default values via configuration within the WAMDefault.json
config file.
- Scenario
- Agent
- DBDef
- DBDef Table
Here is an example of a scenario presenting the ID
variable
declare aClassDef[aWLIPerson].AvailableScenarios[WLIPersonIdentityStatusForSynthesis] = aScenario(
myType: aClassDef[aWLIPerson],
DefaultWidth: 725,
DefaultHeight: 138,
DefaultFont: (FontSize: 10),
myCodeAndDefOrImplem: aClassImplem[WLIPersonIdentityStatusForSynthesisAgent],
SubComponents: [
aQVPXXXAsStaticText(
Name: 'StaticText',
myText: 'ID:',
Modifiers: (mMultiLang: true),
X: 544,
Y: 117,
Width: 15,
XFactor: 1,
Kinds: (
Kinds: (stkHalfTone: true, stkEraseRect: true, stkMargin: true, stkBitmap: true),
Shadow: stsDark,
),
myScenario: aVoidAsStaticText[StaticText],
ExplanationFont: (FontSize: 8, FontName: 'Tms Rmn'),
),
aQVPXXXAsStaticText(
Name: 'ID001',
myText: 'ID',
X: 576,
Y: 117,
Width: 12,
XFactor: 1,
Kinds: (
Kinds: (stkHalfTone: true, stkEraseRect: true, stkMargin: true, stkBitmap: true),
Shadow: stsDark,
),
IsForTheType: qvpuUIAgent,
myVar: aClassDef[WLIPersonIdentityStatusForSynthesisAgent].myVars[ID],
myScenario: aXXXAsStaticText[XXXAsStaticText],
ExplanationFont: (FontSize: 8, FontName: 'Tms Rmn'),
)
],
myAvailableEvents: [
aModuleDef[SystemModDef].myTypes[Init],
aModuleDef[SystemModDef].myTypes[Terminate],
aModuleDef[SystemModDef].myTypes[ValueLoaded],
aModuleDef[SystemModDef].myTypes[ValueStored],
aModuleDef[SystemModDef].myTypes[Help]
],
)
; WLIPersonIdentityStatusForSynthesisAgent (aUIAgent) (Def Version:18) (Implem Version:18)
class WLIPersonIdentityStatusForSynthesisAgent (aUIAgent)
uses aWLIPerson, WFStandardPersonIdentityAndStatusAgent, aVoidAsXXXAgent, aCStringControlAgent
Thing : aWLIPerson override
WFStandardPersonIdentityAndStatus : WFStandardPersonIdentityAndStatusAgent
StaticText : aVoidAsXXXAgent
ID : CString
NotDefined : aVoidAsXXXAgent
ID001 : aCStringControlAgent
function NotifyInit return Int2 override
_Result = inherited self.NotifyInit
self.ID = self.Thing.UniqueId
if self.myExecMode = Creation
self.ID001.Hide
self.NotDefined.Show
else
self.ID001.Show
self.NotDefined.Hide
endIf
endFunc
declare aOracleOCI9DBDef[WynsureOracle] = aOracleOCI9DBDef(
Comment: '/SKIPUSELESSREQUESTS /xSKIPUSELESSREQUESTSWITHEXCEPTIONS /SEQIDALLOC',
DataSetId: 9,
DataSetVersion: 32767,
StaticStmtsKept: 40,
fromNSId: 1,
toNsId: 9999999,
fromNSIdContext: 19,
toNSIdContext: 20,
Shared: true,
AccessPlanDescriptors: null,
LastOwnedId: 155171,
DBMgrClassDef: aClassDef[aWynsureOracleORAPRBDBMgr],
UserName: 'WydefCurrent_Accept_fr',
PassWord: '*****',
DefaultTableDescs: [
aSqlTableDesc(
Name: 'IDALLOCATOR',
myColumns: [
aSqlColumnDesc(
Name: 'NSID',
myType: aOracleOCI9DBDef[WynsureOracle].AvailableTypes[NUMBER],
myData: aSqlTypeDataForNumber(Precision: '10'),
),
aSqlColumnDesc(
Name: 'LASTALLOCATEDID',
myType: aOracleOCI9DBDef[WynsureOracle].AvailableTypes[NUMBER],
myData: aSqlTypeDataForNumber(NotNull: false, ConversionKind: CStringConversion,
Precision: '20'),
)
],
myIndexes: [
aSqlIndexDesc(
Name: 'IIDALLOCATOR',
Primary: true,
Unique: true,
myColumns: [
aOracleOCI9DBDef[WynsureOracle].DefaultTableDescs[IDALLOCATOR].myColumns[NSID]
],
)
],
)
],
AvailableTypes: [
aSqlTypeWithPrecision(Name: 'CHAR', myText: 'CHAR', TypeKind: 96),
aSqlTypeWithPrecision(Name: 'VARCHAR2', myText: 'VARCHAR2', TypeKind: 1),
aSqlType(Name: 'LONG', myText: 'LONG', TypeKind: 8, FixedPrecision: 1048576),
aSqlTypeForNumber(Name: 'NUMBER', myText: 'NUMBER', TypeKind: 2),
aSqlTypeWithPrecision(Name: 'RAW', myText: 'RAW', TypeKind: 23),
aSqlType(Name: 'LONG RAW', myText: 'LONG RAW', TypeKind: 24, FixedPrecision: 1048576),
aOracleSqlDateType(Name: 'DATE (for date only)', myText: 'DATE', TypeKind: 12,
FixedPrecision: 7, NewTimeFormatWithValidDate: true),
aOracleSqlDateType(Name: 'DATE (for time only)', myText: 'DATE', TypeKind: 12,
FixedPrecision: 7, WhatToStore: dtTime, NewTimeFormatWithValidDate: true),
aOracleSqlDateType(Name: 'DATE (date and time)', myText: 'DATE', TypeKind: 12,
FixedPrecision: 7, WhatToStore: dtDateTime, NewTimeFormatWithValidDate: true),
aSqlType(Name: 'CLOB', myText: 'CLOB', TypeKind: 112, FixedPrecision: 1048576),
aSqlType(Name: 'BLOB', myText: 'BLOB', TypeKind: 113, FixedPrecision: 1048576),
aSqlTypeWithPrecision(Name: 'NCHAR', myText: 'NCHAR', TypeKind: 96),
aSqlTypeWithPrecision(Name: 'NVARCHAR2', myText: 'NVARCHAR2', TypeKind: 1),
aSqlType(Name: 'NCLOB', myText: 'NCLOB', TypeKind: 112, FixedPrecision: 1048576),
aSqlTypeWithPrecision(Name: 'CLOB (with variable precision)', myText: 'CLOB',
TypeKind: 112),
aSqlTypeWithPrecision(Name: 'BLOB (with variable precision)', myText: 'BLOB',
TypeKind: 113),
aSqlTypeWithPrecision(Name: 'NCLOB (with variable precision)', myText: 'NCLOB',
TypeKind: 112)
],
DataBaseName: 'WynsureTest',
FailoverRetries: 60,
FailoverDelay: 3,
UseCLOBForDefaultTextMapping: true,
TablesTableSpace: 'WYNCURRENT_DATA',
IndexesTableSpace: 'WYNCURRENT_INDX',
AccentInsensitive: true,
LockDurationDays: 10,
)
declare aOracleOCI9DBDef[WynsureOracle].myClassDBDefs[aEDA_Event] = aSqlClassDefRepresentation(
Presenting: aClassDef[aEDA_Event],
NbrversionsKept: 5,
UseClassDefAPDescs: true,
ClassTable: aSqlTableDesc(
Name: 'AEDA_EVENT',
Presenting: aClassDef[aEDA_Event],
myColumns: [
aSqlColumnDesc(
Name: 'NSID',
Presenting: aClassDef[aFullObject].myVars[NSId],
myType: aOracleOCI9DBDef[WynsureOracle].AvailableTypes[NUMBER],
myData: aSqlTypeDataForNumber(Precision: '10'),
),
aSqlColumnDesc(
Name: 'ID',
Presenting: aClassDef[aFullObject].myVars[Id],
myType: aOracleOCI9DBDef[WynsureOracle].AvailableTypes[NUMBER],
myData: aSqlTypeDataForNumber(ConversionKind: CStringConversion, Precision: '20'),
),
aSqlColumnDesc(
Name: 'VERSION',
Presenting: aClassDef[aFullObject].myVars[Version],
myType: aOracleOCI9DBDef[WynsureOracle].AvailableTypes[NUMBER],
myData: aSqlTypeDataForNumber
...
Virtual FS API
GET /fs/file:/
=> Give all packages name and.installed
and.unpackaged
directoriesGET /fs/file:/{package}
=> Give package folder namesGET /{package}/{folder}
=> Give the package folder content:- In addition to the folder content we need to add entities that have the
Package Annotation
matching the requested package and folder. See below. - TGV units will be served from namespaces to avoid name collisions.
- In addition to the folder content we need to add entities that have the
GET /file:/{package}/{folder}/{namespace}/{name}/index.gold?version={version}
- => give a TGV Unit
- Medata such as last user and modification date should be send in headers
- Giving the version parameter should allow to retrieve a previous version
POST /{package}/{folder}/{namespace}/{name}/index.wam
=> Modify a TGV UnitDELETE /{package}/{folder}/{namespace}/{name}/index.wam
=> Delete a TGV UnitPUT /{package}/{folder}/{namespace}/{name}/index.wam
=> Create a TGV Unit within the namespace
Beta version
Below APIs are subject to change and are not fully documented. Use it with care and provide us feedback if you use any of those APIs and we will try to keep it retro-compatible