Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Artifact ID: | caabe653648087d485c9f9c2b0623abffd9dc3f4 |
---|---|
Page Name: | mod_spatialite |
Date: | 2014-06-25 21:34:20 |
Original User: | sandro |
Parent: | 819fa85dc3aac249ed93e2effb2a1550be0d2839 (diff) |
Next | 74e891a6db2413b62d2ef9882146e7429cf0acc4 |
Content
back to 4.2.0-doc
Dynamically loading SpatiaLite as an extension module
Theoretical foundations
Speacking in rigorous technical terms, SpatiaLite simply is an extension to SQLite.Consequently we are strictly required to deploy some appropriate mechanism allowing to load both binary libraries (libsqlite3 and libspatialite) then properly registering within SQLite3 the many extended Spatial SQL functions implemented by SpatiaLite.
A further compication should be taken in proper debt; libspatialite isn't a simple stand-alone self-contained library and depends on several further libraries (libgeos, libproj, libxml2 and so on).
There are several possible alternative paths leading to this final goal:
- using static linkage: a straighforward solution avoiding many subsequent headhaches related to installation and run-time configuration.
Following this approach a single monolithic fat executable internally containing all required binary code will be created at build time; this monolithic executable will have no external dependencies at all, thus radically simplifying any installation task.
Such strategy nicely works in the case of stand-alone self-contained apps (e.g. both spatialite.exe and spatialite_gui.exe Windows binaries are usually built this way).
Unhappily this elementary simple solution doesn't fit well in Linux and Unix-like environments; and even worst often directly conflicts with the internal architecture supported by many language connectors or by other complex frameworks (as e.g. is QGIS). - using shared libraries (aka DLLs on Windows).
This second approach will carefully avoid to link once for all a monolithic executable; at the opposite, each single code component will be shipped as an autonomous individual member, and only at run-time all components will be finally bound together.
The good new is that this way each library/component will be (hopefully) installed only once on your system, and that every executable depending on that library will load exactly the same binary code, thus granting a robust overall consistency.
The bad new is in that if a single required component couldn't be loaded at run-time (for any possible reason) the executable as a whole will fail to run.
To make things even worst, this schema works nicely on Linux, Unix and Mac OS X; but on Windows it's plagued by many serious issues (the infamous DLL hell). - using real dynamic linkage aka late binding (which hasn't to be confused with simply using shared libraries).
Following this third approach an extension module could be selectively loaded or not and the actual action will be activated only at run-time. If for any reason the main executable fails to load an eventual extension module, it will still continue to work by simply ingoring every optional feature requiring the failing module.
As a direct consequence, an executable built this way can theoretically growth to the infinite, and can practically ignore any specific detail about the optional features supported by its extensions; this corresponds to the so called plug-in architecture.
Happily enough SQLite3 fully supports this more advanced mechanism; and this option is widely supported by many language connectors.
How it works
libsqlite3 has the capability to dynamically load extension modules. This feature is available as a C-language API, but is avaibles as a special SQL function as well:SELECT load_extension('mod_spatialite');This SQL function make elementary simple (and language independent) the problem of loading any possible extension; you are simply expected to execute a rather trivial SQL statement in order to load an external extension when it's actually required.
Loadable extension anathomy:
- any SQLite extension module is expected to declare a conventional interface.
Except for this, any SQLite's own extension simply is an ordinary shared library or DLL as any other. - a real extension module will never explicitly depend on SQLite3, because the following actions will be automatically taken by SQLite3 when loading:
- all SQL fuctions defined/supported by the extension will be added to the standard list; and eventually an extension could ever overload any pre-defined SQL function directly defined by SQLite3.
- that's not all; SQLite3 will implicitly pass to the extension a mirror copy of its own APIs: this will ensure that exactly the same code will support both the SQLite's own core and the extension, and will effectively avoid any possible conflict between them.
Common failure causes:
- if the expected conventional interface isn't correctly declared by the shared library being loaded, then SQLite3 will simply assume that it's not a valid extension module.
And consequently will refuse to load the module without any other consequence (except may be printing some appropriate error message). - a more obvious failure cause could be the one to attempt loading a not existing module (or possibly, a module whom actual address couldn't be resolved by applying the standard system-dependent seach rules).
- finally, the module could effectively exists and could correctly declare a valid conventional interface. Anyway, if the corresponding shared library has further dependecies some broken link could possibly forbid a succesful loading.
- the last hill-fated combination: SQLite3 is a strongly configurable component. If for any highly opinable choice your system packages had decided to disable at all the extension module mechamism you'll then never be able to load any extension. Full stop. (anyway you'll probably be able to switch to some more reasoble / less paranoid distribution).
What's new in mod_spatialite
You'll probably be already accustomed to load SpatiaLite as a dynamic extension; but any previous version before 4.2 made no real distinction between loadable modules and general-purpose shared libraries.As we painfully learned by direct on-the-field experience, this apparently simpler configuration caused lot of troubles: instabilities, sudden crashes and so on. Making a clearer distinction between a general-purpose shared library and a pure loadable module seems to be the definitive solution.
Exactly here is the radical innovation introduce starting since version 4.2; now SpatiaLite is distributed in two alternative flavors:
- libspatialite (.so, .dll, .dylib and so on): a genuine classic shared library.
It will always depend on some external libsqlite3, and is uniquely intended to be used by stand-alone applications (such as e.g. spatialite or spatialite_gui
You'll never be able to succesfully load this libspatialite shared library as a dynamic extension via the SELECT load_extension mechanism, simply because it doesn't declare the required conventional interface.
- mod_spatialite (.so, .dll, .dylib and so on): this is simply intended as pure loadable module lacking any explicit SQLite3 dependency.
You never be able to directly link this mod_spatialite shared library following the classic way, because it doesn't declare any external link symbol except that the conventional interface. The unique possible way to load and activate this module is by calling a SELECT load_extension SQL statement.
back to 4.2.0-doc