| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
- <HTML>
- <HEAD>
- <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=iso-8859-1">
- <TITLE></TITLE>
- <META NAME="GENERATOR" CONTENT="OpenOffice 4.1.1 (Unix)">
- <META NAME="CREATED" CONTENT="0;0">
- <META NAME="CHANGEDBY" CONTENT="Alex Peshkoff">
- <META NAME="CHANGED" CONTENT="20141113;13283500">
- <STYLE TYPE="text/css">
- <!--
- @page { margin: 0.79in }
- P { margin-bottom: 0.08in }
- -->
- </STYLE>
- </HEAD>
- <BODY LANG="en-US" DIR="LTR">
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in"><FONT SIZE=4>Providers.</FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in"><BR>
- </P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in"><FONT SIZE=4>Providers
- architecture is definitely one of key features of Firebird 3. But to
- be precise this is far not new feature - providers existed in
- Firebird's predecessors long ago, and in 'deeply hidden' form are
- present in any Firebird version. Initially providers were introduced
- to deal with a task which is currently well known to be performed by
- ODBC, ADO, BDE, etc. They were needed to make it possible to access
- different database engines using single external interface. But later
- providers architecture (known that time as OSRI - Open Systems
- Relational Interface) also showed itself as very efficient for
- supporting mix of old and new database formats (different major ODS)
- at single server and having mixed connections to local and remote
- databases. Implemented in Firebird 3 providers make it possible to
- support all this modes (remote connections, different ODS databases,
- foreign engines) and also providers chaining (when some provider is
- using callback to standard API when performig an operation on
- database).</FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in"><FONT SIZE=4>Main
- element of providers architecture is YValve. On initial attach (or
- create) database call it scans the list of known providers and calls
- them one by one until tried provider completes requested operation
- successfully. For already established connection appropriate provider
- is called at once with almost zero overhead. Lets take a look at some
- samples of YValve operation when it selects appropriate provider at
- attach stage.</FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in"><BR>
- </P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in"><FONT SIZE=4>Next
- samples are with default configuration, which contains 3 providers:
- <B>Remote</B> (establish network connection), <B>Engine14</B> (main
- database engine) and <B>Loopback</B> (force network connection to
- local server for database name without explicitly given network
- protocol).</FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in"><FONT SIZE=4>When
- one attaches to database called <I>RemoteHost:dbname</I> (TCP syntax)
- or <I>\\RemoteHost\dbname</I> (NetBios) <B>Remote</B> provider
- detects explicit network protocol syntax and (being the first
- provider in the list) at once redirects such call to <I>RemoteHost</I>.
- That's how typical client configuration works.</FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in"><FONT SIZE=4>When
- database name does not contain network protocol (just <I>dbname</I>)
- <B>Remote</B> provider rejects it and <B>Engine14</B> provider comes
- to stage. It tries to open <I>dbname</I> – and in case of
- success we get embedded connection to the database. Pay attention –
- we do not need special embedded library to have embedded connection,
- standard client loads appropriate provider and becomes embedded
- server.</FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in"><FONT SIZE=4>But
- what happens if engine returned an error on an attempt to attach to
- database? Certainly, if file for database to be attached does not
- exist there is no interest at all, but embedded connection may also
- be impossible when user, attaching to it, does not have enough rights
- to open database file. This is normal case if database was not
- created by that user in embedded mode or if he was not explicitly
- given OS rights for embedded access to databases on given box.
- Moreover, setting access rights in such a manner is a requirement for
- correct superserver operation. So after failure of <B>Engine14</B> to
- access database <B>Loopback</B> provider is attempted for an attach.
- It does not differ much from <B>Remote</B>, but tries to access
- database <I>dbname</I> on a server running on local host. On windows
- XNET protocol (also known as local connection) is used for it, posix
- systems prepend <I>dbname</I> with <I>localhost:</I> and use TCP
- connection. In case of success remote-like connection is established
- with database no matter that it's located on a local machine.</FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in"><BR>
- </P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in"><FONT SIZE=4>Certainly
- use of providers is not limited with this 3 standard ones. Firebird 3
- does not support pre-ODS 12 databases. But in FB 3 – not in
- alpha1 – we plan to have additional provider to access old (ODS
- from 8 to 11) format databases. Removing old ODS support from engine
- helps to make it's code simpler and a bit faster. Taking into an
- account that this faster sometimes takes place in performance
- critical places (like search of a key in an index block) avoiding old
- code and related branches makes Firebird work really faster.
- Providers architecture at the same time makes it possible to access
- old databases when changing Firebird version.</FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in"><FONT SIZE=4>The
- strong feature of providers architecture is ability for user to add
- his own providers to server and/or client. You may be surprised –
- what else except remote connection is needed on client? But do not
- forget about providers chaining. Imagine a case when database is
- accessed via very slow network connection – something like 3G
- or even worse GPRS. A strong desire to cache rarely changed but
- rather big tables on a client is first that comes on my mind to make
- it work faster. Such systems were really implemented, but to do it
- one had to rename fbclient to something arbitrary and load it into
- own library called fbclient. This makes it possible to use standard
- tools to access the database at the same time caching required
- tables. Works, but solution is obviously far from ideal. With
- providers architecture instead libraries renaming one just adds local
- caching provider which can use any method to detect connections to it
- (something like <I>cache@</I> prefix in the beginning of database
- name or whatever else you choose). In this sample when database name
- <I>cache@RemoteHost:dbname </I><SPAN STYLE="font-style: normal">is
- used caching provider accepts such connection and invokes YValve once
- again with traditional database name </SPAN><I>RemoteHost:dbname</I><SPAN STYLE="font-style: normal">.
- But when user later performs any call to his database caching
- provider gets control on it before </SPAN><SPAN STYLE="font-style: normal"><B>Remote</B></SPAN>
- <SPAN STYLE="font-style: normal">one and for locally cached table can
- avoid calls to remote server.</SPAN></FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in; font-style: normal">
- <FONT SIZE=4>Using chaining one can implement a lot of other useful
- things like database replication without need in triggers - just
- repeat same calls for replication host when (for example) transaction
- is commited. In this case chaining provider is installed on server,
- not on client, and no modification of command line is needed at all.
- To avoid cycling when performing callback to YValve at attach time
- such provider can modify list of providers using isc_dpb_config
- parameter in DPB – for details please see README.configuration.
- BTW, same technique may be used at client too.</FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in; font-style: normal">
- <FONT SIZE=4>And certainly we should not forget about ability to
- access foreign DB engines using providers. This looks strange at the
- first glance when a lot of other tools performing this task already
- exist. But let's take into an account ability to access other
- Firebird databases using EXECUTE STATEMENT. With provider to ODBC or
- other common tool to access various data sources it's getting
- possible to directly access from procedures and triggers (using
- mentioned EXECUTE STATEMENT) data from almost any database, at least
- any, having a driver in chosen access tool. Certainly it's possible
- to have a provider to access some particular type of foreign database
- engine if one wants to avoid ODBC layer for some reason. </FONT>
- </P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in; font-style: normal">
- <FONT SIZE=4>Description of how to access databases using providers
- API is present in the interfaces part of Firebird examples and
- therefore there is no need repeating it here. Moreover, except
- IStatement (interface used for execution of SQL operators) and
- IEvents (works with Firebird events) all functions in interfaces are
- similar to old API.</FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in"><BR>
- </P>
- <P STYLE="margin-bottom: 0in"><FONT SIZE=4>Questions and answers.</FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in; font-style: normal">
- <FONT SIZE=4>Q. Interfaces and providers are probably very good, but
- I have old task written using plain functions API and for a lot of
- reasons I can't rewrite it in the nearest future. Does it mean I have
- problem migrating to Firebird 3?</FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in; font-style: normal">
- <FONT SIZE=4>A. Definitely no problems. Old API is supported for
- backward compatibility in Firebird 3 and will be supported in future
- versions as long as people need it. Moreover, since Firebird 3 one
- can access from XSQLDA API records longer than 64Kbytes.</FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in; font-style: normal">
- <FONT SIZE=4>Q. And what about performance when using old API?</FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in; font-style: normal">
- <FONT SIZE=4>A. Functional API is implemented as a very thin layer
- over interfaces. Code in most case is trivial – convert passed
- handles to pointers to interfaces (this step was always present but
- called 'handles validation') and invoke appropriate function from
- interface. The only a bit more complex place are functions that
- execute SQL operator and fetch data from it. But SQLDA and related to
- it data moves has never been the most fast place of functional API,
- it was one the reasons to have new API and logic between new and old
- API does not add much to that old overhead.</FONT></P>
- <P STYLE="text-indent: 0.39in; margin-bottom: 0in"><BR>
- </P>
- </BODY>
- </HTML>
|