module Lite3 # This module provides some basic access to the underlying # `Sequel::Database` objects used by `Lite3::DBM` to actually store # and retrieve data. # # The only thing you need to care about is that if your process # forks, you *must* invoke `Lite3::SQL.close_all` before forking the # process. Otherwise, it will clone the connection and could lead # to database corruption. # # More details: # # `Lite3` maintains a pool of private handle objects (private class # `Lite3::Handle`) which in turn manage the `Sequel::Database` # objects that actually do the work. There is one handle per # SQLite3 database file; since each `DBM` represents one table in a # SQLite3 file, multiple `DBM` objects will use the same handle. # # Handle objects can themselves close and replace their # `Sequel::Database` objects transparently. # # The underlying system keeps track of which `DBM` objects reference # which files and will close a file's `Sequel::Database` when all # of the `DBM`s using it have been closed. (It does **not** handle # the case where a `DBM` object remains open and goes out of scope; # that object will be kept around for the life of the process.) # # Mostly, you don't need to care about this. However, it affects # you in two ways: # # 1. Transactions are done at the file level and not the table level. # This means that you can access separate tables in the same # transaction, which is a Very Good Thing. # # 2. You can safely fork the current process and keep using existing # `DBM` objects in both processes, provided you've invoked # `close_all` before the fork. This will have closed the actual # database handles (which can't tolerate being carried across a # fork) and opens new ones the next time they're needed. # # If you find yourself needing to be sure that you don't have any # unexpected open file handles (e.g. before forking or if you need # Windows to unlock it), you should call `close_all`. # # Otherwise, it's safe to ignore this stuff. # This module provides some basic, consistent access to the # underlying database library(es) (currently `sequel`). module SQL # Tests if the underlying database libraries are threadsafe. # # (Currently, it always returns true, since Sequel does that for # us.) def self.threadsafe? return true end # Disconnect and delete all database handles and associated # metadata that are no longer needed (i.e. because their # corresponding `DBM`s have been closed or reclaimed). # # Returns a hash mapping the path to each open database file to # the number of live DBM objects referencing it. (Note that DBM # objects that have gone out of scope but are not yet finalized # count as "live"; as a result, this will differ across Ruby # implementations due to differing garbage collector semantics.) # # You normally won't need to explicitly call this, but it's # useful for testing and debugging. def self.gc() return HandlePool.gc; end # Close and remove the underlying database connections. This does # not invalidate existing `Lite3::DBM` objects; they will recreate # the connections when needed. # # The main use for this is for safely forking the current process. # You should call this just before each `fork` to avoid potential # corruption from duplicated database handles. # # This **should not** be called while a database operation is in # progress. (E.g. do **not** call this from the block of # `DBM.each`.) def self.close_all() return HandlePool.close_all end end end