2010/12/27 Bruce Bruen <bbr...@paddys-hill.net>: > > Hello all, > > (gambas 2.22) > > I am trying to build a persistence mechanism ala Ambler to decouple the > business logic from the persistence mechanism. I have done this > > several times before in gambas with great success, but with the "rule" that > a > > business-object instance can only represent a single row in the associated > > database table. However, this time I am trying to include a way to allow > > a single business-object instance to represent a set of database rows and > > to provide the means to enumerate across the rows. In short, it changes the > > business-object class into a psuedo collection. > > I have attached a png showing the class structure. It has been simplified > very much to illustrate the problem I am having. > > [cid:183244887@KDE] > > I have also attached a test project (as a "source archive") that > demonstrates the problems. These are > > 1) Use of "WITH" seems to decouple the _free() method > > 2) use of "FOR EACH ... NEXT" seems to decouple the _free() method and > > introduces circular references. > > The test project steps through a number of test cases. In each step, an > instance of a specific business-object class is created and an explicit > destruction request is issued > > $employee = NEW Employee > > ... > > $employee = NULL > > Between these, each test demonstrates a single type of access to the > business_object class instance, for example Test3 just prints the values of > the properties of the first row encountered in the database Result. > > (The Main routine includes all the "STOP"s so that the output does not > become jumbled.) > > Here is the output I get (with some comments in colour): > > ============================= > > ----> Test 1 just creates a BO instance and then destroys it > > BO destructor for Employee (2 references) > > <---- Test 1 complete, explicit object destruction trace should be above > this line > > This demonstrates that the destructor (_free) method is being called for the > explicit $employee=NULL line > > ============================= > > ----> Test 2 creates a BO instance, loads it and then destroys it > > Employee Load got 3 rows > > BO destructor for Employee (2 references) > > <---- Test 2 complete, explicit object destruction trace should be above > this line > > Loading the multiple rows occurs properly and the destruct call works > > ============================= > > ----> Test 3 creates a BO instance, loads it, uses it explicity and then > destroys it > > Employee Load got 3 rows > > Test 3 Ard01 Aaron Ardvaark 1001 45000 > > BO destructor for Employee (2 references) > > <---- Test 3 complete, explicit object destruction trace should be above > this line > > Here we just use the object in a simple manner, again destruct is OK > > ============================= > > ----> Test 4 creates a BO instance, loads it, uses it via WITH and then > destroys it > > Employee Load got 3 rows > > Test 4 Ard01 Aaron Ardvaark 1001 45000 > > <---- Test 4 complete, explicit object destruction trace should be above > this line > > BO destructor for Employee (2 references) > > Here's the first problem, just by using WITH instead of directly referencing > the object variables has caused the _free() method to not be called on > > $employee=NULL (I do see that it is called when the Test4 method exits > though, i.e. the runtime does know it has to free the references somehow. > But why is the explicit destruction ignored? > > ============================= > > ----> Test 5 creates a BO instance, loads it, uses it explicity and then > destroys it (repeat Test3) > > Employee Load got 3 rows > > Test 5 Ard01 Aaron Ardvaark 1001 45000 > > BO destructor for Employee (2 references) > > <---- Test 5 complete, explicit object destruction trace should be above > this line > > This was just included to prove to myself that everything is still ok. > > ============================= > > ----> Test 6 creates a BO instance, loads it, enumerates the set (using FOR > EACH & explicit property name) and then destroys it > > Employee Load got 3 rows > > Test 6 Ard01 Aaron Ardvaark 1001 45000 > > Test 6 Ban01 Bev Banana 1001 48500 > > Test 6 Fri01 Fanny Fricassee 1001 38920 > > <---- Test 6 complete, explicit object destruction trace should be above > this line > > Here the explicit and implicit destructions are both ignored ( and this > causes > > the final error below) > > ============================= > > ----> Test 7 creates a BO instance, loads it, enumerates the set (manually) > and then destroys it > > Employee Load got 3 rows > > Test 7 0 Ard01 Aaron Ardvaark 1001 45000 > > Test 7 1 Ban01 Bev Banana 1001 48500 > > Test 7 2 Fri01 Fanny Fricassee 1001 38920 > > BO destructor for Employee (2 references) > > <---- Test 7 complete, explicit object destruction trace should be above > this line > > In this final test, where I use MoveNext rather than FOR EACH, everything > appears OK. > > ============================= > > WARNING: circular references detected > > _pEmployee (1) > > Employee (1) > > WARNING: 49 allocation(s) non freed. > > When the program exits, I get the circular references problem > > Hopefully, I have packed up the test project correctly and some kind soul > will confirm the above and be able to reply with what it is that I am doing > wrong. > > The only thing I have been able to isolate is that the circular reference > appears the second time that Unmarshall is called from the Persistor _next() > method at line 143. If this call is commented out then the circular > references do not happen. The ingorances of the $employee=NULL still > continue though. > > The test project is a very cut down version of the real dev project, so some > of the constructs used may appear odd, such as the use of dynamic object > creation. Please ignore the use of these as they do make sense in the real > project and have been proven OK in the other (single row) versions of this > design. The issues lie solely with "WITH" (where I cannot see how I have > disturbed it) and with FOR EACH (where I cannot understand what is causing > the circular references). > > Thank you for reading this and many thanks in advance if you could find time > > to help me with this. > > -- > > best regards > > Bruce Bruen > > ------------------------------------------------------------------------------ > Learn how Oracle Real Application Clusters (RAC) One Node allows customers > to consolidate database storage, standardize their database environment, and, > should the need arise, upgrade to a full multi-node Oracle RAC database > without downtime or disruption > http://p.sf.net/sfu/oracle-sfdevnl > _______________________________________________ > Gambas-user mailing list > Gambas-user@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/gambas-user > >
Clearly, gambas miss a way to know the var name where are stored the unfreed ref... i can't find in your code where the free are not done.... -- Fabien Bodard ------------------------------------------------------------------------------ Learn how Oracle Real Application Clusters (RAC) One Node allows customers to consolidate database storage, standardize their database environment, and, should the need arise, upgrade to a full multi-node Oracle RAC database without downtime or disruption http://p.sf.net/sfu/oracle-sfdevnl _______________________________________________ Gambas-user mailing list Gambas-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gambas-user