#import "Aprica.h"
// Aprica2
// copyright Pirmin Braun 1997-2007 - pirmin@pirmin.de
// all Rights reserved;
@implementation PBEO
ACCESSClassm(myTable, setMyTable,PBDDTable)
ACCESSm(eoColor, setEoColor)
/* for debugging
- (NSString *)mysqlEscapedString;
{ PRINTCURRENTSTACK;
return EON;
}
*/
- (Application *)application;
{ return _APP;
}
- (Session *)session;
{// fuer scripting %session
return _SESSION;
}
- (PBEO *)eo_copy;
{// returnt eine copy von sich unter beachtung des duplicate-flags an den attributen;
PBEO *newEO;
if(!(newEO = [_APP createEOforEN:entityName]))return nil;
[newEO takeValuesFromDictionaryToDuplicate:[self values]];
return newEO;
}
- (NSString *)pidImagePathForPrint;
{ return [NSSWF @"%@/documents/%@",RESOURCEPATH,[self pidimagefnJpg]];
}
- (void)setPidimagefnJpg:(NSString *)s;
{ if(s == pidimagefnJpg)return;
[pidimagefnJpg release];
pidimagefnJpg = [s retain];
}
- (NSString *)pidimagefnJpg;
{ if(!pidimagefnJpg){ if([myTable hasPidimage]){ NSString *pi = [self vfk:@"pidimagefn"];
if(FILLED(pi)){ [self setPidimagefnJpg:pi];
return pidimagefnJpg;
}
}
[self setPidimagefnJpg:@"1a.jpg"];
}
return pidimagefnJpg;
}
- init;
{ if(!(self = [super init]))return nil;
MDS(values,30);
MD(changedValues);
oldValues=nil;
isCheckedPBEO = NO;
wasFetched = NO;
[self setDescri:nil];
pidimagefnJpg = nil;
return self;
}
- initWithEntityName:(NSString *)en;
{ if(![self init])return nil;
if(!en){ LOGS(@"entityName fehlt");
return nil;
}
[self setEntityName:en];
if(!myTable){ LOGS(([NSSWF @"entityName %@ nicht gefunden",en]));
return nil;
}
return self;
}
- (void)setEntityName:(NSString *)en;
{ if(!FILLED(en)){ LOGS(@"entityName fehlt");
return;
}
if(![en iE:entityName]){ [entityName release];
entityName = [en retain];
}
[self setMyTable:[MYDD tableNamed:entityName]];
}
- (NSString *)entityName;
{ return entityName;
}
- (BOOL)wasFetched;
{ return wasFetched;
}
- (void)setWasFetched:(BOOL)yn;
{ wasFetched = yn;
}
- (NSMutableDictionary *)values;
{ return values;
}
- (NSMutableDictionary *)oldValues;
{ return oldValues;
}
- (void)takeValuesFromDictionaryToDuplicate:(NSDictionary *)d;
{ NSArray *a;
int i,j;
if(!d)return;
a = [myTable plainAttributes];
for(i=0,j=[a count];i<j;i++){ PBDDAttribute *pba = [a oai:i];
if([pba isDuplicate]){ NSString *s = [pba dbName];
[self tvfk([d ofk:s],s)];
}
}
}
- (void)takeValuesOfSameNameFromEo:(PBEO *)eo;
{ NSArray *a;
int i,j;
NSString *s;
if(!eo)return;
a = [[eo myTable]plainAttributes];
for(i=0,j=[a count];i<j;i++){ PBDDAttribute *pba = [a oai:i];
if(![pba isDuplicate])continue;
s = [pba dbName];
if([myTable plainAttrNamed:s]){ [self tvfk([eo vfk:s],s)];
}
}
}
+ (NSDictionary *)knownKeys;
{// YES bedeutet, dass er auch gesetzt werden darf
static NSDictionary *d;
if(!d){ d = [[NSDictionary alloc]initWithObjectsAndKeys:
@"NO",@"values",
@"NO",@"oldValues",
@"NO",@"changedValues",
@"NO",@"descri",
@"NO",@"description",
@"NO",@"entityName",
@"NO",@"myTable",
@"NO",@"primaryKey",
@"NO",@"primaryKeyName",
@"NO",@"pkq",
@"NO",@"class",
@"NO",@"selObj",
@"NO",@"classNameNS",
@"NO",@"pidImagePathForPrint",
@"NO",@"session",
@"NO",@"application",
@"YES",@"pidimagefnJpg",
@"YES",@"isCheckedPBEO",
@"YES",@"eoColor",
nil,nil];
}
return d;
}
- (NSString *)valueForKeyPath:(NSString *)keypath;
{ // keypath aufloesen
NSArray *kps;
PBEO *co = self;
int i,j;
NSString *kpv=EON;
if(!FILLED(keypath))return EON;
kps = [keypath componentsSeparatedByString:@"."];
for(i=0,j = [kps count];i<j;i++){ NSString *kp = [kps oai:i];
kpv = [co vfk:kp]; //Wert aus dem EO
if(!FILLED(kpv))return EON; //geht nicht weiter
if([co isKindOfClass:[PBEO class]]){ PBDDTable *t;
PBDDAttribute *pba;
if(i==(j-1))return kpv; //letztes Element nicht aufloesen, sondern foreignkey liefern
pba = [[co myTable] plainAttrNamed:kp];
if(pba){ if((t = [pba relationTable])){ //relation verfolgen NSString *effTn = [t dbName];
if(effTn){ co = getEOPkValue(effTn,kpv);
if(!co)return EON;
continue;
}
}
}
}
co = (PBEO *)kpv;
}
return kpv;
}
- (NSString *)valueForKey:(NSString *)k;
{ NSString *s;
PBDDAttribute *pbat;
if(!FILLED(k)){ return (NSString *)EON;
}
s=[values vfk:k];
if(s)return s;
if([[PBEO knownKeys]ofk:k])return [super vfk:k];
// convenience for WOD
// _wodValueFor_ prefixes attributename for formatting
if([k hasSecurePrefix:@"_wodValueFor_"]){ k = [k substringFromIndex:[@"_wodValueFor_" length]];
pbat = [myTable plainAttrNamed:k];
if(!pbat)return EON;
s=[values vfk:k];
if(!FILLED(s))return EON;
if([pbat hasVL]){ return [pbat bezeichnungForValue:s];
}else{ switch([pbat dataTyp]){ case DT_DATE:
case DT_DATETIME:
return [s guiDate];
case DT_MONEY:
return MONEYGUI(s);
case DT_FLOAT:
return [NSString dottedGuiFromDouble:[s doubleValue] nak:[pbat nak]];
case DT_INT:
return NSS([s intValue]);
}
return s;
}
}
pbat = [myTable plainAttrNamed:k];
if(!pbat){ if(wasFetched){ LOGS(([NSSWF @"NAME_CHECKING:%@ %@ --- %@ !!!",[_APP currentScriptName],entityName,k]));
// PRINTCURRENTSTACK;
return EON;
}
}else{ if([pbat pbexpression]){ s = (NSString *)[[pbat pbexpression] valueForDatasource:(PBWOEditor *)self varDict:nil localVarDict:nil];
}else{ if([pbat scriptName]){ s = [[_APP executeScriptNamed:[pbat scriptName] datasource:(PBWOEditor *)self parmDict:nil] ofk:@"_rv"];
}else{ return (NSString *)EON;
}
}
if(s){ // nicht cachen; soll es immer wieder neu holen; macht wohl mehr sinn;
return s;
}
}
return (NSString *)EON;
}
- (PBEO *)selObj;
{// f. kompatiblitaet scripting als datasource
return self;
}
- (PBEO *)dot:(NSString *)relationName;
{ return [_APP eoOfRelation:relationName forEo:self];
}
- (void)takeValues:(NSArray *)a1 forKeys:(NSArray *)a2;
{ int i,j;
j = [a1 count];
if(j!=[a2 count]){ LOGS(@"different length of arrays");
// PRINTCURRENTSTACK;
return;
}
for(i=0;i<j;i++){ [self takeValue:[a1 oai:i] forKey:[a2 oai:i]]; //damit richtig geprueft wird
}
}
- (void)takeValue:(NSString *)s forKey:(NSString *)k;
{ NSString *oldVal;
//dem eo duerfen auch Werte gesetzt werden, die nicht als attribute in seiner table vorhanden sind;
// diese werden bei insert/update wieder rausgefiltert
if(!k){ LOGS(@"kein key");
return;
}
// f. debug if([k iE:@"teilanzahl"])LOGS(([NSSWF @"set %@ = %@",k,s]));
if ([[[PBEO knownKeys] ofk: k] boolValue]) { [super takeValue: s forKey: k];
return;
}
if(!s)s = EON;
#ifdef NAME_CHECKING
if(![myTable plainAttrNamed:k] && ![k iE:@"luser"] && ![k iE:@"ldate"] && ![k iE:@"cuser"] && ![k iE:@"cdate"] && ![[PBEO knownKeys]ofk:k]){ LOGS(([NSSWF @"NAME_CHECKING_SET:%@ %@ --- %@ !!!",[_APP currentScriptName],entityName,k]));
// PRINTCURRENTSTACK;
}
#endif
if(!wasFetched){ [values sofk(s,k)];
return;
}
oldVal = [values ofk:k];
if(!oldVal)oldVal = EON;
if(![oldVal iE:s]){ if(!oldValues)MDS(oldValues,20); //f. undo u. sparsames update in DB
if(![oldValues ofk:k]){ [oldValues sofk(oldVal,k)];
}
[values sofk(s,k)];
}
}
- (NSArray *)valuesArrayForKeys:(NSArray *)a;
{ LMA;
int i,j;
for(i=0,j=[a count];i<j;i++){ [lma addObject:[self valueForKey:[a oai:i]]];
}
return lma;
}
- (NSArray *)valuesArrayForKeypaths:(NSArray *)a;
{ LMA;
int i,j;
for(i=0,j=[a count];i<j;i++){ [lma addObject:[self valueForKeyPath:[a oai:i]]];
}
return lma;
}
- (void)dealloc
{ [entityName release];
[values release];
[descri release];
[oldValues release];
[eoColor release];
[changedValues release];
[myTable release];
[pidimagefnJpg release];
[super dealloc];
}
- (NSMutableDictionary *)changedValues;
{ return changedValues;
}
- (PBSQLQualifier *)pkq;
{ NSString *pkn = [self primaryKeyName];
if(!pkn)return PBNOTHINGQ;
return [PBSQLQualifier qualifierWithString:[NSSWF @"%@ = '%@'",pkn,[self primaryKey]]];
}
- (NSString *)primaryKeyName;
{ return [myTable primaryKeyName];
}
- (NSString *)primaryKey;
{ return [self vfk:[self primaryKeyName]];
}
- (void)setPrimaryKey:(NSString *)s;
{ if(!s)return;
[self tvfk(s,[self primaryKeyName])];
}
- (NSString *)descri;
{ NSMutableString *ms;
NSString *dan;
NSArray *a;
int i,j;
if(FILLED(descri))return descri;
a = [myTable descriAttributes];
ms = [NSMutableString stringWithCapacity:50];
[ms setString:EON];
for(i=0,j=[a count];i<j;i++){ if(i)[ms appendString:@"-"];
dan = [[a oai:i]dbName];
[ms appendString:[self vfk:dan]];
}
if(FILLED(ms)){ [self setDescri:[ms abbreviated40String]];
return descri;
}
[self setDescri:[self primaryKey]];
return descri;
}
- (void)setDescri:(NSString *)s;
{ if(s != descri){ [descri release];
descri = [s retain];
}
}
- (BOOL)isEqual:(id)anotherEO;
{ if(![anotherEO isKindOfClass:[PBEO class]])return NO;
if(![entityName iE:[anotherEO entityName]])return NO;
if(FILLED([self primaryKey]) && ![[self primaryKey]iE:[anotherEO primaryKey]])return NO;
return [values iE:[anotherEO values]];
}
- (BOOL)isEqualTableAndPK:(id)anotherEO;
{ if(![anotherEO isKindOfClass:[PBEO class]])return NO;
if(![entityName iE:[anotherEO entityName]])return NO;
if(FILLED([self primaryKey]) && ![[self primaryKey]iE:[anotherEO primaryKey]])return NO;
return YES;
}
- (unsigned)hash
{ return [[self primaryKey] hash]^[entityName hash];
}
- (NSString *)description;
{ return [NSSWF @"%@|%@",entityName,[self primaryKey]];
}
- (void)undo;
{ [values addEntriesFromDictionary:oldValues];
[oldValues removeAllObjects];
}
- (void)refetch;
{ [_APP refetchEO:self];
}
- (void)encodeWithCoder:(NSCoder *)coder
{ [coder encodeObject:entityName];
[coder encodeObject:[self values]];
}
- (id)initWithCoder:(NSCoder *)coder
{ if(![self init])return nil;
[self setEntityName:[coder decodeObject]];
if(!myTable){ LOGS(([NSSWF @"entityName %@ nicht gefunden",entityName]));
return nil;
}
[self useValuesFromDictionary:[coder decodeObject]];
return self;
}
- (void)useValuesFromDictionary:(NSDictionary *)d;
{ NSArray *keys,*dvalues;
int i,j,dt;
NSObject *value;
NSString *key;
PBDDAttribute *pba;
PBDDTable *t = [MYDD tableNamed:entityName];
// ordentlich initalisieren gemaess Modell
keys = [d allKeys];
dvalues = [d allObjects];
for(i=0,j=[keys count];i<j;i++){ key = [keys oai:i];
value = [dvalues oai:i];
pba = [t plainAttrNamed:key];
if(!pba){//auch Werte aufnehmen, fuer die kein pba angelegt ist;
//z.B. sinnvoll bei Archive in BB bzw. XML-Attribute
[[self values] tvfk([(NSString *)value stringValue],key)];
continue;
}
if(!FILLED(value)){ //auch eon mitschleppen value=EON;
}
dt = [pba dataTyp];
switch(dt){ case DT_BOOL:
if(!FILLED(value))value=SC_BOOL_FALSE;
case DT_CHAR:
[[self values] tvfk((NSString *)value,key)];
break;
case DT_DATE:
case DT_DATETIME:
[[self values] tvfk([(NSString *)value normalizedDate],key)];
break;
case DT_MONEY:
case DT_FLOAT:
[[self values] tvfk([NSString dbFromDouble:[(NSNumber *)value doubleValue] pba:pba],key)];
break;
case DT_INT:
[[self values] tvfk(NSS([(NSString *)value intValue]),key)];
break;
}
}
}
- (void)encodeIntoString: (NSMutableString *)ms;
{ NSString *propertyName, *propertyValue;
NSString *pid = [[self primaryKey] stringByEscapingCRTAB];
NSArray *pNames = [myTable dbNamesDB];
int i,j;
for(i=0,j=[pNames count];i<j;i++){ propertyName = [pNames oai:i];
if([propertyName iE:@"cdate"])continue;
if([propertyName iE:@"ldate"])continue;
if([propertyName iE:@"cuser"])continue;
if([propertyName iE:@"luser"])continue;
if([propertyName iE:@"oldid"])continue;
if([propertyName iE:@"von42erp"])continue;
if([propertyName iE:@"collect_trans"])continue;
propertyValue = [[self vfk:propertyName] stringByEscapingCRTAB];
if(!FILLED(propertyValue))propertyValue=EON;
[ms appendString: entityName];
[ms appendString: @"\t"];
[ms appendString: pid];
[ms appendString: @"\t"];
[ms appendString: propertyName]; //propertyName
[ms appendString: @"\t"];
[ms appendString:propertyValue]; //propertyValue
[ms appendString: @"\n"];
}
}
+ (NSArray *)eosFromString:(NSString *)contents;
{ PBEO *eo;
NSArray *lines = [contents componentsSeparatedByString:@"\n"];
LMD; /* Both lmd and lines must be created before the auto release pool.*/
NSAutoreleasePool *pool = [NSAutoreleasePool new];
unsigned i,j,n,m;
for (i=0, n=[lines count]; i<n; i++) { NSString *val[5];
NSString *line = [lines oai: i];
NSArray *fvals = [line componentsSeparatedByString: @"\t"];
if ([line length]==0) continue;
if ([line hasSecurePrefix:@"//"]) continue;
m = [fvals count];
if (m!=4) { LOGS(([NSSWF @"corrupted line %i\n'%@'",i,line]));
continue;
}
for (j=0; j<4; j++) { val[j] = [fvals oai: j];
}
/* Construct GlobalID (entityName+pid) */
val[1] = [val[1] stringByUnescapingCRTAB];
val[3] = [val[3] stringByUnescapingCRTAB];
val[4] = [NSSWF @"%@-%@",val[0],val[1]];
eo = [lmd ofk: val[4]];
if (eo==nil) { eo = [[PBEO alloc]initWithEntityName:val[0]];
[lmd setObject: eo forKey: val[4]];
[eo setPrimaryKey:val[1]];
[eo release];
}
[eo tvfk(val[3],val[2])];
if (i%5 == 0) { [pool release];
pool = [NSAutoreleasePool new];
}
}
[pool release];
return [lmd allValues];
}
@end