Monday, November 08, 2010 at 12:01 AM.
system.verbs.apps.Filemaker.examples.transactions
<<These examples show how to use transactions with Filemaker <<Filemaker is not threaded and can not handle multiple script interactions at <<the same time. Since scripting Filemaker often assumes that the database <<was left in a certain state (ie a found set, after a find), you want a way <<to make sure that Filemaker ignores messages from other scripts while the <<current script is interacting with it. <<There are two ways to limit interaction with Filemaker, transactions and semaphores. ----------------------------------------------------------------------------; <<Transactions <<Transactions are Filemaker's own way of limiting interaction. <<A transaction locks Filemaker from Filemaker and will limit interaction from any <<Apple Event system (Frontier or Applescript). This is more secure but is just a bit <<slower as it requires events to begin and end the transaction. << <<You need to use some special constructions if you want to make repeated <<attempts to begin a transaction, see the example below. << <<The ONLY way to end a transaction is from a script or by quitting and relaunching Filemaker! bundle { <<using transactions try { local(transID=beginTransaction()); <<beginTransaction() returns a number <<event transactions are an Apple Event device <<all statements until "setEventTransaction" carry an implied ID SetEventTransactionID (transID); bundle { <<Filmaker statements go here delete(request[all]); create(request,"requestData",0,endOf(database[1].layout[1])); find(window[1]); local(foundSet=get(document[1].layout[1].record[all]))}; <<"document" contains the found set EndTransaction (); <<the transaction ID is passed to filemaker since we are still in an event transaction SetEventTransactionID (0)} else { <<be sure to end the transaction no matter what EndTransaction (); SetEventTransactionID (0); scriptError(tryError)}}; loop { <<using transactions with repeated attempts <<you could modify this to only try 10 times, or for a certain amount of time try { local(transID=beginTransaction()); SetEventTransactionID (transID); bundle { <<Filmaker statements go here delete(request[all]); create(request,"requestData",0,endOf(database[1].layout[1])); find(window[1]); local(foundSet=get(document[1].layout[1].record[all]))}; <<"document" contains the found set EndTransaction (); SetEventTransactionID (0); break} <<end the loop else { if tryError contains "transaction" { clock.waitseconds(1)} <<or <<sys.systemTask() else { <<be sure to end the transaction no matter what EndTransaction (); SetEventTransactionID (0); scriptError(tryError)}}}; ---------------------------------------------------------------------------; <<Semaphores <<Semaphores provide a way to lock a value within Frontier that other scripts can check <<the status of. When a script trys to lock a semaphore it will try for a specified amount of <<time and then result in an error. The semaphore will remain locked until unlocked, but may <<be unlocked from any script- not only the one that locked it. This can be useful if you want <<different scripts to work together, with one script locking the semaphore and another <<unlocking it (ie script a performs a find, script b gets the records). << <<Semaphores exist only within Frontier and do not prevent Filemaker from interacting <<with other applications, so if other applications are sending Apple Events to Filemaker <<use transactions. << <<Since locking a semaphore will try for a certain amount of time, no special construct is needed bundle { <<using Semephores try { semaphores.lock("filemaker",1800)} <<#ticks to try and lock the semaphore else { scriptError("The Database was busy for too long!")}; try { <<was able to lock the semaphore within 1800 ticks bundle { <<Filmaker statements go here delete(request[all]); create(request,"requestData",0,endOf(database[1].layout[1])); find(window[1]); local(foundSet=get(document[1].layout[1].record[all]))}; <<"document" contains the found set semaphores.unlock("filemaker")} else { <<be sure to unlock the semaphore in case of an error semaphores.unlock("filemaker"); scriptError(tryError)}}
This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.