Perl: why aren't my environment variables being set? - database

I am trying to connect to an Oracle DB using perl-DBD-Oracle. I need to have the following environmental variables set:
export LD_LIBRARY_PATH=/home/x/lib/ora10gclient
export TNS_ADMIN=/home/x/lib/ora10gclient
export PATH=/home/x/lib/ora10gclient:/usr/kerberos/bin:/home/x/bin:/home/x/bin64:/usr/local/sbin:/sbin:/usr/sbin:/usr/local/bin:/bin:/usr/bin
export ORACLE_HOME=/home/x/lib/ora10gclient
This script is run by a headless user and I have placed those lines in the .bash_profile file for that headless user.
The problem is, the headless user ssh's into the machine where this script is run and the bash profile isn't sourced. So I thought I would just set those environment variables in the BEGIN block of the script like so:
BEGIN {
$ENV{'LD_LIBRARY_PATH'} = '/home/x/lib/ora10gclient';
$ENV{'TNS_ADMIN'} = '/home/x/lib/ora10gclient';
$ENV{'PATH'} = '/home/x/lib/ora10gclient:/usr/kerberos/bin:/home/x/bin:/home/x/bin64:/usr/local/sbin:/sbin:/usr/sbin:/usr/local/bin:/bin:/usr/bin';
$ENV{'ORACLE_HOME'} = '/home/x/lib/ora10gclient';
}
However, the script fails claiming it can't find Oracle.pm, something that it doesn't do when those environment variables are set.
I've sprinkled print statements throughout the script to confirm that it does indeed set the environment variables. And even printed the environment variables out the line before attempting to create a handle to the DB (which is where the script fails) and confirmed that they are still set to the correct values.
I'm not spawning any child processes either. Below is a simplified version of my script which fails in the same manner.
#!/usr/local/bin/perl
use warnings;
use strict;
BEGIN {
$ENV{'LD_LIBRARY_PATH'} = '/home/x/lib/ora10gclient';
$ENV{'TNS_ADMIN'} = '/home/x/lib/ora10gclient';
$ENV{'PATH'} = '/home/x/lib/ora10gclient:/usr/kerberos/bin:/home/x/bin:/home/x/bin64:/usr/local/sbin:/sbin:/usr/sbin:/usr/local/bin:/bin:/usr/bin';
$ENV{'ORACLE_HOME'} = '/home/x/lib/ora10gclient';
}
use DBI;
testConnect();
sub testConnect {
my $orclPort = 1521;
my $orclHost = '<oraclehost>';
my $orclUser = '<user>';
my $srvName = '<servicename>';
my $db = "DBI:Oracle:service_name=$srvName;host=$orclHost;port=$orclPort";
my $orclDBHndl = DBI->connect($db, $orclUser, $orclUser) or die "could not connect: $DBI::errstr\n";
}
Any ideas on what might be the problem?

LD_LIBRARY_PATH needs to be set before perl starts. Write a shell wrapper that sets the variables and then launches your script.
Also see this thread for alternatives and other links to explanations.

Related

running shell command through ReactJs code

I have a file stored in local computer and a printer connected too. So generally if I want to give a print of the file to the connected printer, I would run following command in command prompt:
cd <path where the file is locally stored>
copy <filename.ext> <portname in which the printer is connected>
So for example, if I have a file at path /Users/chandrani.chatterjee/Desktop/TestFolder and a printer connected at port lpt1 I would write following commands in command prompt
cd /Users/chandrani.chatterjee/Desktop/TestFolder
copy testfilename.txt lpt1
So this would print my testfilename.txt
No I want to achieve this on a button click in ReactJs.
I searched the web and found out about shellJs but I am not sure on how to fire the commands using it.
I tried
var sh = require('shelljs');
const { stdout, stderr, code } = sh.exec('cd /Users/chandrani.chatterjee/Desktop/TestFolder', { silent: true });
I also tried
var sh = require('shelljs');
var output = sh.exec('java -version', {silent:true}).stdout;
but getting error in both the scenarios
Cannot read property 'stdout' of null
How to do this correctly?
EDIT:
For example in .Net the same can be achieved with below code:
function create_send_file() {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var s = fso.CreateTextFile("c:\\FilePrn\\label.prn", true);
s.WriteLine("some string");
s.Close();
var newpath = fso.CopyFile("c:\\FilePrn\\label.prn", "lpt1");
}
Your Reactapp is running in the browser so doesn't have access to your shell.
To do this you will need to create a web service that React app can call to. Here you can execute the shell command return the result to the React in the browser.

