OCILIB (C and C++ Driver for Oracle)  4.7.3
Open source and cross platform Oracle Driver delivering efficient access to Oracle databases.
Lob.hpp
1 /*
2  * OCILIB - C Driver for Oracle (C Wrapper for Oracle OCI)
3  *
4  * Website: http://www.ocilib.net
5  *
6  * Copyright (c) 2007-2021 Vincent ROGIER <vince.rogier@ocilib.net>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #pragma once
22 
23 #include "ocilibcpp/types.hpp"
24 
25 // ReSharper disable CppClangTidyHicppUseEqualsDefault
26 // ReSharper disable CppClangTidyModernizeUseEqualsDefault
27 // ReSharper disable CppClangTidyHicppUseAuto
28 // ReSharper disable CppClangTidyModernizeUseAuto
29 // ReSharper disable CppClangTidyMiscMisplacedConst
30 
31 namespace ocilib
32 {
33 
34 template<class T, int U>
36 {
37 }
38 
39 template<class T, int U>
40 Lob<T, U>::Lob(const Connection &connection)
41 {
42  Acquire(core::Check(OCI_LobCreate(connection, U)), reinterpret_cast<HandleFreeFunc>(OCI_LobFree), nullptr, connection.GetHandle());
43 }
44 
45 template<class T, int U>
46 Lob<T, U>::Lob(OCI_Lob *pLob, core::Handle *parent)
47 {
48  Acquire(pLob, nullptr, nullptr, parent);
49 }
50 
51 template<>
52 inline ostring Lob<ostring, LobCharacter>::Read(unsigned int length)
53 {
54  core::ManagedBuffer<otext> buffer(static_cast<size_t>(Environment::GetCharMaxSize() * (length + 1)));
55 
56  unsigned int charCount = length;
57  unsigned int byteCount = 0;
58 
59  if (core::Check(OCI_LobRead2(*this, static_cast<AnyPointer>(buffer), &charCount, &byteCount)))
60  {
61  length = byteCount / sizeof(otext);
62  }
63 
64  return core::MakeString(static_cast<const otext *>(buffer), static_cast<int>(length));
65 }
66 
67 template<>
68 inline ostring Lob<ostring, LobNationalCharacter>::Read(unsigned int length)
69 {
70  core::ManagedBuffer<otext> buffer(static_cast<size_t>(Environment::GetCharMaxSize() * (length + 1)));
71 
72  unsigned int charCount = length;
73  unsigned int byteCount = 0;
74 
75  if (core::Check(OCI_LobRead2(*this, static_cast<AnyPointer>(buffer), &charCount, &byteCount)))
76  {
77  length = byteCount / sizeof(otext);
78  }
79 
80  return core::MakeString(static_cast<const otext *>(buffer), static_cast<int>(length));
81 
82 }
83 
84 template<>
85 inline Raw Lob<Raw, LobBinary>::Read(unsigned int length)
86 {
87  core::ManagedBuffer<unsigned char> buffer(length + 1);
88 
89  length = core::Check(OCI_LobRead(*this, static_cast<AnyPointer>(buffer), length));
90 
91  return core::MakeRaw(buffer, length);
92 }
93 
94 template<class T, int U>
95 unsigned int Lob<T, U>::Write(const T& content)
96 {
97  if (content.empty())
98  {
99  return 0;
100  }
101 
102  unsigned int res = 0;
103  unsigned int charCount = 0;
104  unsigned int byteCount = static_cast<unsigned int>(content.size() * sizeof(typename T::value_type));
105  const AnyPointer buffer = static_cast<AnyPointer>(const_cast<typename T::value_type *>(&content[0]));
106 
107  if (core::Check(OCI_LobWrite2(*this, buffer, &charCount, &byteCount)))
108  {
109  res = U == LobBinary ? byteCount : charCount;
110  }
111 
112  return res;
113 }
114 
115 template<class T, int U>
116 void Lob<T, U>::Append(const Lob& other)
117 {
118  core::Check(OCI_LobAppendLob(*this, other));
119 }
120 
121 template<class T, int U>
122 unsigned int Lob<T, U>::Append(const T& content)
123 {
124  if (content.empty())
125  {
126  return 0;
127  }
128 
129  const AnyPointer data = static_cast<AnyPointer>(const_cast<typename T::value_type*>(&content[0]));
130 
131  return core::Check(OCI_LobAppend(*this, data, static_cast<unsigned int>(content.size())));
132 }
133 
134 template<class T, int U>
135 bool Lob<T, U>::Seek(SeekMode seekMode, big_uint offset)
136 {
137  return (core::Check(OCI_LobSeek(*this, offset, seekMode)) == TRUE);
138 }
139 
140 template<class T, int U>
142 {
143  Lob result(GetConnection());
144 
145  core::Check(OCI_LobAssign(result, *this));
146 
147  return result;
148 }
149 
150 template<class T, int U>
151 bool Lob<T, U>::Equals(const Lob &other) const
152 {
153  return (core::Check(OCI_LobIsEqual(*this, other)) == TRUE);
154 }
155 
156 template<class T, int U>
158 {
159  return LobType(static_cast<LobType::Type>(core::Check(OCI_LobGetType(*this))));
160 }
161 
162 template<class T, int U>
163 big_uint Lob<T, U>::GetOffset() const
164 {
165  return core::Check(OCI_LobGetOffset(*this));
166 }
167 
168 template<class T, int U>
169 big_uint Lob<T, U>::GetLength() const
170 {
171  return core::Check(OCI_LobGetLength(*this));
172 }
173 
174 template<class T, int U>
175 big_uint Lob<T, U>::GetMaxSize() const
176 {
177  return core::Check(OCI_LobGetMaxSize(*this));
178 }
179 
180 template<class T, int U>
181 big_uint Lob<T, U>::GetChunkSize() const
182 {
183  return core::Check(OCI_LobGetChunkSize(*this));
184 }
185 
186 template<class T, int U>
188 {
189  return Connection(core::Check(OCI_LobGetConnection(*this)), nullptr);
190 }
191 
192 template<class T, int U>
193 void Lob<T, U>::Truncate(big_uint length)
194 {
195  core::Check(OCI_LobTruncate(*this, length));
196 }
197 
198 template<class T, int U>
199 big_uint Lob<T, U>::Erase(big_uint offset, big_uint length)
200 {
201  return core::Check(OCI_LobErase(*this, offset, length));
202 }
203 
204 template<class T, int U>
205 void Lob<T, U>::Copy(Lob &dest, big_uint offset, big_uint offsetDest, big_uint length) const
206 {
207  core::Check(OCI_LobCopy(dest, *this, offsetDest, offset, length));
208 }
209 
210 template<class T, int U>
212 {
213  return (core::Check(OCI_LobIsTemporary(*this)) == TRUE);
214 }
215 
216 template<class T, int U>
218 {
219  return (core::Check(OCI_LobIsRemote(*this)) == TRUE);
220 }
221 
222 template<class T, int U>
224 {
225  core::Check(OCI_LobOpen(*this, mode));
226 }
227 
228 template<class T, int U>
230 {
231  core::Check(OCI_LobFlush(*this));
232 }
233 
234 template<class T, int U>
236 {
237  core::Check(OCI_LobClose(*this));
238 }
239 
240 template<class T, int U>
242 {
243  core::Check(OCI_LobEnableBuffering(*this, value));
244 }
245 
246 template<class T, int U>
248 {
249  Append(other);
250  return *this;
251 }
252 
253 template<class T, int U>
254 bool Lob<T, U>::operator == (const Lob<T, U>& other) const
255 {
256  return Equals(other);
257 }
258 
259 template<class T, int U>
260 bool Lob<T, U>::operator != (const Lob<T, U>& other) const
261 {
262  return !(*this == other);
263 }
264 
265 }
OCI_SYM_PUBLIC unsigned int OCI_API OCI_LobGetChunkSize(OCI_Lob *lob)
Returns the chunk size of a LOB.
Internal usage. Interface for handling ownership and relationship of a C API handle.
Definition: core.hpp:312
bool IsRemote() const
Check if the given lob is a remote lob.
Definition: Lob.hpp:217
Connection GetConnection() const
Return the lob parent connection.
Definition: Lob.hpp:187
Lob & operator+=(const Lob &other)
Appending the given lob content to the current lob content.
Definition: Lob.hpp:247
OCILIB ++ Namespace.
OCI_SYM_PUBLIC boolean OCI_API OCI_LobIsEqual(OCI_Lob *lob, OCI_Lob *lob2)
Compare two lob handles for equality.
Raw MakeRaw(AnyPointer result, unsigned int size)
Internal usage. Constructs a C++ Raw object from the given OCILIB raw buffer.
Definition: Utils.hpp:70
bool IsTemporary() const
Check if the given lob is a temporary lob.
Definition: Lob.hpp:211
big_uint GetChunkSize() const
Returns the current lob chunk size.
Definition: Lob.hpp:181
OCI_SYM_PUBLIC unsigned int OCI_API OCI_LobGetType(OCI_Lob *lob)
Return the type of the given Lob object.
void Copy(Lob &dest, big_uint offset, big_uint offsetDest, big_uint length) const
Copy the given portion of the lob content to another one.
Definition: Lob.hpp:205
A connection or session with a specific database.
Definition: types.hpp:1563
Lob()
Create an empty null Lob instance.
Definition: Lob.hpp:35
core::Enum< LobTypeValues > LobType
Type of Lob.
Definition: types.hpp:290
T Read(unsigned int length)
Read a portion of a lob.
OCI_SYM_PUBLIC unsigned int OCI_API OCI_LobRead(OCI_Lob *lob, void *buffer, unsigned int len)
[OBSOLETE] Read a portion of a lob into the given buffer
static T Check(T result)
Internal usage. Checks if the last OCILIB function call has raised an error. If so, it raises a C++ exception using the retrieved error handle.
Definition: Utils.hpp:53
void Close()
Close explicitly a Lob.
Definition: Lob.hpp:235
OCI_SYM_PUBLIC big_uint OCI_API OCI_LobGetOffset(OCI_Lob *lob)
Return the current position in the Lob content buffer.
OCI_SYM_PUBLIC boolean OCI_API OCI_LobIsRemote(OCI_Lob *lob)
Indicates if the given lob belongs to a local or remote database table.
bool operator==(const Lob &other) const
Indicates if the current lob value is equal to the given lob value.
Definition: Lob.hpp:254
void Flush()
Flush the lob content to the server (if applicable)
Definition: Lob.hpp:229
OCI_SYM_PUBLIC boolean OCI_API OCI_LobRead2(OCI_Lob *lob, void *buffer, unsigned int *char_count, unsigned int *byte_count)
Read a portion of a lob into the given buffer.
OCI_SYM_PUBLIC boolean OCI_API OCI_LobSeek(OCI_Lob *lob, big_uint offset, unsigned int mode)
Perform a seek operation on the OCI_lob content buffer.
OCI_SYM_PUBLIC OCI_Lob *OCI_API OCI_LobCreate(OCI_Connection *con, unsigned int type)
Create a local temporary Lob instance.
ostring MakeString(const otext *result, int size=-1)
Internal usage. Constructs a C++ string object from the given OCILIB string pointer.
Definition: Utils.hpp:65
unsigned int Write(const T &content)
Write the given content at the current position within the lob.
Definition: Lob.hpp:95
void * AnyPointer
Alias for the generic void pointer.
Definition: config.hpp:129
Template Enumeration template class providing some type safety to some extends for manipulating enume...
Definition: core.hpp:117
OCI_SYM_PUBLIC boolean OCI_API OCI_LobCopy(OCI_Lob *lob, OCI_Lob *lob_src, big_uint offset_dst, big_uint offset_src, big_uint count)
Copy a portion of a source LOB into a destination LOB.
Lob Clone() const
Clone the current instance to a new one performing deep copy.
Definition: Lob.hpp:141
Internal usage. Provide a buffer class with RAII capabilities.
Definition: core.hpp:196
LobType GetType() const
return the type of lob
Definition: Lob.hpp:157
OCI_SYM_PUBLIC big_uint OCI_API OCI_LobGetLength(OCI_Lob *lob)
Return the actual length of a lob.
OCI_SYM_PUBLIC boolean OCI_API OCI_LobIsTemporary(OCI_Lob *lob)
Check if the given lob is a temporary lob.
OCI_SYM_PUBLIC big_uint OCI_API OCI_LobGetMaxSize(OCI_Lob *lob)
Return the maximum size that the lob can contain.
OCI_SYM_PUBLIC boolean OCI_API OCI_LobAppendLob(OCI_Lob *lob, OCI_Lob *lob_src)
Append a source LOB at the end of a destination LOB.
big_uint GetLength() const
Returns the number of characters or bytes contained in the lob.
Definition: Lob.hpp:169
OCI_SYM_PUBLIC boolean OCI_API OCI_LobEnableBuffering(OCI_Lob *lob, boolean value)
Enable / disable buffering mode on the given lob handle.
static unsigned int GetCharMaxSize()
Return maximum size for a character.
Definition: Environment.hpp:67
OCI_SYM_PUBLIC boolean OCI_API OCI_LobAssign(OCI_Lob *lob, OCI_Lob *lob_src)
Assign a lob to another one.
big_uint GetOffset() const
Returns the current R/W offset within the lob.
Definition: Lob.hpp:163
std::vector< unsigned char > Raw
C++ counterpart of SQL RAW data type.
Definition: config.hpp:138
OCI_SYM_PUBLIC OCI_Connection *OCI_API OCI_LobGetConnection(OCI_Lob *lob)
Retrieve connection handle from the lob handle.
OCI_SYM_PUBLIC boolean OCI_API OCI_LobFree(OCI_Lob *lob)
Free a local temporary lob.
OCI_SYM_PUBLIC boolean OCI_API OCI_LobOpen(OCI_Lob *lob, unsigned int mode)
Open explicitly a Lob.
OCI_SYM_PUBLIC big_uint OCI_API OCI_LobErase(OCI_Lob *lob, big_uint offset, big_uint len)
Erase a portion of the lob at a given position.
Object identifying the SQL data type LOB (CLOB, NCLOB and BLOB)
Definition: config.hpp:198
unsigned int Append(const T &content)
Append the given content to the lob.
Definition: Lob.hpp:122
void Open(OpenMode mode)
Open explicitly a Lob.
Definition: Lob.hpp:223
OCI_SYM_PUBLIC unsigned int OCI_API OCI_LobAppend(OCI_Lob *lob, void *buffer, unsigned int len)
Append a buffer at the end of a LOB.
std::basic_string< otext, std::char_traits< otext >, std::allocator< otext > > ostring
string class wrapping the OCILIB otext * type and OTEXT() macros ( see Character sets ) ...
Definition: config.hpp:120
bool operator!=(const Lob &other) const
Indicates if the current lob value is not equal the given lob value.
Definition: Lob.hpp:260
big_uint GetMaxSize() const
Returns the lob maximum possible size.
Definition: Lob.hpp:175
OCI_SYM_PUBLIC boolean OCI_API OCI_LobWrite2(OCI_Lob *lob, void *buffer, unsigned int *char_count, unsigned int *byte_count)
Write a buffer into a LOB.
void Truncate(big_uint length)
Truncate the lob to a shorter length.
Definition: Lob.hpp:193
bool Seek(SeekMode seekMode, big_uint offset)
Move the current position within the lob for read/write operations.
Definition: Lob.hpp:135
void EnableBuffering(bool value)
Enable / disable buffering mode on the given lob object.
Definition: Lob.hpp:241
struct OCI_Lob OCI_Lob
Oracle Internal Large objects:
Definition: types.h:186
OCI_SYM_PUBLIC boolean OCI_API OCI_LobClose(OCI_Lob *lob)
Close explicitly a Lob.
big_uint Erase(big_uint offset, big_uint length)
Erase a portion of the lob at a given position.
Definition: Lob.hpp:199
OCI_SYM_PUBLIC boolean OCI_API OCI_LobTruncate(OCI_Lob *lob, big_uint size)
Truncate the given lob to a shorter length.
OCI_SYM_PUBLIC boolean OCI_API OCI_LobFlush(OCI_Lob *lob)
Flush Lob content to the server.