V4CC Questions

Justin Drury justin at crunch-recording.com
Fri Dec 9 11:49:21 CST 2005


Hello...

Faulting: From Apple's docs
The object graph should be no larger than is necessary. Ideally, you  
should not have more model objects in memory than are necessary for  
the user’s current needs.

 From my experience valentina is very optimized, so this shouldn't be  
an issue.  I was getting about 1800 allotments in objectalloc in a  
tableview with 40 or so rows being displayed and 6 columns.

As far as implementation, I hope the foundation tool code is helpful  
enough.  You can always look up the framework in XCode's class browser.

Essentially instead of inheriting from NSObject we inherit from  
VObject(and it inherits from NSObject).  Its basically an empty  
class, it ensures that our valentina objects are all descendants of  
VObject(for future type checking).  It shouldn't concern you though...

You have one singleton class - Valentina, you MUST call the class  
method initWithCacheSize: on this. (I'd do it on +(initialize))  This  
sets up all the C++ static objects.

Then you have VDatabase (representing a database of tables, local or  
remote, ram or disk based)
,VTable(a specific table of VFields)
,VCursor(a query on vDatabase, supports joins/links across multiple  
tables) You'll also see a lot of API method and SQL method chat, for  
learning I'd recommend doing some sql queries(basically passing in a  
NSString representing the query to an instance of VDatabase)

Then you have VField and it's descendants, these are all the  
VVarchar, VBoolean, etc types.  When you construct a field using the  
VTable methods you can pass parameters specific to the type of VField 
(max length for instance).

All the usual cocoa rules apply, you create it you release it! (In my  
code below, I create VDatabase so it needs a release), all other  
objects are autoreleased, so I would retain them if I wanted them to  
persist.  For my needs i've found it sufficient for my controller to  
have a VDatabase and VCursor ivar.  The query I want to retain and  
display I key code to that ivar so the observers in my NIB can  
refresh themselves when the query change...
(ie...[typed in mail not tested])

@interface AppController:NSObject
{
VDatabase *dbTest;
VCursor *displayCursor;
}
- (VCursor *)displayCursor;
- (void)setDisplayCursor:(VCursor *)aDisplayCursor;

// etc...
@end

And then in the implementation...

- (void) doQuery:(NSString*) aQuery
{
	NS_DURING
	VCursor *testCursor=[dbTest sqlSelect:@"select * from  
tableTest"]; // bring back the first 100
	[self setDisplayCursor:aQuery];
	 	
	 NS_HANDLER
		 // display error message
	NS_ENDHANDLER

}

- (VCursor *)displayCursor
{
     return displayCursor;
}
- (void)setDisplayCursor:(VCursor *)aDisplayCursor
{
     if (displayCursor != aDisplayCursor) {
         [aDisplayCursor retain];
         [displayCursor release];
         displayCursor = aDisplayCursor;
     }
}


Hope that helps, i've yet to have coffee so I hope that's reasonably  
right!
--------------------------------
Heres the foundation test tool code for the archives...

void PrintResultToLog(VCursor* cursorPtr);

int main (int argc, const char * argv[]) {
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	VDataBase *dbTest;	
	int i;	
	[[Valentina sharedManager] initWithCacheSize:4 * 1024 * 1024  
macSerial:@"demo serial"];
	//[[Valentina sharedManager] setDebugLevel:3];
	
	dbTest=[[VDataBase alloc]initWithStorageType:kV4CC_Storage_RAM];
	[dbTest create:@"/test_dbFields"]; // Create a test_db on startup  
volume...
	
	VTable *newTable=[dbTest createTable:@"tableTest"];
	
	// Create some various field types in the table...
	[newTable createByteField:@"byteField"];
	[newTable createShortField:@"shortField"];
	[newTable createUShortField:@"ushortField"];
	[newTable createMediumField:@"mediumField"];
	[newTable createUMediumField:@"umediumField"];
	[newTable createLongField:@"longField"];
	[newTable createULongField:@"ulongField"];
	[newTable createLLongField:@"llongField"];
	[newTable createULLongField:@"ullongField"];
	[newTable createFloatField:@"floatField"];
	[newTable createDoubleField:@"dblField"];
	[newTable createDateField:@"dateField"];
	[newTable createTimeField:@"timeField"];
	[newTable createDateTimeField:@"dateTimeField"];
	[newTable createStringField:@"stringField" maxLength:200];
	[newTable createVarCharField:@"varstringField" maxLength:200];
	[newTable createFixedBinaryField:@"fixedBinaryField" maxLength:200];
	[newTable createVarBinaryField:@"varBinaryField" maxLength:200];
	[newTable createBLOBField:@"blobField" segmentSize:32];
	[newTable createTextField:@"textField"segmentSize:32];
	[newTable createPictureField:@"pictureField"segmentSize:32];
	
	/*************  Create another field, and populate it **************/
	[newTable createVarCharField:@"testField" maxLength:200];
	VVarChar *stringtestField;
	// let's cache the field for speed.
	stringtestField=(VVarChar*)[newTable fieldForName:@"testField"]; //  
I could have just done stringtestField=[newTable  
createVarCharField:@"testField" maxLength:200]; but this is a demo!

	for (i=0;i<5000;i++) // create 5000 records
	{
		[newTable setBlank];
		[stringtestField setStringValue:[NSString stringWithFormat:@"A test  
string:%i",i]];
		[newTable addRecord];
	}
	[newTable flush];
	
	/*************  NOW A SQL QUERY **************/
	// queries will throw exceptions, even if they are malformed...
	
	NS_DURING
	VCursor *testCursor=[dbTest sqlSelect:@"select testField from  
tableTest limit 100"]; // bring back the first 100
	PrintResultToLog(testCursor);
	
	 // OK let's do another
	 testCursor=[dbTest sqlSelect:@"select UPPER(testField) from  
tableTest limit 50"];
	 PrintResultToLog(testCursor);
	 	
	 NS_HANDLER
		
	NS_ENDHANDLER
	
	
	/*************  NOW A DUMP **************/
	//[dbTest dump:@"/testdump" dumpType:1];
	
	 /*************  Cleanup **************/
	[dbTest close];	
	[dbTest release];
	[[Valentina sharedManager] shutDown];
     [pool release];
	
     return 0;
}
/ 
************************************************************************ 
*************************/
void PrintResultToLog(VCursor* cursorPtr)
{
	// Setup a little release pool
	NSAutoreleasePool *innerPool=[[NSAutoreleasePool alloc]init];
	int i;
	NSLog(@"%s",__PRETTY_FUNCTION__);
	for (i=0;i<[cursorPtr recordCount];i++)
	{
		[cursorPtr setPosition:i];
		NSLog([[cursorPtr fieldAtIndex:0]stringValue]);
	}
	
	[innerPool release];
}




More information about the Valentina-beta mailing list