Un Wrap Oracle Package - sql

I need to un wrap an Oracle Package created by some other dev.
I have the Prackage created in my DB, but in encrypted format.
The reason i need is, original Developer has left the organization and now the procedure define in the package needs to be redefine with updated changes in DB Structure and logic.
Can some one help me as How can i un wrap the package in oracle.

You can paste the code here and it will unwrap it for you.
Be advised you will lose all comments but variable names will remain.
But for fun lets test the logic.
First create the procedure:
sqlplus testing/testtest
SQL*Plus: Release 11.2.0.3.0 Production on Fri Oct 10 08:36:06 2014
Copyright (c) 1982, 2011, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> create or replace procedure AA as
2 begin
3 null;
4 /*comments*/
5 end;
6 /
Procedure created.
Next we will save the procedure into the OS:
SQL> save aa.sql
Created file aa.sql
SQL> exit
Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
oracle#HOSTNAME:/home/oracle/USER/wrapTest> ll
total 12K
drwxr-x---. 4 oracle oinstall 4.0K Oct 10 08:36 ../
-rw-r-----. 1 oracle oinstall 66 Oct 10 08:37 aa.sql
drwxr-x---. 2 oracle oinstall 4.0K Oct 10 08:37 ./
After saving it we will use the seeded wrap utility to obfuscate the package:
oracle#HOSTNAME:/home/oracle/USER/wrapTest> wrap iname=aa.sql oname=aa.pls
PL/SQL Wrapper: Release 11.2.0.3.0- 64bit Production on Fri Oct 10 08:37:29 2014
Copyright (c) 1993, 2009, Oracle. All rights reserved.
Processing aa.sql to aa.pls
Now lets see what it looks like:
oracle#HOSTNAME:/home/oracle/USER/wrapTest> cat aa.
aa.pls aa.sql
oracle#HOSTNAME:/home/oracle/USER/wrapTest> cat aa.pls
create or replace procedure AA wrapped
a000000
1f
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
22 55
7weeW1mRAdYVG9cX0WEujCaQghIwg5nnm7+fMr2ywFy49cO4dIvAwDL+0oabmYEILYsGwIHH
LcmmpnWE55Q=
/
So we copy that code into that link and this is what it looks like:
As you can see we lost the comments but retrieved the code.