Run ddl script from file in Groovy

I working with Spock and Groovy in order to test my application. I should need to run a ddl script before to run every test.
To execute the script from Groovy I am using the following code:
def scriptToExecute = './src/test/groovy/com/sql/createTable.sql'
def sqlScriptToExecuteString = new File(scriptToExecute).text
sql.execute(sqlScriptToExecuteString)
The createTable.sql is a complex script that do several drop and create operation ( of course it is multiline ). When I try to execute it I got the following exception:
java.sql.SQLSyntaxErrorException: ORA-00911: invalid character
To notice that the ddl is correct since that it has been checked running it on the same DB that I am connecting with groovy.
Any Idea how to resolve the problem?
I think JDBC does not support this, but there are tools/libraries that could help, see this answer for Java.
In Groovy, using this JDBC script runner would be something like:
Connection con = ....
def runner = new ScriptRunner(con, [booleanAutoCommit], [booleanStopOnerror])
def scriptFile = new File("createTable.ddl")
scriptFile.withReader { reader ->
runner.runScript(reader)
}
Or, if your script is "simple enough" (ie no comments, no semicolons other than separating statements...), you can load the text, split it around ; and execute using sql.withBatch, something like that:
def scriptText = new File("createTable.ddl").text
sql.withBatch { stmt ->
scriptText.split(';').each { order ->
stmt.addBatch order.trim()
}
}
If you can't get it done in JDBC (See Hugues' answer), consider executing sqlplus from your Groovy program.
["sqlplus", CREDENTIALS, "#"+scriptToExecute].execute()

Determine if SoapUI (ReadyAPI) is started via testrunner.bat or by the user (running in UI-mode)

Is it possible to determine if SoapUI (ReadyAPI) is started
via testrunner.bat
by the user (running in interactive UI-mode)
I know that you can retrieve the current environment using this groovy script code:
def env = testRunner.testCase.testSuite.project.activeEnvironment.name
However I wonder what value this will return when running via the command-line (testrunner.bat) ; will it return the active environment from the test project, or will it be null/empty ?
Update (use-case)
The user case is that depending on the way the tests are run. In case of testrunner.bat I want to be able to set the environment to a fixed value. Else I want enable the user to select the environment manually.
Note that the some environment settings like EndPoints for each environment are defined a pre-defined XML file.
Update (possible solution)
#albciff
On the latest version from ReadyAPI (1.9.0), this does not work as you described.
testrunner.bat returns SoapUIProTestCaseRunner
running via ui returns InProcessSoapUIProTestCaseRunner
When using this code:
def runner = com.eviware.soapui.SoapUI.getCmdLineRunner();
log.info "runner = [" + runner.getClass().getSimpleName() + "]"
A more easier way to detect this would be:
if (com.eviware.soapui.SoapUI.isCommandLine()) {
// todo
}
Found at community.smartbear.com
I think that there is no property inside SOAPUI to difference between how it's executed. In fact I test your proposal:
def env = testRunner.testCase.testSuite.project.activeEnvironment.name
And it returns Default for both cases (from UI and using testrunner).
A possible workaround to do so, it's for example to pass a project property parameter in the CLI of the testrunner execution; and then in your code check for this parameter to detect how the project is launched.
To pass a project property you've to use -Pname=value. So for example launch the testrunner using:
testrunner -r -I <path/To/yourProject.xml> -PrunningBy=testRunner
And then in your code you can get the property and check for this content to decide if it's running by testrunner or from the UI, something like:
def runningBy = testRunner.testCase.testSuite.project.getPropertyValue('runningBy')
if(runningBy){
// it's not null so is launched from testRunner
}else{
// it's null, so is launched from UI
}
UPDATE
After reviewing the API seems that it's possible thought the follow method:
com.eviware.soapui.SoapUI.getCmdLineRunner()
It returns null when executed from UI, instead when executed from testrunner it returns and instance of com.eviware.soapui.tools.CmdLineRunner.
So you can use something like:
def clr = com.eviware.soapui.SoapUI.getCmdLineRunner()
if(clr){
// it's not null so is launched from testRunner
}else{
// it's null, so is launched from UI
}

