2010-04-07 Jb Evain <jbevain@novell.com>
[mcs.git] / class / Npgsql / Npgsql / NpgsqlCopyIn.cs
blobecb6226c9d4d457a425528d4fa9b90ce00b7c02c
1 // Npgsql.NpgsqlCopyIn.cs
2 //
3 // Author:
4 // Kalle Hallivuori <kato@iki.fi>
5 //
6 // Copyright (C) 2007 The Npgsql Development Team
7 // npgsql-general@gborg.postgresql.org
8 // http://gborg.postgresql.org/project/npgsql/projdisplay.php
9 //
10 // Copyright (c) 2002-2007, The Npgsql Development Team
11 //
12 // Permission to use, copy, modify, and distribute this software and its
13 // documentation for any purpose, without fee, and without a written
14 // agreement is hereby granted, provided that the above copyright notice
15 // and this paragraph and the following two paragraphs appear in all copies.
16 //
17 // IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY
18 // FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
19 // INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
20 // DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF
21 // THE POSSIBILITY OF SUCH DAMAGE.
22 //
23 // THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES,
24 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
25 // AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
26 // ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS
27 // TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
30 using System.IO;
32 namespace Npgsql
34 /// <summary>
35 /// Represents a PostgreSQL COPY FROM STDIN operation with a corresponding SQL statement
36 /// to execute against a PostgreSQL database
37 /// and an associated stream used to read data from (if provided by user)
38 /// or for writing it (when generated by driver).
39 /// Eg. new NpgsqlCopyIn("COPY mytable FROM STDIN", connection, streamToRead).Start();
40 /// </summary>
41 public class NpgsqlCopyIn
43 private readonly NpgsqlConnector _context;
44 private readonly NpgsqlCommand _cmd;
45 private Stream _copyStream;
46 private bool _disposeCopyStream; // user did not provide stream, so reset it after use
48 /// <summary>
49 /// Creates NpgsqlCommand to run given query upon Start(). Data for the requested COPY IN operation can then be written to CopyData stream followed by a call to End() or Cancel().
50 /// </summary>
51 public NpgsqlCopyIn(string copyInQuery, NpgsqlConnection conn)
52 : this(new NpgsqlCommand(copyInQuery, conn), conn)
56 /// <summary>
57 /// Given command is run upon Start(). Data for the requested COPY IN operation can then be written to CopyData stream followed by a call to End() or Cancel().
58 /// </summary>
59 public NpgsqlCopyIn(NpgsqlCommand cmd, NpgsqlConnection conn)
60 : this(cmd, conn, null)
64 /// <summary>
65 /// Given command is executed upon Start() and all data from fromStream is passed to it as copy data.
66 /// </summary>
67 public NpgsqlCopyIn(NpgsqlCommand cmd, NpgsqlConnection conn, Stream fromStream)
69 _context = conn.Connector;
70 _cmd = cmd;
71 _copyStream = fromStream;
74 /// <summary>
75 /// Returns true if the connection is currently reserved for this operation.
76 /// </summary>
77 public bool IsActive
79 get { return _context != null && _context.CurrentState is NpgsqlCopyInState && _context.Mediator.CopyStream == _copyStream; }
82 /// <summary>
83 /// The stream provided by user or generated upon Start().
84 /// User may provide a stream to constructor; it is used to pass to server all data read from it.
85 /// Otherwise, call to Start() sets this to a writable NpgsqlCopyInStream that passes all data written to it to server.
86 /// In latter case this is only available while the copy operation is active and null otherwise.
87 /// </summary>
88 public Stream CopyStream
90 get { return _copyStream; }
93 /// <summary>
94 /// Returns true if this operation is currently active and in binary format.
95 /// </summary>
96 public bool IsBinary
98 get { return IsActive && _context.CurrentState.CopyFormat.IsBinary; }
101 /// <summary>
102 /// Returns true if this operation is currently active and field at given location is in binary format.
103 /// </summary>
104 public bool FieldIsBinary(int fieldNumber)
106 return IsActive && _context.CurrentState.CopyFormat.FieldIsBinary(fieldNumber);
109 /// <summary>
110 /// Returns number of fields expected on each input row if this operation is currently active, otherwise -1
111 /// </summary>
112 public int FieldCount
114 get { return IsActive ? _context.CurrentState.CopyFormat.FieldCount : -1; }
117 /// <summary>
118 /// The Command used to execute this copy operation.
119 /// </summary>
120 public NpgsqlCommand NpgsqlCommand
122 get { return _cmd; }
125 /// <summary>
126 /// Set before a COPY IN query to define size of internal buffer for reading from given CopyStream.
127 /// </summary>
128 public int CopyBufferSize
130 get { return _context.Mediator.CopyBufferSize; }
131 set { _context.Mediator.CopyBufferSize = value; }
134 /// <summary>
135 /// Command specified upon creation is executed as a non-query.
136 /// If CopyStream is set upon creation, it will be flushed to server as copy data, and operation will be finished immediately.
137 /// Otherwise the CopyStream member can be used for writing copy data to server and operation finished with a call to End() or Cancel().
138 /// </summary>
139 public void Start()
141 if (_context.CurrentState is NpgsqlReadyState)
143 _context.Mediator.CopyStream = _copyStream;
144 _cmd.ExecuteBlind();
145 _disposeCopyStream = _copyStream == null;
146 _copyStream = _context.Mediator.CopyStream;
147 if (_copyStream == null && ! (_context.CurrentState is NpgsqlReadyState))
149 throw new NpgsqlException("Not a COPY IN query: " + _cmd.CommandText);
152 else
154 throw new NpgsqlException("Copy can only start in Ready state, not in " + _context.CurrentState);
158 /// <summary>
159 /// Called after writing all data to CopyStream to successfully complete this copy operation.
160 /// </summary>
161 public void End()
163 if (_context != null)
167 if (IsActive)
169 _context.CurrentState.SendCopyDone(_context);
172 finally
174 if (_context.Mediator.CopyStream == _copyStream)
176 _context.Mediator.CopyStream = null;
178 if (_disposeCopyStream)
180 _copyStream = null;
186 /// <summary>
187 /// Withdraws an already started copy operation. The operation will fail with given error message.
188 /// Will do nothing if current operation is not active.
189 /// </summary>
190 public void Cancel(string message)
192 if (_context != null)
196 if (IsActive)
198 _context.CurrentState.SendCopyFail(_context, message);
201 finally
203 if (_context.Mediator.CopyStream == _copyStream)
205 _context.Mediator.CopyStream = null;
207 if (_disposeCopyStream)
209 _copyStream = null;