HP/Tandem TACL How to use the % as a value in the SQL like clause - sql

In my TACL, I'm trying to create a variable used as input to an SQLCI command. I want to use a LIKE clause with a % as a wildcard. Every time it replaces the % with a ? causing the SQL statement to not return the desired results.
Code snippitz:
?TACL macro
#Frame
#Set #informat plain
#Set #outformat pretty
#Push stoprun DC fidata var1 mailmast sqlvol sqlsvol IsOpen EMLFile ans emlline
#Push mailfile mfile likeit charaddr sqlin sqlout test
[#Def True text |body|-1]
[#Def False text |body|0]
Intervening code cut out to reduce length - the cutout code works
== select <program name> from <full mailmast filename> where mm_file_prefix
== like "<likename>%" for browse access;
[#If Not [StopRun]
|then|
#Setv test "~%"
#Set #trace -1
#Set SqlIn select mm_program_name from [mailmast] where mm_file_prefix
#appendv sqlin "like ""[LikeIt]~%"" for browse access;"
SQLCI/Inv Sqlin,outv sqlout/
] == end of if
When I run the code, I display the variables, and it has replaced the % with ?
-TRACE-
-19-st 1 v
Invoking variable :MAILMAST.1
#Set SqlIn select mm_program_name from $DATA5.SQL2510.MAILMAST where mm_file_p
refix
-TRACE-
-20-
#appendv sqlin "like ""[LikeIt]
^
-TRACE-
-20-
Invoking variable :LIKEIT.1
#appendv sqlin "like ""ED?"" for browse access;"
-TRACE-
-20-d test
?
-22-st 1 v
SQLCI/Inv Sqlin,outv sqlout/
-TRACE-
-23-d sqlin
select mm_program_name from $DATA5.SQL2510.MAILMAST where mm_file_prefix
like "ED?" for browse access;
-24-
Since the % is not there as a wildcard, this SQL statement fails to bring up the proper record.
The question is, how do I put a % into a TACL variable and not get it changed to a ?
Edited to replace duplicate code with the start of the TACL Macro - MEH

I really don't like answering my own question because that looks like I was just setting things up to make me look smart, but in continuing my research while waiting, I found the answer. See code snippitz below:
?TACL macro
#Frame
#Set #informat plain
#Set #outformat pretty
#Push stoprun DC fidata var1 mailmast sqlvol sqlsvol IsOpen EMLFile ans emlline
#Push mailfile mfile likeit charaddr sqlin sqlout test
[#Def True text |body|-1]
[#Def False text |body|0]
[#Def ascii struct
Begin
BYTE byt0 value 37;
CHAR pcent REDEFINES byt0;
End;
] == end of struct
Note the addition of the struct. This is to be able to assign a byte a decimal value of 37 (%) and redefine it as a character to be used in the like statement.
== select <program name> from <full mailmast filename> where mm_file_prefix
== like "<likename>%" for browse access;
[#If Not [StopRun]
|then|
#Set test [ascii:pcent]
#Set #trace -1
#Set SqlIn select mm_program_name from [mailmast] where mm_file_prefix
#append sqlin like "[LikeIt][ascii:pcent]" for browse access;
SQLCI/Inv Sqlin,outv sqlout/
] == end of if
Note the use of the struct [ascii:pcent] and this does work.
Thanks to all who read my question.

Related

Nextflow adding def function in to script

I have got errors like .command.sh: line 2: syntax error near unexpected token `('
/*
* Step 3
*/
chr_length = file(params.chr_length)
process create_bedgraph_and_bigwig {
publishDir "${params.outdir}/bedgraphandbigwig", mode: 'copy'
input:
set val(sample_id), file(vector_log) from vector_log_ch
set val(sample_id), file(target_query_bam) from target_query_bam_ch
file chr_length
output:
set val(sample_id), file("${sample_id}.bedgraph.log.txt") into bed_log_ch
set val(sample_id), file("${sample_id}.bed") into bed_ch
set val(sample_id), file("${sample_id}.clean.bed") into clean_bed_ch
set val(sample_id), file("${sample_id}.fragments.bed") into fragments_bed_ch
set val(sample_id), file("${sample_id}.sorted.fragments.bed") into sorted_fragments_bed_ch
shell:
'''
def fp = file(${vector_log})
def lines = fp.readLines()
def line3 = lines[3].split(' ')[4].toInteger()
def line4 = lines[4].split(' ')[4].toInteger()
def aln_sum = (10000/(line3 + line4)).toString()
bedtools bamtobed -bedpe -i !{target_query_bam} > !{sample_id}.bed 2>!{sample_id}.bedgraph.log.txt
awk '$1==$4 && $6-$2 < 1000 {{print $0}}' !{sample_id}.bed > !{sample_id}.clean.bed 2>!{sample_id}.bedgraph.log.txt
cut -f 1,2,6 !{sample_id}.clean.bed > !{sample_id}.fragments.bed 2>!{sample_id}.bedgraph.log.txt
sort -k 1,1 !{sample_id}.fragments.bed > !{sample_id}.sorted.fragments.bed
'''
}
The simple answer is to avoid using 'def' if the variable needs to be used in a shell definition or template. I couldn't actually find this after a quick search of the documentation, but I did find this note from the author:
Using groovy native string interpolation that would work, but when using the !{..} syntax scripts variable cannot be declared locally using the def keyword.
To summarise:
script/shell variable should be defensively declared in the local scope using the def keyboard
do not use def when:
i. the variable needs to be referenced as a output value
ii. the variable needs to be used in a shell template
https://github.com/nextflow-io/nextflow/issues/678#issuecomment-386206123

Karate: one liner json path expression not working

I have a two line json path expression that prints something and I want to put it all in one line:
Given path 'device/'
When method get
Then status 200
#This correctly prints the value:
And def device_search = $.device[?(#.manufacturer == 'a manufacturer')]
And print device_search[0].id
#This doesn't work (prints null):
And print $.device[?(#.manufacturer == 'a manufacturer')][0].id
Thanks!
This is not supported. Use 2 steps.
But if you insist, use karate.get().
And print karate.get("$.device[?(#.manufacturer == 'a manufacturer')][0].id")

How can I signal parsing errors with LPeg?

I'm writing an LPeg-based parser. How can I make it so a parsing error returns nil, errmsg?
I know I can use error(), but as far as I know that creates a normal error, not nil, errmsg.
The code is pretty long, but the relevant part is this:
local eof = lpeg.P(-1)
local nl = (lpeg.P "\r")^-1 * lpeg.P "\n" + lpeg.P "\\n" + eof -- \r for winblows compat
local nlnoeof = (lpeg.P "\r")^-1 * lpeg.P "\n" + lpeg.P "\\n"
local ws = lpeg.S(" \t")
local inlineComment = lpeg.P("`") * (1 - (lpeg.S("`") + nl * nl)) ^ 0 * lpeg.P("`")
local wsc = ws + inlineComment -- comments count as whitespace
local backslashEscaped
= lpeg.P("\\ ") / " " -- escaped spaces
+ lpeg.P("\\\\") / "\\" -- escaped escape character
+ lpeg.P("\\#") / "#"
+ lpeg.P("\\>") / ">"
+ lpeg.P("\\`") / "`"
+ lpeg.P("\\n") -- \\n newlines count as backslash escaped
+ lpeg.P("\\") * lpeg.P(function(_, i)
error("Unknown backslash escape at position " .. i) -- this error() is what I wanna get rid of.
end)
local Line = lpeg.C((wsc + (backslashEscaped + 1 - nl))^0) / function(x) return x end * nl * lpeg.Cp()
I want Line:match(...) to return nil, errmsg when there's an invalid escape.
LPeg itself doesn't provide specific functions to help you with error reporting. A quick fix to your problem would be to make a protected call (pcall) to match like this:
local function parse(text)
local ok, result = pcall(function () return Line:match(text) end)
if ok then
return result
else
-- `result` will contain the error thrown. If it is a string
-- Lua will add additional information to it (filename and line number).
-- If you do not want this, throw a table instead like `{ msg = "error" }`
-- and access the message using `result.msg`
return nil, result
end
end
However, this will also catch any other error, which you probably don't want. A better solution would be to use LPegLabel instead. LPegLabel is an extension of LPeg that adds support for labeled failures. Just replace require"lpeg" with require"lpeglabel" and then use lpeg.T(L) to throw labels where L is an integer from 1-255 (0 is used for regular PEG failures).
local unknown_escape = 1
local backslashEscaped = ... + lpeg.P("\\") * lpeg.T(unknown_escape)
Now Line:match(...) will return nil, label, suffix if there is a label thrown (suffix is the remaining unprocessed input, which you can use to compute for the error position via its length). With this, you can print out the appropriate error message based on the label. For more complex grammars, you would probably want a more systematic way of mapping the error labels and messages. Please check the documentation found in the readme of the LPegLabel repository to see examples of how one may do so.
LPegLabel also allows you to catch the labels in the grammar by the way (via labeled choice); this is useful for implementing things like error recovery. For more information on labeled failures and examples, please check the documentation.

How to fix UnboundLocalError: local variable 'file_lines' referenced before assignment

So this is my function which is meant to read the lines of text from a file.
This is extracted from a larger program hence some of the comments may seem out of place. Anyways I need to use the functions text and file_lines in numerous other functions but even after declaring them as global I still get the UnboundLocalError: local variable 'file_lines' referenced before assignment error and I don't know what to do.
import sys
text = []
case = ''
file_lines = []
def read_file(file): # function to read a file and split it into lines
global text #sets variable text as a global variable for use in multiple locations
global case #handles case sensitivity.
try: #tests the statement after colon
open(file)
except:
print('oops no file found bearing that name')
else:
while file == '': #if the file name is blank print error, this prevents program from crashing
print ('error')
filename = input('enter a file and its extension ie file.ext\n>>')
with open(file) as f : #opens filewith name
text = f.read() #read all lines of program text.
print ("file successfully read")
print('TEXT SENSITIVITY TURNED ON !!!!!!')
text = text.split('\n')# breaks lines in file into list instead of using ".readlines"
# so that the program doesn't count blank lines
case == True
global file_lines
file_lines = text
a function that tries to use the read_lines variable would be
def find_words(words):
line_num = 0 # to count the line number
number_of_word = 0
if case == False:
words = words.lower()
file_lines = [file_lines.lower() for file_lines in text]
while "" in file_lines:
file_lines.remove('')
for lines in file_lines:
line_num += 1
if words in lines: #checks each for the words being looks for
print(line_num,"...", text[line_num-1])
number_of_word = 1
if number_of_word == 0: #to check if the word is located in the file
print('Words not found')
In your function find_words you forgot to specify that find_lines is global. Try
def find_words(words):
global file_lines
line_num = 0 # to count the line number
The function errors because file_lines is not defined within the scope of find_words otherwise.

f.open() issue resulting in Unbound error for f.close()

I don't quite have an answer but I'm narrowing it down. Somehow I'm mixing/confusing types, I believe, between what is provided by commands like 'os.path' and type str().
As I've made the assignment of the logfile(s) globally, even though I can print it in the function, when the variable is used in fout = open(... it's actually a null that's being referenced, i.e. open() doesn't like/can't use the type it finds.
The error:
UnboundLocalError: local variable 'fout' referenced before assignment
I am simply writing a log of dot files (left on USB drives by OSX) for deletion, but the try/except is now falling over. First the original version.
working code:
logFile = "/Users/dee/Desktop/dotFile_names.txt"
try:
fout = open(logFile, 'w')
for line in dotFile_names:
fout.write(line)
except IOError as e:
print ("Error : %s not found." % fout)
finally:
fout.close()
Attempting better practice, I sought to put the log file specs and path as variables so they can be modified if need be - I hope to make it cross platform workable. these variables are at the head of the program, i.e. not in main(), but I pass them in and print() statements have shown me they are successfully being referenced. i.e. I get this printed:
/Users/dee/Desktop/dotFile_names.txt
Despite this the error I get is:
UnboundLocalError: local variable 'fout' referenced before assignment -
error points at the "fout.close()" line
Error producing code
logFilespec = "dotFile_names.txt"
fullLogFileSpec = []
userDesktop = os.path.join(os.path.expanduser('~'), 'Desktop')
fullLogFilespec = os.path.join(userDesktop, logFilespec)
try:
print "opening " + fullLogFilespec
fout = open(fullLogFileSpec, 'w')
for line in dotFile_names:
print "..", # are we executing this line..?
fout.write(line)
except IOError as e:
print ("Error : %s not found." % fout)
finally:
print "\nclosing " + fullLogFilespec
fout.close()
I've found that if I modify this line by converting to a string
fout = open(fullLogFileSpec, 'w')
fout = open(str(fullLogFileSpec), 'w')
the error goes away, BUT NO file is created on the Desktop!
At the very least I guess that I am passing something unrecognisable to fout = open() but it is not being caught by the except. Then when I pass something that does seem to allow fout =open() to work it seems to be a ghost?
So I figure I am lost between a String and whatever kind of reference/pointer os.path.expanduser() gives me.
I'm sure it's insanely simple. Before adding the str() code I also checked all indentation, removing them all and adding back using the editor indent hotkeys, just in case that was affecting things somehow.
OK, it looks like I was wearing my dumb glasses, I think declaring
fullLogFileSpec = []
as a list instead of a string was my error.
Similar as it is, having re-written it without that list declaration this code is working fine:
logfile_directory = os.path.join(os.path.expanduser('~'),'Desktop')
log_bf_file_spec = 'ItemsFoundByFolder_' + Deez_1.current_datetime() + '.txt'
log_by_folder = os.path.join(logfile_directory, log_bf_file_spec)
the function later calls, with no error:
fout_by_folder = open(log_by_folder, 'w')