All wrapping is, is a base64 encoded Caesar-ciphered compressed string. So if you don't want to paste your code into a website:
import javax.xml.bind.DatatypeConverter;
import java.util.zip.InflaterInputStream;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.FileReader;
public class Unwrap {
static public void main(String[] args) throws Exception {
byte[] charmap = new byte[] {
(byte)0X3d, (byte)0X65, (byte)0X85, (byte)0Xb3, (byte)0X18, (byte)0Xdb, (byte)0Xe2, (byte)0X87, (byte)0Xf1, (byte)0X52, (byte)0Xab, (byte)0X63, (byte)0X4b, (byte)0Xb5, (byte)0Xa0, (byte)0X5f, (byte)0X7d, (byte)0X68, (byte)0X7b, (byte)0X9b, (byte)0X24, (byte)0Xc2, (byte)0X28, (byte)0X67, (byte)0X8a, (byte)0Xde, (byte)0Xa4, (byte)0X26, (byte)0X1e, (byte)0X03, (byte)0Xeb, (byte)0X17
, (byte)0X6f, (byte)0X34, (byte)0X3e, (byte)0X7a, (byte)0X3f, (byte)0Xd2, (byte)0Xa9, (byte)0X6a, (byte)0X0f, (byte)0Xe9, (byte)0X35, (byte)0X56, (byte)0X1f, (byte)0Xb1, (byte)0X4d, (byte)0X10, (byte)0X78, (byte)0Xd9, (byte)0X75, (byte)0Xf6, (byte)0Xbc, (byte)0X41, (byte)0X04, (byte)0X81, (byte)0X61, (byte)0X06, (byte)0Xf9, (byte)0Xad, (byte)0Xd6, (byte)0Xd5, (byte)0X29, (byte)0X7e
, (byte)0X86, (byte)0X9e, (byte)0X79, (byte)0Xe5, (byte)0X05, (byte)0Xba, (byte)0X84, (byte)0Xcc, (byte)0X6e, (byte)0X27, (byte)0X8e, (byte)0Xb0, (byte)0X5d, (byte)0Xa8, (byte)0Xf3, (byte)0X9f, (byte)0Xd0, (byte)0Xa2, (byte)0X71, (byte)0Xb8, (byte)0X58, (byte)0Xdd, (byte)0X2c, (byte)0X38, (byte)0X99, (byte)0X4c, (byte)0X48, (byte)0X07, (byte)0X55, (byte)0Xe4, (byte)0X53, (byte)0X8c
, (byte)0X46, (byte)0Xb6, (byte)0X2d, (byte)0Xa5, (byte)0Xaf, (byte)0X32, (byte)0X22, (byte)0X40, (byte)0Xdc, (byte)0X50, (byte)0Xc3, (byte)0Xa1, (byte)0X25, (byte)0X8b, (byte)0X9c, (byte)0X16, (byte)0X60, (byte)0X5c, (byte)0Xcf, (byte)0Xfd, (byte)0X0c, (byte)0X98, (byte)0X1c, (byte)0Xd4, (byte)0X37, (byte)0X6d, (byte)0X3c, (byte)0X3a, (byte)0X30, (byte)0Xe8, (byte)0X6c, (byte)0X31
, (byte)0X47, (byte)0Xf5, (byte)0X33, (byte)0Xda, (byte)0X43, (byte)0Xc8, (byte)0Xe3, (byte)0X5e, (byte)0X19, (byte)0X94, (byte)0Xec, (byte)0Xe6, (byte)0Xa3, (byte)0X95, (byte)0X14, (byte)0Xe0, (byte)0X9d, (byte)0X64, (byte)0Xfa, (byte)0X59, (byte)0X15, (byte)0Xc5, (byte)0X2f, (byte)0Xca, (byte)0Xbb, (byte)0X0b, (byte)0Xdf, (byte)0Xf2, (byte)0X97, (byte)0Xbf, (byte)0X0a, (byte)0X76
, (byte)0Xb4, (byte)0X49, (byte)0X44, (byte)0X5a, (byte)0X1d, (byte)0Xf0, (byte)0X00, (byte)0X96, (byte)0X21, (byte)0X80, (byte)0X7f, (byte)0X1a, (byte)0X82, (byte)0X39, (byte)0X4f, (byte)0Xc1, (byte)0Xa7, (byte)0Xd7, (byte)0X0d, (byte)0Xd1, (byte)0Xd8, (byte)0Xff, (byte)0X13, (byte)0X93, (byte)0X70, (byte)0Xee, (byte)0X5b, (byte)0Xef, (byte)0Xbe, (byte)0X09, (byte)0Xb9, (byte)0X77
, (byte)0X72, (byte)0Xe7, (byte)0Xb2, (byte)0X54, (byte)0Xb7, (byte)0X2a, (byte)0Xc7, (byte)0X73, (byte)0X90, (byte)0X66, (byte)0X20, (byte)0X0e, (byte)0X51, (byte)0Xed, (byte)0Xf8, (byte)0X7c, (byte)0X8f, (byte)0X2e, (byte)0Xf4, (byte)0X12, (byte)0Xc6, (byte)0X2b, (byte)0X83, (byte)0Xcd, (byte)0Xac, (byte)0Xcb, (byte)0X3b, (byte)0Xc4, (byte)0X4e, (byte)0Xc0, (byte)0X69, (byte)0X36
, (byte)0X62, (byte)0X02, (byte)0Xae, (byte)0X88, (byte)0Xfc, (byte)0Xaa, (byte)0X42, (byte)0X08, (byte)0Xa6, (byte)0X45, (byte)0X57, (byte)0Xd3, (byte)0X9a, (byte)0Xbd, (byte)0Xe1, (byte)0X23, (byte)0X8d, (byte)0X92, (byte)0X4a, (byte)0X11, (byte)0X89, (byte)0X74, (byte)0X6b, (byte)0X91, (byte)0Xfb, (byte)0Xfe, (byte)0Xc9, (byte)0X01, (byte)0Xea, (byte)0X1b, (byte)0Xf7, (byte)0Xce };
String line;
BufferedReader br = new BufferedReader(new FileReader(args[0]));
int l = 0;
String s = "";
while ((line = br.readLine()) != null) {
if (l>0) {
l -= line.length()+1;
s += line;
} else if (l<0) {
l = 0;
byte[] b = DatatypeConverter.parseBase64Binary(s);
byte[] c = new byte[b.length-20];
for (int i = 20; i < b.length; i++)
c[i-20] = (byte)(charmap[b[i]&255]);
InputStream is = new InflaterInputStream(new ByteArrayInputStream(c));
byte[] buffer = new byte[1000];
int len;
while((len = is.read(buffer)) > 0)
System.out.write(buffer, 0, len);
}
if (line.matches("^[0-9a-f]+ ([0-9a-f]+)$")) {
l = Integer.parseInt(line.substring(1+line.lastIndexOf(' ')),16);
s = "";
}
}
}
}

