ZF2 PDO_IBM Driver with Relational Database Name - database

Have a Zend Framework 2.4 connection factory that needs to establish a connection with an AS400 iSeries database. The connection has to be made this way because there are multiple test environment and the factory needs to accommodate each.
The method is using Zend\Db\Adapter\Adapter and I pass that class an array of database connection parameters.
At issue: Zend\Db\Adapter doesn't accept the relational database (directory) name. I'm assuming that since the driver is PDO_IBM, there would be some expectation of a field for explicitly defining the name for the directory.
Here is the method:
public function conn($dbs) {
$this->adapter = new Adapter(array(
'driver' => $dbs['db']['driver'],
'dbname' => $dbs['db']['dbname'],
'username' => $dbs['db']['username'],
'password' => $dbs['db']['password'],
'hostname' => $dbs['db']['hostname'],
'port' => $dbs['db']['port'],
));
var_dump($this->adapter);
return $this->adapter;
}
Adapter is an alias for \Zend\Db\Adapter\Adapter
And here is the object that gets created.
["driver":protected]=> object(Zend\Db\Adapter\Driver\Pdo\Pdo)#224 (4){
["connection":protected]=>object(Zend\Db\Adapter\Driver\Pdo\Connection)#225 (6) {
["driver":protected]=> *RECURSION*
["profiler":protected]=> NULL
["driverName":protected]=> string(3)"ibm"
["connectionParameters":protected]=> array(6) {
["driver"]=> string(7) "PDO_IBM"
["dbname"]=> string(7) “<relational_database_name>”
["username"]=> string(3) “<user_name"
["password"]=> string(3) “<password>"
["hostname"]=> string(9) "127.0.0.1"
["port"]=> string(3) "446"
}
I can instantiate the connection object using:
$conn = new \Zend\Db\Adapter\Adapter( );
Pdo=ibm:<relational_database_name>
But this isn't a workable solution for this situation. Finally, here is the error:
Connect Error: SQLSTATE=42705, SQLConnect: -950 Relational database dbname=;hos not in relational database directory.

For the sake of completeness, here is the configuration that worked for ZF2 Zend\Db\Adapter\Adapter running on Zend Server 6 and connecting to an AS400 iSeries database.
//concat the driver and rel. db directory name into one string
//$dsn name is required for Zend\Db to correctly read it into memory
$dsn = "ibm:" . $db_dir_name;
$this->adapter = new Adapter(array(
'driver' => $driver, // Pdo
'dsn' => $dsn,
'username' => <user_name>,
'password' => <user_pwd>
));
This wasn't documented anywhere and figured it out through trial and error.

Related

