1 // Npgsql.NpgsqlCopyOut.cs
4 // Kalle Hallivuori <kato@iki.fi>
6 // Copyright (C) 2007 The Npgsql Development Team
7 // npgsql-general@gborg.postgresql.org
8 // http://gborg.postgresql.org/project/npgsql/projdisplay.php
10 // Permission to use, copy, modify, and distribute this software and its
11 // documentation for any purpose, without fee, and without a written
12 // agreement is hereby granted, provided that the above copyright notice
13 // and this paragraph and the following two paragraphs appear in all copies.
15 // IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY
16 // FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
17 // INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
18 // DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF
19 // THE POSSIBILITY OF SUCH DAMAGE.
21 // THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES,
22 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
23 // AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
24 // ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS
25 // TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
33 /// Represents a PostgreSQL COPY TO STDOUT operation with a corresponding SQL statement
34 /// to execute against a PostgreSQL database
35 /// and an associated stream used to write results to (if provided by user)
36 /// or for reading the results (when generated by driver).
37 /// Eg. new NpgsqlCopyOut("COPY (SELECT * FROM mytable) TO STDOUT", connection, streamToWrite).Start();
39 public class NpgsqlCopyOut
41 private readonly NpgsqlConnector _context
;
42 private readonly NpgsqlCommand _cmd
;
43 private Stream _copyStream
;
44 private bool _disposeCopyStream
; // user did not provide stream, so reset it after use
47 /// Creates NpgsqlCommand to run given query upon Start(), after which CopyStream provides data from database as requested in the query.
49 public NpgsqlCopyOut(string copyOutQuery
, NpgsqlConnection conn
)
50 : this(new NpgsqlCommand(copyOutQuery
, conn
), conn
)
55 /// Given command is run upon Start(), after which CopyStream provides data from database as requested in the query.
57 public NpgsqlCopyOut(NpgsqlCommand cmd
, NpgsqlConnection conn
)
58 : this(cmd
, conn
, null)
63 /// Given command is executed upon Start() and all requested copy data is written to toStream immediately.
65 public NpgsqlCopyOut(NpgsqlCommand cmd
, NpgsqlConnection conn
, Stream toStream
)
67 _context
= conn
.Connector
;
69 _copyStream
= toStream
;
73 /// Returns true if the connection is currently reserved for this operation.
80 _context
!= null && _context
.CurrentState
is NpgsqlCopyOutState
&& _context
.Mediator
.CopyStream
== _copyStream
;
85 /// The stream provided by user or generated upon Start()
87 public Stream CopyStream
89 get { return _copyStream; }
93 /// The Command used to execute this copy operation.
95 public NpgsqlCommand NpgsqlCommand
101 /// Returns true if this operation is currently active and in binary format.
105 get { return IsActive && _context.CurrentState.CopyFormat.IsBinary; }
109 /// Returns true if this operation is currently active and field at given location is in binary format.
111 public bool FieldIsBinary(int fieldNumber
)
113 return IsActive
&& _context
.CurrentState
.CopyFormat
.FieldIsBinary(fieldNumber
);
117 /// Returns number of fields if this operation is currently active, otherwise -1
119 public int FieldCount
121 get { return IsActive ? _context.CurrentState.CopyFormat.FieldCount : -1; }
125 /// Command specified upon creation is executed as a non-query.
126 /// If CopyStream is set upon creation, all copy data from server will be written to it, and operation will be finished immediately.
127 /// Otherwise the CopyStream member can be used for reading copy data from server until no more data is available.
131 if (_context
.CurrentState
is NpgsqlReadyState
)
133 _context
.Mediator
.CopyStream
= _copyStream
;
135 _disposeCopyStream
= _copyStream
== null;
136 _copyStream
= _context
.Mediator
.CopyStream
;
137 if (_copyStream
== null && ! (_context
.CurrentState
is NpgsqlReadyState
))
139 throw new NpgsqlException("Not a COPY OUT query: " + _cmd
.CommandText
);
144 throw new NpgsqlException("Copy can only start in Ready state, not in " + _context
.CurrentState
);
149 /// Faster alternative to using the generated CopyStream.
153 get { return IsActive ? ((NpgsqlCopyOutStream) _copyStream).Read() : null; }
157 /// Flush generated CopyStream at once. Effectively reads and discard all the rest of copy data from server.
161 if (_context
!= null)
163 bool wasActive
= IsActive
;
166 if (_copyStream
is NpgsqlCopyOutStream
)
172 while (_context
.CurrentState
.GetCopyData(_context
) != null)
178 if (_context
.Mediator
.CopyStream
== _copyStream
)
180 _context
.Mediator
.CopyStream
= null;
181 if (_disposeCopyStream
)