If you are using SQL Developer, you can install an add-in PL/SQL Unwrapper for SQL Developer from Salvis to unwrap the proc. ref. https://github.com/Trivadis/plsql-unwrapper-sqldev
Step by Step:
Open SQL Developer
Help > Check for Updates, click Add
Set
Name=Salvis
Location=http://update.salvis.com/
then OK, then check Salvis, then Next
Let it add and update and restart SQL Developer
After restart, find a procedure that is wrapped and open it in the editor
Right Click the editor and new option "Unwrap" is presented, click it and voila your proc should be plain text.
We were struggling with a situation where an Oracle ASP.NET Membership provider proc ora_aspnet_PPU_SetPgSettings was not working like its SQL Server counterpart. After unwrapping it, we discovered a bug there and we were able to fix.

Try this page: http://www.codecrete.net/UnwrapIt/
There you can simply paste your code.

Related

How can I use existing database in SERENE Core?

I already have a database in SQL Server 2019 express and I would love to be able to use it in SERENE, how should I do it?
The Migration helper checks, if the database of the connection string exists. if yes data for migration will not be executed. Switch of this check in Line 205 in file Datamigrations.cs of :
if (!isOracle && cs.ConnectionString.IndexOf(typeof(DataMigrations).Namespace +
#"_" + databaseKey + "_v1", StringComparison.OrdinalIgnoreCase) < 0)
{
// SkippedMigrations = true;
// return;
}

How to convert PDF with images which I don't care about to text?

I'm trying to convert pdf to text files. The problem is that those pdf contain images, which I don't care about (this is the type of file I want to extract (https://www.sia.aviation-civile.gouv.fr/pub/media/store/documents/file/l/f/lf_sup_2020_213_fr.pdf). Note that if I do copy/paste with my mouse, it work quite well (except the line break), so I'd guess that it's possible. Most of the answer I found online work pretty well on dummy pdf with text only, but give especially bad result on the map.
For instance, something like this
from tika import parser # pip install tika
raw = parser.from_file('test2.pdf')
print(raw['content'])
works well for retrieving the text, but I have a lot of trash like this :
ERY
CTR
3
CH
A
which appear because of the map.
Something like this, which work by converting the pdf to images and then reading the images, face the same problem (I found it on a very similar thread on stackoverflow, but there is no answer) :
import pytesseract as pt
from PIL import Image
import sys
def convert(name):
pages = convert_from_path(name, dpi=200)
for idx,page in enumerate(pages):
page.save('page'+str(idx)+'.jpg', 'JPEG')
quote = Image.open('page'+str(idx)+'.jpg')
text = pt.image_to_string(quote, lang="fra")
file_ex = open('page'+str(idx)+'.text',"w")
file_ex.write(text)
file_ex.close()
if __name__ == '__main__':
convert(sys.argv[1])
Finally, I tried to remove the image first, and then using one of the solutions above, but it didn't work better :
from tika import parser # pip install tika
from PyPDF2 import PdfFileWriter, PdfFileReader
# Remove the images
inputStream = open("lf_sup_2020_213_fr.pdf", "rb")
outputStream = open("test3.pdf", "wb")
src = PdfFileReader(inputStream)
output = PdfFileWriter()
[output.addPage(src.getPage(i)) for i in range(src.getNumPages())]
output.removeImages()
output.write(outputStream)
outputStream.close()
# Read from pdf without images
raw = parser.from_file('test2.pdf')
print(raw['content'])
Do you know how to solve this ? It can be in any language.
Thanks
One approach you could try is to use a toolkit capable of parsing the text characters in the PDF then use the object properties to try and remove the unwanted map labels while keeping the text characters required.
For example, the ParsePages method from LEADTOOLS PDF toolkit (which is what I am familiar with since I work for the vendor of this toolkit) can be used to obtain the text from the PDF:
using (PDFDocument document = new PDFDocument(pdfFileName))
{
PDFParsePagesOptions options = PDFParsePagesOptions.All;
document.ParsePages(options, 1, -1);
using (StreamWriter writer = File.CreateText(txtFileName))
{
IList<PDFObject> objects = document.Pages[0].Objects;
writer.WriteLine("Objects: {0}", objects.Count);
foreach (PDFObject obj in objects)
{
if (obj.TextProperties.IsEndOfLine)
writer.WriteLine(obj.Code);
else
writer.Write(obj.Code);
}
writer.WriteLine("---------------------");
}
}
This will obtain all the text in the PDF for the first page, with the unwanted results as you mentioned. Here is an excerpt below:
Objects: 3918
5
91L
F5
4
1 LF
N
OY
L2
1AM
TService
8
26
1de l’Information
0
B09SUP AIP 213/20
7
Aéronautique
Date de publication : 05 NOV
e-mail : sia.qualite#aviation-civile.gouv.fr
Internet : www.sia.aviation-civile.gouv.fr
141
17˚
82
N20
9Objet : Création de 4 zones réglementées temporaires (ZRT) pour l’exercice VOLOPS en région de Chambéry
En vigueur : Du mercredi 25 Novembre 2020 au vendredi 04 décembre 2020
More code can be used to examine the properties for each parsed character:
writer.WriteLine(" ObjectType: {0}", obj.ObjectType.ToString());
writer.WriteLine(" Bounds: {0}, {1}, {2}, {3}", obj.Bounds.Left, obj.Bounds.Top, obj.Bounds.Right, obj.Bounds.Bottom);
writer.WriteLine(" TextProperties.FontHeight: {0}", obj.TextProperties.FontHeight.ToString());
writer.WriteLine(" TextProperties.FontIndex: {0}", obj.TextProperties.FontIndex.ToString());
writer.WriteLine(" Code: {0}", obj.Code);
writer.WriteLine("------");
This will give the properties for each character:
Objects: 3918
ObjectType: Text
Bounds: -60.952693939209, 1017.25231933594, -51.8431816101074, 1023.71826171875
TextProperties.FontHeight: 7.10454273223877
TextProperties.FontIndex: 48
Code: 5
------
Using these properties, the unwanted text might be filtered using their properties. For example, I noticed that the FontHeight for a good portion of the unwanted text is around 7 PDF units, so the first code might be altered to avoid extracting any text smaller than 7.25 PDF units:
foreach (PDFObject obj in objects)
{
if (obj.TextProperties.FontHeight > 7.25)
{
if (obj.TextProperties.IsEndOfLine)
writer.WriteLine(obj.Code);
else
writer.Write(obj.Code);
}
}
The extracted output would give a better result, an excerpt follows:
Objects: 3918
Service
de l’Information
SUP AIP 213/20
Aéronautique
Date de publication : 05 NOV
e-mail : sia.qualite#aviation-civile.gouv.fr
Internet : www.sia.aviation-civile.gouv.fr
Objet : Création de 4 zones réglementées temporaires (ZRT) pour l’exercice VOLOPS en région de Chambéry
En vigueur : Du mercredi 25 Novembre 2020 au vendredi 04 décembre 2020
Lieu : FIR : Marseille LFMM - AD : Chambéry Aix-Les-Bains LFLB, Chambéry Challes les Eaux LFLE
ZRT LE SIRE, MOTTE CASTRALE, ALLEVARD
*
C
D
E
In the end, you will have to try and come up with a good criteria to filter out the unwanted text without removing the text you need to keep, using this approach.

PhpSpreadsheet's and PHP 7 > ZipArchive::close failure to create tempory file

At work, we use PhpSpreadsheet to generate some Excel file (we use it to be able to provide some export).
Here is the simple code I use (based on some example given but PhpSpreadsheet) to generate a file:
<?php
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
include_once '../../../libs/includes.inc';
/** #var array $_POST */
$_POST = db::encodeHTMLPost($_POST);
/** #var string $httpReferer */
$httpReferer = $_SERVER['HTTP_REFERER'];
if (strstr($httpReferer, '?')) {
$httpReferer = explode('?', $httpReferer);
$httpReferer = $httpReferer[0];
}
try {
/** #var Spreadsheet $spreadsheet */
$spreadsheet = new Spreadsheet();
//$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
// Set the document properties
$spreadsheet
->getProperties()
->setCreator('Christina')
->setLastModifiedBy('Christina')
->setTitle('Test XLSX')
->setSubject('Here is the test')
->setDescription('Test document for Office 2007 XLSX, generated using PHP classes.')
->setKeywords('office 2007 openxml php')
->setCategory('Test result file');
$spreadsheet->setActiveSheetIndex(0)
->setCellValue('A1', 'Hello')
->setCellValue('B2', 'World')
->setCellValue('C1', 'Here')
->setCellValue('D2', 'test');
$spreadsheet->getActiveSheet()->setTitle('A simple test');
$spreadsheet->setActiveSheetIndex(0);
// Redirect output to a client’s web browser (Xlsx)
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="01simple.xlsx"');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
header('Cache-Control: max-age=1');
// If you're serving to IE over SSL, then the following may be needed
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header('Pragma: public'); // HTTP/1.0
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save('php://output');
exit;
} catch (Exception $e) {
var_dump($e);
}
Unfortunately, it returns an error in the generate Excel file:
Warning: ZipArchive::close(): Failure to create temporary file: No such file or directory in /Applications/XAMPP/xamppfiles/htdocs/bdoparticipantenweekend.nl/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php on line 409
I understand the error, I just don't know how to fix it.
I'm the only one to have this error at the office, of course.. I'm the only one to use PHP 7
I made some research, apparently PHP 7 as another behaviour about Zip::close(): https://www.php.net/manual/en/ziparchive.close.php#119960
Is somebody have a clue how to fix this ?
NB: PhpSpreadsheet is update at the version 1.8.2 (the latest one)
Your path is wrong or you have not the permission to write into the path. Change the destination path or the permissions.

Cannot use threads to insert data to PostgreSQL with DBIish. What's going wrong?

Edit: This was solved by moritz. I've added a note to the code on the line that's wrong.
My application is a web server talking to a game client. The server is multithreaded, which Postgres allows. When loading client data into the database, I noticed parallel requests fail with several different errors, none of which make sense to me.
This short-ish test case dumps a nested hash into the database. When run without start, it works perfectly. When run with threads, it almost always gives one or more of the following errors:
DBDish::Pg: Error: (7) in method prepare at
D:\rakudo\share\perl6\site\sources\BAD7C1548F63C7AA7BC86BEDDA0F7BD185E141AD
(DBDish::Pg::Connection) line 48 in block at testcase.p6 line 62
in sub add-enum-mappings at testcase.p6 line 59 in block at
testcase.p6 line 91
DBDish::Pg: Error: ERROR: prepared statement
"pg_3448_16" already exists (7) in method prepare at
D:\rakudo\share\perl6\site\sources\BAD7C1548F63C7AA7BC86BEDDA0F7BD185E141AD
(DBDish::Pg::Connection) line 46 in block at testcase.p6 line 62
in sub add-enum-mappings at testcase.p6 line 59 in block at
testcase.p6 line 91
DBDish::Pg: Error: Wrong number of arguments to
method execute: got 1, expected 0 (-1) in method enter-execute at
D:\rakudo\share\perl6\site\sources\65FFB78EFA3030486D1C4D339882A410E3C94AD2
(DBDish::StatementHandle) line 40 in method execute at
D:\rakudo\share\perl6\site\sources\B3190B6E6B1AA764F7521B490408245094C6AA87
(DBDish::Pg::StatementHandle) line 52 in sub add-enum-mappings at
testcase.p6 line 54 in block at testcase.p6 line 90
message type 0x31 arrived from server while idle
message type 0x5a arrived from server while idle
message type 0x74 arrived from server while idle
message type 0x6e arrived from server while idle
message type 0x5a arrived from server while idle
Here's the code. (If you choose to run it, remember to set the right password. It creates/manipulates a table called "enummappings", but does nothing else.) The meat is in add-enum-mappings(). Everything else is just setup. Oh, and dbh() creates a separate DB connection for each thread. This is necessary, according to the PostgreSQL docs.
#!/usr/bin/env perl6
use DBIish;
use Log::Async;
my Lock $db-lock;
my Lock $deletion-lock;
my Lock $insertion-lock;
INIT {
logger.send-to($*ERR);
$db-lock .= new;
$deletion-lock .= new;
$insertion-lock .= new;
}
# Get a per-thread database connection.
sub dbh() {
state %connections;
my $dbh := %connections<$*THREAD.id>; # THIS IS WRONG. Should be %connections{$*THREAD.id}.
$db-lock.protect: {
if !$dbh.defined {
$dbh = DBIish.connect('Pg', :host<127.0.0.1>, :port(5432), :database<postgres>,
:user<postgres>, :password<PASSWORD>);
}
};
return $dbh;
}
sub create-table() {
my $name = 'enummappings';
my $column-spec =
'enumname TEXT NOT NULL, name TEXT NOT NULL, value INTEGER NOT NULL, UNIQUE(enumname, name)';
my $version = 1;
my $sth = dbh.prepare("CREATE TABLE IF NOT EXISTS $name ($column-spec);");
$sth.execute;
# And add the version number to a version table:
dbh.execute:
"CREATE TABLE IF NOT EXISTS tableversions (name TEXT NOT NULL UNIQUE, version INTEGER NOT NULL);";
$sth = dbh.prepare:
'INSERT INTO tableversions (name, version) VALUES (?, ?)
ON CONFLICT (name)
DO
UPDATE SET version = ?;';
$sth.execute($name, $version, $version);
}
sub add-enum-mappings($enumname, #names, #values --> Hash) {
$deletion-lock.protect: {
my $sth = dbh.prepare('DELETE FROM enummappings WHERE enumname = ?;');
$sth.execute($enumname);
};
my #rows = (^#names).map: -> $i {$enumname, #names[$i], #values[$i]};
info "Inserting #rows.elems() rows...";
$insertion-lock.protect: {
my $sth = dbh.prepare('INSERT INTO enummappings (enumname,name,value) VALUES '~
('(?,?,?)' xx #rows.elems).join(',') ~ ';');
$sth.execute(#rows>>.list.flat);
};
return %(status => 'okay');
}
# Create a bunch of long enums with random names, keys, and values.
sub create-enums(--> Hash[Hash]) {
my #letters = ('a'..'z', 'A'..'Z').flat;
my Hash %enums = ();
for ^36 {
my $key = #letters.pick(10).join;
for ^45 {
my $sub-key = #letters.pick(24).join;
%enums{$key}{$sub-key} = (0..10).pick;
}
}
return %enums;
}
sub MAIN() {
create-table;
await do for create-enums.kv -> $enum-name, %enum {
start {
add-enum-mappings($enum-name, %enum.keys, %enum.values);
CATCH { default { note "Got error adding enum: " ~ .gist; } }
};
}
}
I'm on Windows 10, with a 8-core computer. I know I could insert the data single-threadedly, but what if the game gets a hundred connections at once? I need to fix this for good.
I suspect your problem is here:
my $dbh := %connections<$*THREAD.id>;
The %hash<...> syntax is only for literals. You really need to write %connections{$*THREAD.id}.
With your error in place, you have just one DB connection that's shared between all threads, and I guess that's what DBIish (or the underlying postgresql C client library) is unhappy about.

Writing a Groovy Script to execute this command to PostgresDB

I currently am using SOAPUI 4.0 Pro to hit a Postgresdb on a specific host. I have modified my properties file to include port, username, and password and name of database. Here is my query below:
SELECT
eis_entity.local_id,
eis_trait_instance_history.trait_value,
eis_identifier_domain.identifier,
eis_identifier_domain.label
FROM
public.eis_entity,
public.eis_trait_instance_history,
public.eis_version_label,
public.eis_identifier_domain
WHERE eis_identifier_domain.eis_identifier_domain_key = eis_entity.eis_identifier_domain_key
AND eis_entity.eis_entity_key=eis_version_label.eis_entity_key
AND eis_version_label.eis_version_label_key=eis_trait_instance_history.eis_version_label_key
AND eis_trait_instance_history.trait_value='<name of patient>';
How would I create a groovy script for the query above?
Assuming you can pick up Groovy SQL basics and have a handle on a sql instance...
sql = Sql.newInstance(...)
def List eisEntityList = sql.rows("""
SELECT eis_entity.local_id,
eis_trait_instance_history.trait_value,
eis_identifier_domain.identifier,
eis_identifier_domain.label
FROM public.eis_entity,
public.eis_trait_instance_history,
public.eis_version_label,
public.eis_identifier_domain
WHERE eis_identifier_domain.eis_identifier_domain_key = eis_entity.eis_identifier_domain_key
AND eis_entity.eis_entity_key = eis_version_label.eis_entity_key
AND eis_version_label.eis_version_label_key = eis_trait_instance_history.eis_version_label_key
AND eis_trait_instance_history.trait_value = ''
""")
if (eisEntityList?.size() > 0) {
eisEntityList.each {
// do something with each item...
}
}