undefined method `close_jdbc_connection' for #<Sequel::JDBC::Database:0 x764acb8b>

I have been trying to import data from MS SQL Server to Elastic Search using Logstash. However, I am getting logstash pipeline and undefined method `close_jdbc_connection' error. I have not found the exact solution for this issue. The code used and error messages are as follows -
logstash config -
input {
jdbc {
jdbc_driver_library => "C:\elasticsearch-5.4.3\elasticsearch-5.4.3\lib\sqljdbc42.jar"
jdbc_driver_class => "com.microsoft.sqlserver.jdbc.SQLServerDriver"
jdbc_connection_string => "jdbc:sqlserver://<servername>,<portname>;databaseName=<db_name>"
jdbc_user => "user"
jdbc_password => "password"
statement => "select * from dbo.jobstatus"
jdbc_paging_enabled => "true"
jdbc_page_size => "50000"
}
}
filter {
mutate {
remove_field => [ "message", "path", "score", "#version", "host" ]
}
#mutate { convert => ["REGCONNTYPEID","integer"]}
}
output {
elasticsearch {
hosts => "localhost"
index => "sql_elk_dc_stats"
document_type => "devices"
}
stdout { codec => rubydebug { metadata=> true } }
}
Output -
[2017-10-15T18:20:11,768][INFO ][logstash.agent ] Successfully started
Logstash API endpoint {:port=>9600}
[2017-10-15T18:20:40,971][WARN ][logstash.inputs.jdbc ] Failed test_connecti
on.
[2017-10-15T18:20:40,978][ERROR][logstash.pipeline ] A plugin had an unre
coverable error. Will restart this plugin.
Plugin: <LogStash::Inputs::Jdbc jdbc_driver_library=>"C:\\elasticsearch-5.4.3\
\elasticsearch-5.4.3\\lib\\sqljdbc42.jar", jdbc_driver_class=>"com.microsoft.sql
server.jdbc.SQLServerDriver", jdbc_connection_string=>"jdbc:sqlserver://<servername>,<port>;databaseName=db_name", jdbc
_user=>"user", jdbc_password=><password>, statement=>"select * from dbo.jo
bstatus", jdbc_paging_enabled=>true, jdbc_page_size=>50000, id=>"36bb27ae9af8f6a
086048a0a0f6a22d4a32b1be6-1", enable_metric=>true, codec=><LogStash::Codecs::Pla
in id=>"plain_8d7b9383-b58f-4dfe-82c8-20066ced2652", enable_metric=>true, charse
t=>"UTF-8">, jdbc_validate_connection=>false, jdbc_validation_timeout=>3600, jdb
c_pool_timeout=>5, sql_log_level=>"info", connection_retry_attempts=>1, connecti
on_retry_attempts_wait_time=>0.5, parameters=>{"sql_last_value"=>false}, last_ru
n_metadata_path=>"C:\\Users\\ghosmrin/.logstash_jdbc_last_run", use_column_value
=>false, tracking_column_type=>"numeric", clean_run=>false, record_last_run=>tru
e, lowercase_column_names=>true>
Error: undefined method `close_jdbc_connection' for #<Sequel::JDBC::Database:0
x764acb8b>
Note - I am using windows 7, ELK 5.4.3 version. The sql login is able to connect to the SQL server.
It looks like there was a bug https://github.com/logstash-plugins/logstash-input-jdbc/issues/227 - that was reported in July - It looks like it made it into the 4.2.4 version of the JDBC plugin https://github.com/logstash-plugins/logstash-input-jdbc/blob/v4.2.4/CHANGELOG.md - are you using an earlier version of the plugin?
With that said, I suspect the could still be an issue with your connection, the plugin may just be poorly handling a connection issue... As you've sensibly replaced you db/server details it's impossible to categorically say if there's an issue with the connection string... The one thing I'll say is that you need a colon between the server and port (you have a comma), you might also need a semi-colon at the end of the string, but I don't think it's strictly necessary:
jdbc_connection_string => "jdbc:sqlserver://<servername>:<portname>;databaseName=<db_name>;"
https://learn.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url

Access Sql Server through Ruby Active Record JDBC

I've been attempting to connect to a remote JDBC/SqlServer database using Active Record in Ruby (specifically JRuby). Here is my code:
require 'activerecord'
require 'activerecord-jdbc-adapter'
ActiveRecord::Base.establish_connection(
:adapter => 'sqlserver',
:username => '<username>',
:password => '<password>',
:database => '<database_name>',
:url => '<database_url>',
)
#connection = ActiveRecord::Base.connection
puts #connection
I've also put 'jdbc' as the adapter, and that also did not work.
And here is an abbreviated version of the error I am getting:
NameError: cannot load Java class com.microsoft.sqlserver.jdbc.SQLServerDriver
for_name at org/jruby/javasupport/JavaClass.java:286
get_proxy_class at org/jruby/javasupport/JavaUtilities.java:34
block in java_import at uri:classloader:/jruby/java/core_ext/object.rb:49
map at org/jruby/RubyArray.java:2486
java_import at uri:classloader:/jruby/java/core_ext/object.rb:36
block in driver_class at C:/jruby-9.1.12.0/lib/ruby/gems/shared/gems/activerecord-jdbc-adapter-1.3.23/lib/arjdbc/jdbc/driver.rb:24
module_eval at org/jruby/RubyModule.java:2833
block in driver_class at C:/jruby-9.1.12.0/lib/ruby/gems/shared/gems/activerecord-jdbc-adapter-1.3.23/lib/arjdbc/jdbc/driver.rb:23
synchronized at org/jruby/javasupport/JavaObject.java:257
It's not so much a specific problem but more that I'm just unsure where to go from here. Using the 'activerecord-sqlserver-adapter' in pure Ruby doesn't work because of the JDBC on the server. (I might be misusing the terms here, I'm rather unfamiliar with how databases work.)
However, the jdbc/sqlserver gems seem to be not well-supported or out of date. There's probably no silver bullet for this, but any kind of direction would be of enormous help.
You still need to require 'active_record', no?
And I am not sure you need the require 'arel'. That is the low level sql builder/formatter implemented by active_record.
require 'active_record'
require 'activerecord-jdbc-adapter'
ActiveRecord::Base.pluralize_table_names = false
ActiveRecord::Base.establish_connection(
:adapter => "sqlserver",
:host => "SqlServerHostName",
:database => "HostDbName"
)

How to let Cakephp 3 choose database connection by Apache environment variable

I'm working with cakephp v3 and want to install the application in two different environments, one for development and one for production use. Both installations should consist of exactly the same files (and file contents), so I could use 'git' or 'svn' to easily deploy the application.
If both environments are hosted on the same machine, I need different database settings (so that the development env uses its own 'testing' DB). I thought of configuring two 'Datasources' in app.php, the 'default' one for production and a `development'.
But how can I switch between both sources?
To be more specific: Currently I define the following environment variable in my Apache config for the development environment:
SetEnv CAKEPHP_DEBUG 1
Then I changed the definition of 'debug' in the app.php file like this:
'debug' => (bool)getenv('CAKEPHP_DEBUG'),
This enables DEBUG mode only on the development machine. Now I also want to switch database configuration in the same easy way.
(I already found some solutions for cakephp v2, but all of them are pretty old and I'm not sure what's the best way to do it in cakephp v3.)
The manual says
You can define as many connections as you want in your configuration
file. You can also define additional connections at runtime using
Cake\Datasource\ConnectionManager::config().
So I guess you can check the value of debug in AppController beforeFilter and change the default database connection
AppController.php
if(Configure::read('debug') == 1)
{
ConnectionManager::config('default', [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'dev_server',
'username' => 'dev_username',
'password' => 'dev_passwd',
'database' => 'development',
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
]);
}
I think you can do something similar in app.php using the ternary operator
app.php
'Datasources' => [
'default' => getenv('CAKEPHP_DEBUG')== 1 ? [ /* debug params */ ] : [ /* default params */]
...
]
But somehow it don't seem the 'clean' way to do it
I think that a cleaner way would be to set both configurations in app.php and then in appController choose what configurations to use
app.php
'Datasources' => [
'debug' => [ /* debug params */ ],
'default' => [ /* default params */]
]
Table file
public static function defaultConnectionName() {
if(Configure::read('debug') == 1)
return 'debug';
return 'default';
}

