OCILIB (C and C++ Driver for Oracle)  4.7.6
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-2023 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  AcquireAllocated
43  (
44  core::Check(OCI_LobCreate(connection, U)),
45  connection.GetHandle()
46  );
47 }
48 
49 template<class T, int U>
50 Lob<T, U>::Lob(OCI_Lob *pLob, core::Handle *parent)
51 {
52  AcquireTransient(pLob, parent);
53 }
54 
55 template<>
56 inline ostring Lob<ostring, LobCharacter>::Read(unsigned int length)
57 {
58  core::ManagedBuffer<otext> buffer(static_cast<size_t>(Environment::GetCharMaxSize() * (length + 1)));
59 
60  unsigned int charCount = length;
61  unsigned int byteCount = 0;
62 
63  if (core::Check(OCI_LobRead2(*this, static_cast<AnyPointer>(buffer), &charCount, &byteCount)))
64  {
65  length = byteCount / sizeof(otext);
66  }
67 
68  return core::MakeString(static_cast<const otext *>(buffer), static_cast<int>(length));
69 }
70 
71 template<>
72 inline ostring Lob<ostring, LobNationalCharacter>::Read(unsigned int length)
73 {
74  core::ManagedBuffer<otext> buffer(static_cast<size_t>(Environment::GetCharMaxSize() * (length + 1)));
75 
76  unsigned int charCount = length;
77  unsigned int byteCount = 0;
78 
79  if (core::Check(OCI_LobRead2(*this, static_cast<AnyPointer>(buffer), &charCount, &byteCount)))
80  {
81  length = byteCount / sizeof(otext);
82  }
83 
84  return core::MakeString(static_cast<const otext *>(buffer), static_cast<int>(length));
85 
86 }
87 
88 template<>
89 inline Raw Lob<Raw, LobBinary>::Read(unsigned int length)
90 {
91  core::ManagedBuffer<unsigned char> buffer(length + 1);
92 
93  length = core::Check(OCI_LobRead(*this, static_cast<AnyPointer>(buffer), length));
94 
95  return core::MakeRaw(buffer, length);
96 }
97 
98 template<class T, int U>
99 unsigned int Lob<T, U>::Write(const T& content)
100 {
101  if (content.empty())
102  {
103  return 0;
104  }
105 
106  unsigned int res = 0;
107  unsigned int charCount = 0;
108  unsigned int byteCount = static_cast<unsigned int>(content.size() * sizeof(typename T::value_type));
109  const AnyPointer buffer = static_cast<AnyPointer>(const_cast<typename T::value_type *>(&content[0]));
110 
111  if (core::Check(OCI_LobWrite2(*this, buffer, &charCount, &byteCount)))
112  {
113  res = U == LobBinary ? byteCount : charCount;
114  }
115 
116  return res;
117 }
118 
119 template<class T, int U>
120 void Lob<T, U>::Append(const Lob& other)
121 {
122  core::Check(OCI_LobAppendLob(*this, other));
123 }
124 
125 template<class T, int U>
126 unsigned int Lob<T, U>::Append(const T& content)
127 {
128  if (content.empty())
129  {
130  return 0;
131  }
132 
133  const AnyPointer data = static_cast<AnyPointer>(const_cast<typename T::value_type*>(&content[0]));
134 
135  return core::Check(OCI_LobAppend(*this, data, static_cast<unsigned int>(content.size())));
136 }
137 
138 template<class T, int U>
139 bool Lob<T, U>::Seek(SeekMode seekMode, big_uint offset)
140 {
141  return (core::Check(OCI_LobSeek(*this, offset, seekMode)) == TRUE);
142 }
143 
144 template<class T, int U>
146 {
147  Lob result(GetConnection());
148 
149  core::Check(OCI_LobAssign(result, *this));
150 
151  return result;
152 }
153 
154 template<class T, int U>
155 bool Lob<T, U>::Equals(const Lob &other) const
156 {
157  return (core::Check(OCI_LobIsEqual(*this, other)) == TRUE);
158 }
159 
160 template<class T, int U>
162 {
163  return LobType(static_cast<LobType::Type>(core::Check(OCI_LobGetType(*this))));
164 }
165 
166 template<class T, int U>
167 big_uint Lob<T, U>::GetOffset() const
168 {
169  return core::Check(OCI_LobGetOffset(*this));
170 }
171 
172 template<class T, int U>
173 big_uint Lob<T, U>::GetLength() const
174 {
175  return core::Check(OCI_LobGetLength(*this));
176 }
177 
178 template<class T, int U>
179 big_uint Lob<T, U>::GetMaxSize() const
180 {
181  return core::Check(OCI_LobGetMaxSize(*this));
182 }
183 
184 template<class T, int U>
185 big_uint Lob<T, U>::GetChunkSize() const
186 {
187  return core::Check(OCI_LobGetChunkSize(*this));
188 }
189 
190 template<class T, int U>
192 {
193  return Connection
194  (
196  Environment::GetEnvironmentHandle()
197  );
198 }
199 
200 template<class T, int U>
201 void Lob<T, U>::Truncate(big_uint length)
202 {
203  core::Check(OCI_LobTruncate(*this, length));
204 }
205 
206 template<class T, int U>
207 big_uint Lob<T, U>::Erase(big_uint offset, big_uint length)
208 {
209  return core::Check(OCI_LobErase(*this, offset, length));
210 }
211 
212 template<class T, int U>
213 void Lob<T, U>::Copy(Lob &dest, big_uint offset, big_uint offsetDest, big_uint length) const
214 {
215  core::Check(OCI_LobCopy(dest, *this, offsetDest, offset, length));
216 }
217 
218 template<class T, int U>
220 {
221  return (core::Check(OCI_LobIsTemporary(*this)) == TRUE);
222 }
223 
224 template<class T, int U>
226 {
227  return (core::Check(OCI_LobIsRemote(*this)) == TRUE);
228 }
229 
230 template<class T, int U>
232 {
233  core::Check(OCI_LobOpen(*this, mode));
234 }
235 
236 template<class T, int U>
238 {
239  core::Check(OCI_LobFlush(*this));
240 }
241 
242 template<class T, int U>
244 {
245  core::Check(OCI_LobClose(*this));
246 }
247 
248 template<class T, int U>
250 {
251  core::Check(OCI_LobEnableBuffering(*this, value));
252 }
253 
254 template<class T, int U>
256 {
257  Append(other);
258  return *this;
259 }
260 
261 template<class T, int U>
262 bool Lob<T, U>::operator == (const Lob<T, U>& other) const
263 {
264  return Equals(other);
265 }
266 
267 template<class T, int U>
268 bool Lob<T, U>::operator != (const Lob<T, U>& other) const
269 {
270  return !(*this == other);
271 }
272 
273 }
A connection or session with a specific database.
Definition: types.hpp:1580
static unsigned int GetCharMaxSize()
Return maximum size for a character.
Definition: Environment.hpp:67
Object identifying the SQL data type LOB (CLOB, NCLOB and BLOB)
Definition: types.hpp:4020
void Truncate(big_uint length)
Truncate the lob to a shorter length.
Definition: Lob.hpp:201
unsigned int Write(const T &content)
Write the given content at the current position within the lob.
Definition: Lob.hpp:99
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:213
Lob()
Create an empty null Lob instance.
Definition: Lob.hpp:35
bool IsTemporary() const
Check if the given lob is a temporary lob.
Definition: Lob.hpp:219
big_uint GetOffset() const
Returns the current R/W offset within the lob.
Definition: Lob.hpp:167
void Flush()
Flush the lob content to the server (if applicable)
Definition: Lob.hpp:237
big_uint GetLength() const
Returns the number of characters or bytes contained in the lob.
Definition: Lob.hpp:173
bool operator!=(const Lob &other) const
Indicates if the current lob value is not equal the given lob value.
Definition: Lob.hpp:268
big_uint GetMaxSize() const
Returns the lob maximum possible size.
Definition: Lob.hpp:179
void Close()
Close explicitly a Lob.
Definition: Lob.hpp:243
bool IsRemote() const
Check if the given lob is a remote lob.
Definition: Lob.hpp:225
void EnableBuffering(bool value)
Enable / disable buffering mode on the given lob object.
Definition: Lob.hpp:249
LobType GetType() const
return the type of lob
Definition: Lob.hpp:161
bool operator==(const Lob &other) const
Indicates if the current lob value is equal to the given lob value.
Definition: Lob.hpp:262
Connection GetConnection() const
Return the lob parent connection.
Definition: Lob.hpp:191
unsigned int Append(const T &content)
Append the given content to the lob.
Definition: Lob.hpp:126
big_uint GetChunkSize() const
Returns the current lob chunk size.
Definition: Lob.hpp:185
T Read(unsigned int length)
Read a portion of a lob.
void Open(OpenMode mode)
Open explicitly a Lob.
Definition: Lob.hpp:231
big_uint Erase(big_uint offset, big_uint length)
Erase a portion of the lob at a given position.
Definition: Lob.hpp:207
bool Seek(SeekMode seekMode, big_uint offset)
Move the current position within the lob for read/write operations.
Definition: Lob.hpp:139
Lob & operator+=(const Lob &other)
Appending the given lob content to the current lob content.
Definition: Lob.hpp:255
Lob Clone() const
Clone the current instance to a new one performing deep copy.
Definition: Lob.hpp:145
Template Enumeration template class providing some type safety to some extends for manipulating enume...
Definition: core.hpp:118
Internal usage. Interface for handling ownership and relationship of a C API handle.
Definition: core.hpp:325
struct OCI_Lob OCI_Lob
Oracle Internal Large objects:
Definition: types.h:198
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_LobEnableBuffering(OCI_Lob *lob, boolean value)
Enable / disable buffering mode on the given lob handle.
OCI_SYM_PUBLIC boolean OCI_API OCI_LobOpen(OCI_Lob *lob, unsigned int mode)
Open explicitly a Lob.
OCI_SYM_PUBLIC unsigned int OCI_API OCI_LobGetChunkSize(OCI_Lob *lob)
Returns the chunk size of a LOB.
OCI_SYM_PUBLIC boolean OCI_API OCI_LobIsEqual(OCI_Lob *lob, OCI_Lob *lob2)
Compare two lob handles for equality.
OCI_SYM_PUBLIC boolean OCI_API OCI_LobClose(OCI_Lob *lob)
Close explicitly a Lob.
OCI_SYM_PUBLIC boolean OCI_API OCI_LobIsRemote(OCI_Lob *lob)
Indicates if the given lob belongs to a local or remote database table.
OCI_SYM_PUBLIC big_uint OCI_API OCI_LobGetMaxSize(OCI_Lob *lob)
Return the maximum size that the lob can contain.
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
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_LobWrite2(OCI_Lob *lob, void *buffer, unsigned int *char_count, unsigned int *byte_count)
Write a buffer into a LOB.
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.
OCI_SYM_PUBLIC OCI_Lob *OCI_API OCI_LobCreate(OCI_Connection *con, unsigned int type)
Create a local temporary Lob instance.
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.
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_LobFlush(OCI_Lob *lob)
Flush Lob content to the server.
OCI_SYM_PUBLIC big_uint OCI_API OCI_LobGetLength(OCI_Lob *lob)
Return the actual length of 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.
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 boolean OCI_API OCI_LobAssign(OCI_Lob *lob, OCI_Lob *lob_src)
Assign a lob to another one.
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.
OCI_SYM_PUBLIC boolean OCI_API OCI_LobIsTemporary(OCI_Lob *lob)
Check if the given lob is a temporary lob.
OCI_SYM_PUBLIC unsigned int OCI_API OCI_LobGetType(OCI_Lob *lob)
Return the type of the given Lob object.
OCI_SYM_PUBLIC OCI_Connection *OCI_API OCI_LobGetConnection(OCI_Lob *lob)
Retrieve connection handle from the lob handle.
static T Check(T result)
Internal usage. Checks if the last OCILIB function call has raised an error. If so,...
Definition: Utils.hpp:53
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
Raw MakeRaw(AnyPointer result, unsigned int size)
Internal usage. Constructs a C++ Raw object from the given OCILIB raw buffer.
Definition: Utils.hpp:70
OCILIB ++ Namespace.
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
core::Enum< LobTypeValues > LobType
Type of Lob.
Definition: types.hpp:297
std::vector< unsigned char > Raw
C++ counterpart of SQL RAW data type.
Definition: config.hpp:138
void * AnyPointer
Alias for the generic void pointer.
Definition: config.hpp:129