Specifying Qt Output Directory

In Qt in a Linux environment, how would I go about specifying that one file my application creates goes into a specific, hard-coded directory while another file created at the same time goes into a different hard-coded directory?
I am not sure what you want to do but does this work?
QFile aFile("/some/hard/coded/path/filename");
QFile anotherFile("/another/hard/coded/path/filename");
I'm not sure about files other than MOC, obj, ui, rcc, and executable files, but you can specify where each of them go with the following:
Release:DESTDIR = release
Release:OBJECTS_DIR = release/.obj
Release:MOC_DIR = release/.moc
Release:RCC_DIR = release/.rcc
Release:UI_DIR = release/.ui
Debug:DESTDIR = debug
Debug:OBJECTS_DIR = debug/.obj
Debug:MOC_DIR = debug/.moc
Debug:RCC_DIR = debug/.rcc
Debug:UI_DIR = debug/.ui
If you want to set the output path for other files that are generated, I don't know if it is possible (you might need a custom build step, though I might be wrong)

Assembling SSIS Packages in PowerShell

I should preface by saying my experience with scripting or programming in OOP languages is limited.
I'm working on a method for programatically creating and executing SSIS packages using PowerShell. Unfortunately, most of the resources available for PowerShell and SSIS are for calling PS from SSIS, not the other way around.
I have, however, found a number of resources for VB/C# for creating SSIS packages.
Example resource here.
I've succeeded in converting most of the code by calling the DTS/SSIS assemblies, but it's failing now on converting the TaskHost object to a mainpipe.
Sample code:
[Void][Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.ManagedDTS')
[Void][Reflection.Assembly]::LoadWithPartialName('Microsoft.Sqlserver.DTSPipelineWrap')
# Create the Package and application, set its generic attributes
$Package = New-Object Microsoft.SqlServer.Dts.Runtime.Package
$Package.CreatorName = $CreatorName
$App = New-Object Microsoft.SqlServer.Dts.Runtime.Application
# Set connection info for our package
$SourceConn = $package.Connections.Add("OLEDB")
$SourceConn.Name = "Source Connection"
$SourceConn.set_ConnectionString("Data Source=$SourceServer;Integrated Security=True")
$TargetConn = $package.Connections.Add("OLEDB")
$TargetConn.Name = "Target Connection"
$TargetConn.set_ConnectionString("Data Source=$TargetServer;Integrated Security=True")
# Build the tasks
# Data Flow Task - actually move the table
[Microsoft.SQLServer.DTS.Runtime.Executable]$XferTask = $Package.Executables.Add("STOCK:PipelineTask")
$XferTaskTH = [Microsoft.SqlServer.Dts.Runtime.TaskHost]$XferTask
$XferTaskTH.Name = "DataFlow"
$XferTaskTH.Description = "Dataflow Task Host"
$DataPipe = [Microsoft.SQLServer.DTS.pipeline.Wrapper.MainPipeClass]($XferTaskTH.InnerObject)
Everything works fine til the last line, when I get the error:
Cannot convert the
"System.__ComObject" value of type
"System.__ComObject#{}" to
type
"Microsoft.SqlServer.Dts.Pipeline.Wrapper.MainPipeClass"
Any assistance or ideas are welcome!
Microsoft.SqlServer.DTSPipelineWrap makes heavy use of COM instances.
This forum post suggested using CreateWRapperOfType method:
http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/0f493a31-fbf0-46ac-a6a5-8a10af8822cf/
You could try this:
$DataPipe = [System.Runtime.InteropServices.Marshal]::CreateWrapperOfType($XferTaskTH.InnerObject, [Microsoft.SQLServer.DTS.pipeline.Wrapper.MainPipeClass])
Doesn't error out and produces an object--I'm not sure of what type.
You could always just compile the working .NET version you referenced above into an exe, and allow it to accept parameters as needed in order to create the SSIS packages. Then, use Powershell to call the executable with the parameters as needed.

Resources