Hi Kev

Hope you are keeping well

Have you tried

write $System.OBJ.UnCompile("*") from terminal? - replace the "*" with more specific wild card

write $System.OBJ.Delete("class name") 


write $System.OBJ.DeletePackage("package name")

I had similar issues -but difficult to pin down


Hi Sabarinathan

I use pdfPrintCmd - see http://www.verypdf.com/app/pdf-print-cmd/index.html

it's not free but I have had no issues with it over many years of use

The idea is:
a. Write out the pdf to a directory
b. set xResult=$zf(-1, "print command exe")

The great advantage is that it has command line options that control margins, double sided etc etc

Also it can be run in the background - this is very useful when doing batches of pdf where creating the pdf using FOP can take several seconds - the idea is
a. scan the data via SQL
b. create the pdf
c. use printCmd to send to a printer
To give you an idea of it working I have a client that produces around 50 multi page passport a day - the printing takes around 1 hour - it's set going as a Cache background job and the printer just chugs away.


FAO Mike

Hi Mike

You ask some very good questions!

It's been a few (10+) years since I did some metrics on Cache performance - working on it now (when I have time)

I will publish the results here

But my initial findings are much what I said - given enough memory (8Gb allocated to global buffers) it don't much matter - so a 200Mb global (10,000,000 rows with links to 2 other tables) I can't see any significant diff in the performance between parent/child or foreign key - or bitmap re normal indicies.

going to try it with 50,000,000 and limit the amount of memory allocated to global buffers

Watch this  space


FAO Scott

Hi Scott

Sorry it's taken me so long to get back to you re real world parents and children

It's the example you gave of Cache relationships - and I was a bit quick fire with my answer - sorry!. 

Please let me expand.....

Real world parents and children is an interesting problem and a simple solution that you described is *not* the way I would model it!!

this is regardless of the actual implementation - eg parent/child or foreign keys etc etc

= =

If i wanted to model family trees I would have a class "Person" and another class "PersonRelationship" - the second of these would have links to two instances in the "Person" table

Something like (in relationships rather than foreign keys - but that's implementation rather than the oo design)

PS - I am typing on the fly - so there may be errors!!!!

= =

Class Person as %Persistent

Relationship rRelatedPerson as PersonRelationship [cardinality="many", inverseproperty="rLink"]

property Name as %string;

property pDoB as %Date;


And then PersonRelationship as %Persistent

Relationship1 as Person[cardinality="one", inverseproperty rRelatedPerson]

Relationship2 as Person[cardinality="one", inverseproperty rRelatedPerson]

property RelationshipType as SomeLookupTable;


The SomeLookupTable would describe (in words) the relationship eg "Son Of" and "Farther Of"

For me this has some beauty
You can...

  • Construct a family tree of infinite depth both forwards and backwards
  • Use recursive SQL programming to construct the tree
  • a "child" can have multiple links - eg "gene father" and "step father"
  • The record is complete - eg a woman might have a "gene father" then a "step father" and then go back and be linked to the same "gene father" (life happens)
  • It can also model surrogate parents via AI fathers or surrogate mothers or same sex relationships
  • It can be extended to, say, pets

Some care has to be taken in the database insert/amend eg

  • avoid recursive relationships eg a Person is her own grandmother is not physically possible
  • a person cannot have the same mother and father (well with AI and embryo manipulation tailoring this *may* become a reality - but no problemo the model will still work)

= =

Hope this is clear and of interest - if you need any more info please ask

= =

PS - I was involved around 30 years ago in computing an "In Breeding Coefficient" for rare breeds (think small populations of endangered species in zoos) the aim was to give a metric on how inbred an individual was - small populations where is was common for both grandparents to be the same individual - the logic was intense to get a metric - you could have the case where the same individual was all of the both grandfathers and all 4 great grandfathers- not so good for preserving the gene pool !



Thinking about this the first point is do the children get added to or amended - if it's a lot (eg with case notes) then that will lead to mega block splitting as the data size for the whole record grows

OTOH - if it's an invoice that (essentially) never changes then it's fixed and p/c is cools

==  ==
Apart from the bit map indices only working for integer ID's - do if you really have squillions of products that you need to process then one-many must be the business solution so it gives the performance of

   select sum(qtySold) from invoiceLines where ProductID=123


FAO Mike Kiddow

All of us Cache gurus are getting carried away with the internals and very deep design concepts that rely on an in-depth knowledge of how Cache works.....

I guess you do not fully follow what we are discussing - (sorry not being dismissive at all) - it's just that me, Wolf, Dan Otto, Kyle are just being super-dooper Cache egg heads.

Bottom line is...

That for any reasonable sized database (ie less than <~10,000,000) rows on a modern server with adequate memory - it don't much matter!!! Cache will do the biz.

= =
But please note that the example from Scott is not correct...
Having real children with real parents then the parent-child relationship is incorrect on many levels - because as I said before "a parent can die" and you don't want the children records to disappear!!!!

In case I would have (as a first pass) a class "people" and another class "people relationships" which links different instances of people with each other

= =

oo methodology seems intuitively easy to understand - but it's not
and on top of that is the pros and cons of Cache performance considerations that we have been discussing

But give it a go
As I said it don't much matter unless you are in serious terabyte country


Hi Wolf

Long time no meet !!!

This is such an interesting conversation...

And it all depends on on the actuality - if you have a parent with a sqillion children - then the answer to p/c performance is not so good

Also if you have a business object where the many side are constantly added to - eg a patients lab results- again different - leads to block splitting and a bunch of pointer blocks having to be loaded into memory


my business case argument is with an Invoice header and invoice lines then parent/child v one/many is the most efficient - they (really never change) so no index bock splitting

But I do take Dan's and Otto's comment about bitmaps only doing integer ID's

= =

Tell you a story..

around 12 tears ago I was involved with a client with a 1.2Tb database - I was critisised by the in-house staff for IT staff for using naked global references in one module - blab blah - but it was 2% faster than full global references and  in a tight loop 2%  meant 30 mins off the processing time

= =

Having said that - I *will* be trying out one-many with a cascade delete


Hi Kyle

Thanks for your excellent comment

I agree - sort of....

Bit it's a balance (as always) between loading buffers - it may be the case that there is an occasional need to just grab the dates - but if it's only a 10% (say) need whereas the 90% need is to display/process the header and the lines together then, for me, the 90% need should win out.

Also if the dates (or whatever) are indexed then a selection on a date range (say) will only select the required rows from the index.

= =

But as I said before - it depends on the size of the system - my clients have modest needs (maybe 3 million rows max) and with a 64Gb machine all/most of the blocks are in memory anyway smiley


But thanks for the thoughts - I will certainly start looking at one-many with a cascade delete