===== OpenILS Storage Server API Overview ===== The OpenILS Storage server has a very standardized API for retrieving individual objects, searching for objects, and updating, creating and deleting objects. Aproximately 99% percent of the API is automatically generated from the underlying table definitions, and contains about 8,900 methods. Becuase of this I will give a basic overview of the API and explain the storage layout, but will not be listing every single method published by the Storage server. ==== Base Method Naming Structure ==== Methods published by the Storage server follow a simple functional hierarchy for their [[osrf-devel:terms#opensrf_api-name|API Name]]. They are layed out first by thier access types and then by the object type on which they act. Let us take the example of **open-ils.storage.cachable.direct.config.copy_status.batch.retrieve.atomic**, which method can be broken down in this way: * //open-ils.storage// -- **[[osrf-devel:terms#opensrf_api-namespace|API Namespace]]**\\ The [[osrf-devel:terms#opensrf_api-namespace|API Namespace]] in which the method lives. * //.cachable// -- **Access Type**\\ Denotes this method as a cadidate for server-side caching, and informs the user that the method accepts optional [[open-ils_storage_api#optional_result_caching|cache-oriented parameters]]. * //.direct// -- **Access Type**\\ This method acts directly on the underlying storage mechanism, and deals only with [[backend-devel:fieldmapper|Fieldmapper]] objects of the **Fieldmapper::config::copy_status type**. * //.config.copy_status// -- **Object Type**\\ This tells the user what object type this method deals with, in this case **Fieldmapper::config::copy_status**. * //.batch// -- **Action Modifier**\\ In this case, specifying that the method accepts multiple IDs and will return multiple **Fieldmapper::config::copy_status** objects. * //.retrieve// -- **Action**\\ This is the action to be performed. * //.atomic// -- **Method Variant**\\ Because the base version of this method is streaming, an **atomic** variant is supplied by the system for use by stateless clients. ==== The Creeping C.R.U.D. ==== The basic actions for each object type maintained by the Storage server are //create//, //retrieve//, //update// and //delete//. Thus, C.R.U.D. The Storage server also defines the //batch// action modifier for each of these actions. In addition, for Storage Drivers that can support it, there is a hook available for plugging in a //mass_delete// action for fast removal of many objects. All of these methods live inside the //.direct// access type branch of the //open-ils.storage// [[osrf-devel:terms#opensrf_api-namespace|API Namespace]]. The //.retrieve// and //.batch.retrieve// methods also have a //.cachable// version available. Here are some examples of the CRUD interface: * open-ils.storage.direct.permission.usr_grp_map.create * open-ils.storage.direct.permission.usr_perm_map.batch.create * open-ils.storage.direct.permission.usr_perm_map.batch.retrieve * open-ils.storage.cachable.direct.permission.usr_perm_map.batch.retrieve * open-ils.storage.cachable.direct.permission.usr_perm_map.batch.retrieve.atomic * open-ils.storage.direct.permission.usr_grp_map.update * open-ils.storage.direct.permission.usr_grp_map.batch.update * open-ils.storage.direct.permission.usr_perm_map.delete * open-ils.storage.direct.permission.usr_perm_map.batch.delete There is also an **all** Method Variant for the **retrieve** method, but it is only available on certain object types. The reason for this is that a **retrieve.all** against large lists of objects would be //very// expensive. The object types for which **retrieve.all** is available are: * config.metabib_field * config.standing * config.identification_type * config.copy_status * actor.org_unit * actor.org_unit_type * actor.profile * asset.copy_location === Return types === * **.create** -- Returns the **id** of the new object * **.batch.create** -- Returns the number of objects created * **.retrieve** -- Returns the [[backend-devel:fieldmapper]] object identified by the **id** passed in * **.batch.retrieve** -- Returns a stream of [[backend-devel:fieldmapper]] objects identified by the list of **id**s passed in * **.retrieve.all** -- Returns a stream of **ALL** [[backend-devel:fieldmapper]] objects of that type * **.update** -- Returns **1** on success, **0** on failure * **.batch.update** -- Returns the number of objects updated * **.delete** -- Returns **1** on success, **0** on failure * **.batch.delete** -- Returns the number of objects deleted * **.mass_delete** -- Returns **1** on success, **0** on failure ==== Searching ==== In addition to the CRUD interface's **retrieve** method, there is an API for searching when you don't know the id of the object you want. The base search interface is set up thusly: * open-ils.storage[//.{access_type}//].direct.{object_type}.{search_type}[//.{property}//] As you can see, the search interface plays very well with the CRUD interface. In fact, everything up to the **{search_type}** is the same. The **{search_type}**s available to all drivers are: * **.search**\\ The argument to this function is a hash ([[http://www.crockford.com/JSON/index.html|JSON]] Object) where the keys are the property names and the values are the property values. This will perform an ANDed equality search based on all properties passed in. * **.search.//property//**\\ The argument to this function is the value to search for on the named **//property//**. Use this when you want to search a single property, as it is faster and the method name makes it easier to remeber what your code is doing. * **.search_like**\\ This works exactly like **search**, but performs a text search using **%** as the "any string" wildcard and **_** as the "one character" wildcard. * **.search_like.//property//**\\ This works exactly like **search.//property//**, but performs a text search using **%** as the "any string" wildcard and **_** as the "one character" wildcard. For Storage Drivers that support them, such as the [[http://postgresql.org|Postgres]] driver, there are three more search types available: * **.search_ilike** (and **.search_ilike.//property//**)\\ Provides a case insensitive version of **.search_like**. * **.search_regex** (and **.search_regex.//property//**)\\ Provides POSIX regular expression searching. * **.search_fts** (and **.search_fts.//property//**)\\ Provides Driver specific Full Text searching.((This will eventually use the generic [[http://open-ils.org/cgi-bin/viewcvs.cgi/ILS/Open-ILS/src/perlmods/OpenILS/Application/Storage/FTS.pm|OpenILS::Application::Storage::FTS]] infrastructure to allow Driver agnostic searches.)) * **.search_where**\\ Provides a more complex but flexible search interface with the same syntax as [[http://cpan.uwinnipeg.ca/htdocs/Class-DBI-AbstractSearch/Class/DBI/AbstractSearch.html|Class::DBI::AbstractSearch]]. === Return types === All **search**-type methods return a stream of [[backend-devel:fieldmapper]] objects that match the requested criteria. If you would perfer a single return value of an array containing the objects then simply use the **.atomic** version of the method, as in: open-ils.storage.cachable.direct.actor.user.search_regex.family_name.**atomic** ==== Optional Result Caching ==== The entire **.direct** retrieval and search interface trees, as well as some of the [[open-ils_storage_api#specialized_methods|specialized]] methods, support the **.cachable** access modifier. This alternate [[osrf-devel:terms#opensrf_api-name|API Name]] accepts an addition set of parameters that control the caching of the results from the query. Queries are identified using: - The [[osrf-devel:terms#opensrf_api-name|API Name]] of the method that is called - All parameters other than a **limit** or **offset** listed directly on the request __Paramters that relate directly to the cachable interface__ * **cache_page_size**\\ Default: 1000\\ This controls how much of the total result is held in the cache at any given time * **timeout**\\ Default: 7200 seconds (2 hours)\\ Specifies how long the contents of each cache page will exist in cache. __Paramters that the cachable interface uses directly__ * **limit**\\ Default: 100 * **offset**\\ Default: 0 When written as a direct parameter, as in * open-ils.strorage.cachable.direct... '17', **'limit', '10', 'offset', '40'** the **cachable** interface uses these for returning a (possibly cached) portion of the related **cache page**. The **cache page** is determined by finding the overlapping window of **cache_page_size**, **limit** and **offset**, and checking for a matching cache page.