Skip to content

Commit a897efc

Browse files
committed
writelob
1 parent 0203243 commit a897efc

File tree

10 files changed

+223
-6
lines changed

10 files changed

+223
-6
lines changed

man/man1rwl/databasestatement.1rwl

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ databasestatement ::=
1212
| \fBmodify\fR \fBdatabase\fR \fBconnectionclass\fR concatenation
1313
| \fBmodify\fR \fBdatabase\fR identifier \fBsessionpool\fR expression [ \fB..\fR expression ]
1414
| \fBmodify\fR \fBdatabase\fR identifier \fBcursorcache\fR expression
15-
| \fBwritelob\fR identifier \fB,\fR concatenation
16-
| \fBreadlob\fR identifier \fB,\fR identifier
15+
| \fBwritelob\fR identifier \fB,\fR concatenation [ \fB,\fR expression ]
16+
| \fBreadlob\fR identifier \fB,\fR identifier [\fb,\fR identifier \fb,\fR expression]
1717

1818
.fi
1919
.SH DESCRIPTION
@@ -81,9 +81,17 @@ created in the pool; existing sessions will not have their value changed.
8181
The variable l must be of type clob on which OCILobWrite2() and OCILobTrim2()
8282
will be executed effectively writing the value to the database CLOB.
8383
.TP
84+
.B writelob l, value, offset o
85+
The variable l must be of type clob on which OCILobWrite2() and OCILobTrim2()
86+
will be executed effectively writing the value to the database CLOB, starting from the offset.
87+
.TP
8488
.B readlob l, s
8589
The variable l must be of type clob and s of type string; an OCILobRead2()
8690
call will be performed reading the value of the database CLOB into the string variable.
91+
.TP
92+
.B readlob l, s, length e, offset o
93+
The variable l must be of type clob, s of type string, length of type integer,and offset of type integer; an OCILobRead2()
94+
call will be performed reading the e bytes of the database CLOB into the string variable from the offset.
8795
.SH NOTES
8896
If you have a default database that is declared anything but dedicated, you need
8997
to wrap database calls directly in your main program (such as a DML and the associated

src/rwl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
*
1414
* History
1515
*
16+
* johnkenn 06-mar-2024 - readlob with offset
1617
* johnkenn 18-dec-2023 - Lob size and offset for streaming
1718
* bengsig 9-nov-2023 - Increase RWL_MAX_VAR
1819
* johnkenn 02-nov-2023 - trignometry sin, cos, atan2
@@ -1504,6 +1505,7 @@ enum rwl_code_t
15041505
, RWL_CODE_READLOB // Read a LOB into a string - ceptr1/ceint2 is name/guess of LOB, ceptr3/ceint4 of string variable
15051506
, RWL_CODE_READLOB_LO // Read a LOB into a string with offset and read length - ceptr5 of int - ceptr of int
15061507
, RWL_CODE_WRITELOB // Write a LOB from an expression - ceptr1/ceint2 is name/guess of LOB, ceptr3 is rwl_estack* to write to it
1508+
, RWL_CODE_WRITELOB_O // // Write a LOB from an expression - ceptr1/ceint2 is name/guess of LOB, ceptr3 is rwl_estack* to write to it, ceptr4 is rwl_estack* for offset
15071509
// control control block execution does not nest
15081510
, RWL_CODE_CBLOCK_BEG // Begin of control block - no arguments
15091511
, RWL_CODE_CBLOCK_END // End of control block - no arguments
@@ -1845,6 +1847,7 @@ extern void rwlfreeabd(rwl_xeqenv *, rwl_location *, rwl_sql *);
18451847
extern void rwlalloclob(rwl_xeqenv *, rwl_location *, OCILobLocator **);
18461848
extern void rwlfreelob(rwl_xeqenv *, rwl_location *, OCILobLocator *);
18471849
extern void rwlwritelob(rwl_xeqenv *, OCILobLocator *, rwl_cinfo *, rwl_value *, rwl_location *, text *);
1850+
extern void rwlwritelobo(rwl_xeqenv *, OCILobLocator *, rwl_cinfo *, rwl_value *, rwl_location *, ub8, text *);
18481851
extern void rwlreadlob(rwl_xeqenv *, OCILobLocator *, rwl_cinfo *, rwl_value *, rwl_location *, text *);
18491852
extern void rwlreadloblo(rwl_xeqenv *, OCILobLocator *, rwl_cinfo *, rwl_value *, rwl_value *, ub8, rwl_location *, text *);
18501853
extern void rwldummyonbad(rwl_xeqenv *, text *); // Use dummy database if default is bad

src/rwlcodeadd.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
*
1414
* History
1515
*
16+
* johnkenn 06-mar-2024 - writelob offset
1617
* johnkenn 18-dec-2023 - readlob length offset
1718
* bengsig 20-sep-2023 - list iterator loop
1819
* bengsig 10-aug-2023 - session pool timeout then action
@@ -135,6 +136,7 @@ void rwlcodeadd(rwl_main *rwm, rwl_code_t ctype, void *parg1
135136
case RWL_CODE_READLOB: rwm->code[rwm->ccount].cname = "rdlob"; break;
136137
case RWL_CODE_READLOB_LO: rwm->code[rwm->ccount].cname = "rdloblo"; break;
137138
case RWL_CODE_WRITELOB: rwm->code[rwm->ccount].cname = "wrlob"; break;
139+
case RWL_CODE_WRITELOB_O: rwm->code[rwm->ccount].cname = "wrlobo"; break;
138140
case RWL_CODE_REGEX: rwm->code[rwm->ccount].cname = "regex"; break;
139141
case RWL_CODE_REGEXTRACT: rwm->code[rwm->ccount].cname = "reext"; break;
140142
case RWL_CODE_REGEXSUB: rwm->code[rwm->ccount].cname = "resub"; break;
@@ -634,6 +636,13 @@ void rwlcodeadd(rwl_main *rwm, rwl_code_t ctype, void *parg1
634636
rwm->code[rwm->ccount].ceptr5 = parg5; // codename
635637
break;
636638

639+
case RWL_CODE_WRITELOB_O:
640+
rwm->code[rwm->ccount].ceptr1 = parg1; // lob name
641+
rwm->code[rwm->ccount].ceint2 = (sb4) arg2; // guess of lob var#
642+
rwm->code[rwm->ccount].ceptr3 = parg3; // expression to write to lob
643+
rwm->code[rwm->ccount].ceptr5 = parg5; // offset expression
644+
break;
645+
637646
case RWL_CODE_SPRINTF:
638647
rwm->code[rwm->ccount].ceptr1 = parg1; // string name
639648
rwm->code[rwm->ccount].ceint2 = (sb4) arg2; // guess of string var#

src/rwlcoderun.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*
1515
* History
1616
*
17+
* johnkenn 06-mar-2024 - writelob with offset
1718
* johnkenn 18-dec-2023 - Add lobstreaming to readlob
1819
* bengsig 25-sep-2023 - fix if doublevar then
1920
* bengsig 22-sep-2023 - ampersand needs thread local sql
@@ -1135,6 +1136,54 @@ void *rwlcoderun ( rwl_xeqenv *xev)
11351136
}
11361137
break;
11371138

1139+
case RWL_CODE_WRITELOB_O:
1140+
{
1141+
sb4 l;
1142+
if (bit(xev->rwm->mflags, RWL_DEBUG_EXECUTE))
1143+
rwldebug(xev->rwm, "pc=%d executing writelobo", pc);
1144+
// find the LOB
1145+
l = rwlfindvarug2(xev, xev->rwm->code[pc].ceptr1, &xev->rwm->code[pc].ceint2
1146+
, codename);
1147+
rwlexpreval(xev->rwm->code[pc].ceptr5, &xev->rwm->code[pc].cloc, xev, &xev->xqnum2);
1148+
/*assert*/
1149+
if (xev->evar[l].vtype != RWL_TYPE_CLOB
1150+
&& xev->evar[l].vtype != RWL_TYPE_BLOB)
1151+
{
1152+
rwlexecsevere(xev, &xev->rwm->code[pc].cloc
1153+
, "[rwlcoderun-writelob:%s;%s;%d]", xev->evar[l].vname, xev->evar[l].stype, l);
1154+
}
1155+
else
1156+
{
1157+
if (xev->rwm->lobdataexpr)
1158+
{
1159+
rwlexpreval(xev->rwm->code[pc].ceptr3, &xev->rwm->code[pc].cloc, xev, &xev->xqnum);
1160+
// rwl_identifier *ri = rwlidgetmx(xev, &xev->rwm->code[pc].cloc, l);
1161+
rwlwritelobo(xev
1162+
, rwlnuminvar(xev, xev->evar+l)->vptr // the OCILob *
1163+
, xev->evar[l].vdata // the db (i.e. rwl_cinfo *)
1164+
, &xev->xqnum // the string to write
1165+
, &xev->rwm->code[pc].cloc,
1166+
(ub8) xev->xqnum2.ival, codename);
1167+
}
1168+
else
1169+
{
1170+
sb4 l2;
1171+
l2 = rwlfindvarug2(xev, xev->rwm->code[pc].ceptr3, &xev->rwm->code[pc].ceint4
1172+
, codename);
1173+
rwl_identifier *ri = rwlidgetmx(xev, &xev->rwm->code[pc].cloc, l2);
1174+
rwlwritelobo(xev
1175+
, rwlnuminvar(xev, xev->evar+l)->vptr // the OCILob *
1176+
, xev->evar[l].vdata // the db (i.e. rwl_cinfo *)
1177+
, rwlnuminvar(xev, ri) // the string to write
1178+
, &xev->rwm->code[pc].cloc,
1179+
(ub8) xev->xqnum2.ival, codename);
1180+
rwlidrelmx(xev, &xev->rwm->code[pc].cloc, l2);
1181+
}
1182+
}
1183+
pc++;
1184+
}
1185+
break;
1186+
11381187
case RWL_CODE_READLOB:
11391188
{
11401189
sb4 l, l2;

src/rwlparser.y

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*
1212
* History
1313
*
14+
* johnkenn 06-mar-2024 - writelob with offset
1415
* johnkenn 06-nov-2023 - trigonometry sin, cos, atan2
1516
* bengsig 25-sep-2023 - ampersand bug fix
1617
* bengsig 20-sep-2023 - list iterator loop
@@ -2988,9 +2989,14 @@ statement:
29882989

29892990
| RWL_T_WRITELOB writelobhead maybewritelobtail terminator
29902991
{
2991-
if (rwm->loboffset)
2992+
if (rwm->loboffset && rwm->lobdataexpr)
29922993
{
2993-
rwlcodeaddpupup(rwm, RWL_CODE_WRITELOB, rwm->lobnam, rwm->lobvarn,
2994+
rwlcodeaddpupp(rwm, RWL_CODE_WRITELOB_O, rwm->lobnam
2995+
, rwm->lobvarn, rwm->lobwritedata, rwm->loboffset);
2996+
}
2997+
else if (rwm->loboffset)
2998+
{
2999+
rwlcodeaddpupup(rwm, RWL_CODE_WRITELOB_O, rwm->lobnam, rwm->lobvarn,
29943000
rwm->lobstringnam, rwm->lobstringvarn, rwm->loboffset);
29953001
}
29963002
else if (rwm->lobdataexpr)
@@ -3081,6 +3087,7 @@ writelobhead:
30813087
sb4 l;
30823088
rwm->lobvarn = RWL_VAR_NOTFOUND;
30833089
rwm->lobnam = rwm->inam;
3090+
rwm->loboffset = 0;
30843091
/* lookup the file and check it is a file */
30853092
l = rwlfindvar2(rwm->mxq, rwm->lobnam, RWL_VAR_NOGUESS, rwm->codename);
30863093
if (l>=0)
@@ -3103,6 +3110,7 @@ writelobhead:
31033110
{
31043111
rwl_estack *estk;
31053112
estk = rwlexprfinish(rwm);
3113+
rwm->lobdataexpr = 0;
31063114
if (rwm->codename)
31073115
{
31083116
rwm->lobdataexpr = 1;

src/rwlsql.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*
1212
* History
1313
*
14+
* johnkenn 06-mar-2024 - write lob with offset
1415
* johnkenn 18-dec-2023 - Stream with length and offset from lob locator
1516
* bengsig 4-oct-2023 - Only set cclass on sessionpool if explict
1617
* bengsig 4-oct-2023 - Don't drop session after banner print with session pool
@@ -4237,6 +4238,48 @@ void rwlwritelob(rwl_xeqenv *xev
42374238
}
42384239
}
42394240

4241+
void rwlwritelobo(rwl_xeqenv *xev
4242+
, OCILobLocator *lobp
4243+
, rwl_cinfo *db
4244+
, rwl_value *pnum
4245+
, rwl_location *loc
4246+
, ub8 offset
4247+
, text *fname
4248+
)
4249+
{
4250+
ub8 amtp = rwlstrlen(pnum->sval) + (ub8)offset;
4251+
if (!db)
4252+
{
4253+
rwlexecerror(xev, loc, RWL_ERROR_LOB_NOT_FILLED);
4254+
return;
4255+
}
4256+
if (!amtp)
4257+
{
4258+
// ORA-24801: illegal parameter value in OCI lob function
4259+
// if you try writing zero bytes to LOB
4260+
rwlexecerror(xev, loc, RWL_ERROR_ATTEMPT_ZERO_WRITE, db->vname);
4261+
return;
4262+
}
4263+
if (OCI_SUCCESS != (xev->status=
4264+
OCILobWrite2(db->svchp, xev->errhp, (void *)lobp
4265+
, &amtp
4266+
, 0 /*char_amtp*/
4267+
, (ub8)offset /*offset*/
4268+
, pnum->sval, amtp
4269+
, OCI_ONE_PIECE
4270+
, 0,0
4271+
, (ub2) 0, (ub1) SQLCS_IMPLICIT)))
4272+
{
4273+
rwldberror1(xev, loc, fname);
4274+
}
4275+
if (OCI_SUCCESS != (xev->status=
4276+
OCILobTrim2(db->svchp, xev->errhp, (void *)lobp
4277+
, amtp )))
4278+
{
4279+
rwldberror1(xev, loc, fname);
4280+
}
4281+
}
4282+
42404283
void rwlreadlob(rwl_xeqenv *xev
42414284
, OCILobLocator *lobp
42424285
, rwl_cinfo *db

test/401.rwl

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
$mute:29 # test clob
2+
$mute:120 $dformat:%20.15f
3+
$randseed:b00deadbeef
4+
5+
6+
function inslobs() return integer
7+
is
8+
clob cl1, cl2;
9+
integer id;
10+
string klokken;
11+
sql ins insert into hasclob(id,cl1,cl2)
12+
values (rwlseq.nextval, empty_clob(), empty_clob())
13+
returning id into :1;
14+
bindout 1 id;
15+
end;
16+
17+
18+
sql sel select cl1,cl2, to_char(sysdate,'HH24:MI:SS')
19+
from hasclob where id=:1;
20+
define 1 cl1, 2 cl2, 3 klokken;
21+
bind 1 id;
22+
end;
23+
24+
ins;
25+
sel;
26+
string lobstring1 := "short" || erlang2(100.0);
27+
writelob cl1, lobstring1;
28+
string lobstring2 := "long";
29+
writelob cl1, lobstring2, 30;
30+
writelob cl1, "even longer", 40;
31+
commit;
32+
return id;
33+
end;
34+
35+
private integer id1, id2;
36+
clob xl1;
37+
clob xl2;
38+
39+
procedure dosome()
40+
string(1000) sl1;
41+
string(1000) sl2;
42+
integer readlen := 14;
43+
integer offset := 1;
44+
string newstring := "verylongstring" || erlang2(100.0);
45+
46+
sql selthem
47+
select cl1 from hasclob
48+
where id = :1
49+
order by id;
50+
bind 1 id1;
51+
define 1 xl1;
52+
array 20;
53+
end;
54+
55+
id1 := inslobs();
56+
57+
for selthem loop
58+
readlob xl1, sl1;
59+
printline sl1;
60+
61+
readlob xl1, sl1, readlen, offset;
62+
printline sl1;
63+
64+
offset := 17;
65+
readlob xl1, sl1, readlen, offset;
66+
printline sl1;
67+
68+
offset := 1;
69+
readlen := 4;
70+
readlob xl1, sl1, readlen, offset;
71+
printline sl1;
72+
73+
offset := offset + 4;
74+
readlob xl1, sl1, readlen, offset;
75+
printline sl1;
76+
77+
offset := 30;
78+
readlob xl1, sl1, readlen, offset;
79+
printline sl1;
80+
81+
offset := 40;
82+
readlen := 20;
83+
readlob xl1, sl1, readlen, offset;
84+
printline sl1;
85+
end;
86+
87+
end;
88+
89+
dosome();
90+

test/test.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ then
4747
testlist="$*"
4848
else
4949
# note that 323..326 test CQN which we don't currently compile in
50-
testlist='1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364'
50+
testlist='1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 400 401'
5151
fi
5252

5353
diffokcount=0;
@@ -114,7 +114,7 @@ do
114114
42)
115115
pre='-c 0.1 testuserinfo.rwl testdefault.rwl testdrcp.rwl'
116116
;;
117-
20|21|22|69|41|68|72|74|76|81|88|400)
117+
20|21|22|69|41|68|72|74|76|81|88|400|401)
118118
pre='-c 0.1 testuserinfo.rwl testdefault.rwl'
119119
;;
120120
90)

test/testres/401.err.good

Whitespace-only changes.

test/testres/401.out.good

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
short 240.655644078437007 long
2+
short 240.6556
3+
078437007 l
4+
shor
5+
t 24
6+
long
7+
even longer

0 commit comments

Comments
 (0)