@@ -5700,274 +5700,6 @@ defaultNoticeProcessor(void *arg, const char *message)
5700
5700
5701
5701
</sect1>
5702
5702
5703
- <sect1 id="libpq-row-processor">
5704
- <title>Custom Row Processing</title>
5705
-
5706
- <indexterm zone="libpq-row-processor">
5707
- <primary>PQrowProcessor</primary>
5708
- </indexterm>
5709
-
5710
- <indexterm zone="libpq-row-processor">
5711
- <primary>row processor</primary>
5712
- <secondary>in libpq</secondary>
5713
- </indexterm>
5714
-
5715
- <para>
5716
- Ordinarily, when receiving a query result from the server,
5717
- <application>libpq</> adds each row value to the current
5718
- <type>PGresult</type> until the entire result set is received; then
5719
- the <type>PGresult</type> is returned to the application as a unit.
5720
- This approach is simple to work with, but becomes inefficient for large
5721
- result sets. To improve performance, an application can register a
5722
- custom <firstterm>row processor</> function that processes each row
5723
- as the data is received from the network. The custom row processor could
5724
- process the data fully, or store it into some application-specific data
5725
- structure for later processing.
5726
- </para>
5727
-
5728
- <caution>
5729
- <para>
5730
- The row processor function sees the rows before it is known whether the
5731
- query will succeed overall, since the server might return some rows before
5732
- encountering an error. For proper transactional behavior, it must be
5733
- possible to discard or undo whatever the row processor has done, if the
5734
- query ultimately fails.
5735
- </para>
5736
- </caution>
5737
-
5738
- <para>
5739
- When using a custom row processor, row data is not accumulated into the
5740
- <type>PGresult</type>, so the <type>PGresult</type> ultimately delivered to
5741
- the application will contain no rows (<function>PQntuples</> =
5742
- <literal>0</>). However, it still has <function>PQresultStatus</> =
5743
- <literal>PGRES_TUPLES_OK</>, and it contains correct information about the
5744
- set of columns in the query result. On the other hand, if the query fails
5745
- partway through, the returned <type>PGresult</type> has
5746
- <function>PQresultStatus</> = <literal>PGRES_FATAL_ERROR</>. The
5747
- application must be prepared to undo any actions of the row processor
5748
- whenever it gets a <literal>PGRES_FATAL_ERROR</> result.
5749
- </para>
5750
-
5751
- <para>
5752
- A custom row processor is registered for a particular connection by
5753
- calling <function>PQsetRowProcessor</function>, described below.
5754
- This row processor will be used for all subsequent query results on that
5755
- connection until changed again. A row processor function must have a
5756
- signature matching
5757
-
5758
- <synopsis>
5759
- typedef int (*PQrowProcessor) (PGresult *res, const PGdataValue *columns,
5760
- const char **errmsgp, void *param);
5761
- </synopsis>
5762
- where <type>PGdataValue</> is described by
5763
- <synopsis>
5764
- typedef struct pgDataValue
5765
- {
5766
- int len; /* data length in bytes, or <0 if NULL */
5767
- const char *value; /* data value, without zero-termination */
5768
- } PGdataValue;
5769
- </synopsis>
5770
- </para>
5771
-
5772
- <para>
5773
- The <parameter>res</> parameter is the <literal>PGRES_TUPLES_OK</>
5774
- <type>PGresult</type> that will eventually be delivered to the calling
5775
- application (if no error intervenes). It contains information about
5776
- the set of columns in the query result, but no row data. In particular the
5777
- row processor must fetch <literal>PQnfields(res)</> to know the number of
5778
- data columns.
5779
- </para>
5780
-
5781
- <para>
5782
- Immediately after <application>libpq</> has determined the result set's
5783
- column information, it will make a call to the row processor with
5784
- <parameter>columns</parameter> set to NULL, but the other parameters as
5785
- usual. The row processor can use this call to initialize for a new result
5786
- set; if it has nothing to do, it can just return <literal>1</>. In
5787
- subsequent calls, one per received row, <parameter>columns</parameter>
5788
- is non-NULL and points to an array of <type>PGdataValue</> structs, one per
5789
- data column.
5790
- </para>
5791
-
5792
- <para>
5793
- <parameter>errmsgp</parameter> is an output parameter used only for error
5794
- reporting. If the row processor needs to report an error, it can set
5795
- <literal>*</><parameter>errmsgp</parameter> to point to a suitable message
5796
- string (and then return <literal>-1</>). As a special case, returning
5797
- <literal>-1</> without changing <literal>*</><parameter>errmsgp</parameter>
5798
- from its initial value of NULL is taken to mean <quote>out of memory</>.
5799
- </para>
5800
-
5801
- <para>
5802
- The last parameter, <parameter>param</parameter>, is just a void pointer
5803
- passed through from <function>PQsetRowProcessor</function>. This can be
5804
- used for communication between the row processor function and the
5805
- surrounding application.
5806
- </para>
5807
-
5808
- <para>
5809
- In the <type>PGdataValue</> array passed to a row processor, data values
5810
- cannot be assumed to be zero-terminated, whether the data format is text
5811
- or binary. A SQL NULL value is indicated by a negative length field.
5812
- </para>
5813
-
5814
- <para>
5815
- The row processor <emphasis>must</> process the row data values
5816
- immediately, or else copy them into application-controlled storage.
5817
- The value pointers passed to the row processor point into
5818
- <application>libpq</>'s internal data input buffer, which will be
5819
- overwritten by the next packet fetch.
5820
- </para>
5821
-
5822
- <para>
5823
- The row processor function must return either <literal>1</> or
5824
- <literal>-1</>.
5825
- <literal>1</> is the normal, successful result value; <application>libpq</>
5826
- will continue with receiving row values from the server and passing them to
5827
- the row processor. <literal>-1</> indicates that the row processor has
5828
- encountered an error. In that case,
5829
- <application>libpq</> will discard all remaining rows in the result set
5830
- and then return a <literal>PGRES_FATAL_ERROR</> <type>PGresult</type> to
5831
- the application (containing the specified error message, or <quote>out of
5832
- memory for query result</> if <literal>*</><parameter>errmsgp</parameter>
5833
- was left as NULL).
5834
- </para>
5835
-
5836
- <para>
5837
- Another option for exiting a row processor is to throw an exception using
5838
- C's <function>longjmp()</> or C++'s <literal>throw</>. If this is done,
5839
- processing of the incoming data can be resumed later by calling
5840
- <function>PQgetResult</>; the row processor will be invoked as normal for
5841
- any remaining rows in the current result.
5842
- As with any usage of <function>PQgetResult</>, the application
5843
- should continue calling <function>PQgetResult</> until it gets a NULL
5844
- result before issuing any new query.
5845
- </para>
5846
-
5847
- <para>
5848
- In some cases, an exception may mean that the remainder of the
5849
- query result is not interesting. In such cases the application can discard
5850
- the remaining rows with <function>PQskipResult</>, described below.
5851
- Another possible recovery option is to close the connection altogether with
5852
- <function>PQfinish</>.
5853
- </para>
5854
-
5855
- <para>
5856
- <variablelist>
5857
- <varlistentry id="libpq-pqsetrowprocessor">
5858
- <term>
5859
- <function>PQsetRowProcessor</function>
5860
- <indexterm>
5861
- <primary>PQsetRowProcessor</primary>
5862
- </indexterm>
5863
- </term>
5864
-
5865
- <listitem>
5866
- <para>
5867
- Sets a callback function to process each row.
5868
-
5869
- <synopsis>
5870
- void PQsetRowProcessor(PGconn *conn, PQrowProcessor func, void *param);
5871
- </synopsis>
5872
- </para>
5873
-
5874
- <para>
5875
- The specified row processor function <parameter>func</> is installed as
5876
- the active row processor for the given connection <parameter>conn</>.
5877
- Also, <parameter>param</> is installed as the passthrough pointer to
5878
- pass to it. Alternatively, if <parameter>func</> is NULL, the standard
5879
- row processor is reinstalled on the given connection (and
5880
- <parameter>param</> is ignored).
5881
- </para>
5882
-
5883
- <para>
5884
- Although the row processor can be changed at any time in the life of a
5885
- connection, it's generally unwise to do so while a query is active.
5886
- In particular, when using asynchronous mode, be aware that both
5887
- <function>PQisBusy</> and <function>PQgetResult</> can call the current
5888
- row processor.
5889
- </para>
5890
- </listitem>
5891
- </varlistentry>
5892
-
5893
- <varlistentry id="libpq-pqgetrowprocessor">
5894
- <term>
5895
- <function>PQgetRowProcessor</function>
5896
- <indexterm>
5897
- <primary>PQgetRowProcessor</primary>
5898
- </indexterm>
5899
- </term>
5900
-
5901
- <listitem>
5902
- <para>
5903
- Fetches the current row processor for the specified connection.
5904
-
5905
- <synopsis>
5906
- PQrowProcessor PQgetRowProcessor(const PGconn *conn, void **param);
5907
- </synopsis>
5908
- </para>
5909
-
5910
- <para>
5911
- In addition to returning the row processor function pointer, the
5912
- current passthrough pointer will be returned at
5913
- <literal>*</><parameter>param</>, if <parameter>param</> is not NULL.
5914
- </para>
5915
- </listitem>
5916
- </varlistentry>
5917
-
5918
- <varlistentry id="libpq-pqskipresult">
5919
- <term>
5920
- <function>PQskipResult</function>
5921
- <indexterm>
5922
- <primary>PQskipResult</primary>
5923
- </indexterm>
5924
- </term>
5925
-
5926
- <listitem>
5927
- <para>
5928
- Discard all the remaining rows in the incoming result set.
5929
-
5930
- <synopsis>
5931
- PGresult *PQskipResult(PGconn *conn);
5932
- </synopsis>
5933
- </para>
5934
-
5935
- <para>
5936
- This is a simple convenience function to discard incoming data after a
5937
- row processor has failed or it's determined that the rest of the result
5938
- set is not interesting. <function>PQskipResult</> is exactly
5939
- equivalent to <function>PQgetResult</> except that it transiently
5940
- installs a dummy row processor function that just discards data.
5941
- The returned <type>PGresult</> can be discarded without further ado
5942
- if it has status <literal>PGRES_TUPLES_OK</>; but other status values
5943
- should be handled normally. (In particular,
5944
- <literal>PGRES_FATAL_ERROR</> indicates a server-reported error that
5945
- will still need to be dealt with.)
5946
- As when using <function>PQgetResult</>, one should usually repeat the
5947
- call until NULL is returned to ensure the connection has reached an
5948
- idle state. Another possible usage is to call
5949
- <function>PQskipResult</> just once, and then resume using
5950
- <function>PQgetResult</> to process subsequent result sets normally.
5951
- </para>
5952
-
5953
- <para>
5954
- Because <function>PQskipResult</> will wait for server input, it is not
5955
- very useful in asynchronous applications. In particular you should not
5956
- code a loop of <function>PQisBusy</> and <function>PQskipResult</>,
5957
- because that will result in the installed row processor being called
5958
- within <function>PQisBusy</>. To get the proper behavior in an
5959
- asynchronous application, you'll need to install a dummy row processor
5960
- (or set a flag to make your normal row processor do nothing) and leave
5961
- it that way until you have discarded all incoming data via your normal
5962
- <function>PQisBusy</> and <function>PQgetResult</> loop.
5963
- </para>
5964
- </listitem>
5965
- </varlistentry>
5966
- </variablelist>
5967
- </para>
5968
-
5969
- </sect1>
5970
-
5971
5703
<sect1 id="libpq-events">
5972
5704
<title>Event System</title>
5973
5705
0 commit comments