Solarium 3.2.0 create ping for SOLR5.0

Installed SOLR 5.0 and started the SOLR instance with bin/solr start -e cloud... normal stuff. The web UI is functioning and can see the two nodes.
Created an index file trying to ping the server per Solarium documentation:
require_once ('init.php');
$str="Running Solarium client version: ".Solarium\Client::VERSION;
$client = new Solarium\Client($config);
// create a ping query
$ping = $client->createPing();
var_dump($ping);
// execute the ping query
try {
$result = $client->ping($ping);
$str=$str.'Ping query successful';
var_dump($result->getData());
} catch (Solarium\Exception $e) {
echo 'Ping query failed';
}
return $str;
the $str can show using Solarium client version 3.2.0.
But while doing $client->ping(), there is an exception:
Problem accessing /solr/admin/ping. Reason:
Not Found
Any hints???
config.php pasted here:
<?php
$config = array(
'endpoint' => array(
'localhost' => array(
'host' => '10.0.0.8',
'port' => 8983,
'path' => '/solr/',
)
)
);
It is a remote connection.
I had the same issue. Put collection name in config.php like this:
'path' => '/solr/collection_name/',

Suppressing connection error with DBI and DBD:ODBC SQL Server Native Client 10.0

Writing a script to get SQL Server instance names from a table, then attempting to connect to each of these instances to pull back database configuration information. All database instances involved are some version of SQL Server. If the connection fails (due to a bad password, instance is down, etc.) the intention is to print a user-defined error message ("Unable to connect to $inst, skipping.") and continue through the list. I'm having trouble suppressing the default error message from ODBC (SQL Server Native Client 10.0).
Connection is attempted like this:
eval {
my $dbh = DBI->connect(
"dbi:ODBC:Driver={SQL Server Native Client 10.0};Server=<instance_name>;Uid=<user_name>;Pwd=<password>;",
{ PrintError => 0, RaiseError => 1, AutoCommit => 1 }
);
};
It is my (probably incorrect) understanding that PrintError => 0 should suppress the error message and RaiseError => 1 will cause DBI to die if the connect method fails, at which point I can check $# for the error and print a user-defined message. I have also looked at the HandleError attribute but have not had any success.
Is this a completely unrealistic scenario, or is this a result of the ODBC driver I'm working with?
Per bohica's suggestions, working code looks like:
eval {
my $dbh = DBI->connect(
"dbi:ODBC:Driver={SQL Server Native Client 10.0};Server=<instance_name>;",
"Username",
"Password",
{ PrintError => 0, RaiseError => 1, AutoCommit => 1 }
);
};
Username and password were moved out of connection string and passed as separate parameters to DBI connect method.
Assuming you fix the problem Pedro mentions then, PrintError=>0 suppresses errors and you might want to look at PrintWarn as well. The RaiseError=>1 will cause the connect to die if the connect fails and in your example the error will be in $#.
connect is a class method; you call it with DBI->connect, which returns a db handle ($dbh in your case).

Resources