AS400 with Ruby on Rails - ruby-on-rails-4

I am trying to access our AS400 database with Ruby on Rails, using the "dbi" gem and the "dbd-odbc" gem.
I have found this code to build off of. When I pass in the server address...
It seems that the original code uses an DSN, but I wanted to pass in the IP, database name, and library in the code to prevent any DSN being needed.
require 'dbi'
dbh = DBI.connect('DBI:ODBC:SYSTEM=<ip_address>;DBQ=<db_name>;DFTPKGLIB=<library_name>;LANGUAGEID=ENU', 'UID=<user_name>', 'PWD=<password>')
sth = dbh.prepare('select count(*) from my_table')
sth.execute
# Print out each row
while row=sth.fetch do
p row
end
sth.finish
dbh.disconnect
it gives me an error of...
DBI::InterfaceError: Unable to load driver 'ODBC'
what would be the correct syntax?

This works for me - also, just put your authentication portion inside of the first argument to the DBI.connect function:
First install the gems: dbi, dbd-odbc, ruby-odbc. I was getting the same error without the ruby-odbc gem
Then:
require 'odbc'
require 'dbi'
dbh = DBI.connect('DBI:ODBC:SYSTEM=MYAS400;DBQ=TABLE_NAME;DFTPKGLIB=SCHEMA_NAME;DRIVER=Client Access ODBC Driver (32-bit);LANGUAGEID=ENU;USERID=SUPERADMIN;PWD=SUPERSECURE')

I don't know exactly how that works in Ruby, but in the connection string I don't see where you mention the driver your trying to use to connect.
Seems like this line:
dbh = DBI.connect('DBI:ODBC:SYSTEM=<ip_address>;DBQ=<db_name>;DFTPKGLIB=<library_name>;LANGUAGEID=ENU', 'UID=<user_name>', 'PWD=<password>')
needs to be something like this to indicate the driver ODBC should use to connect:
dbh = DBI.connect('DBI:ODBC:Driver=iSeries Access ODBC Driver;SYSTEM=<ip_address>;DBQ=<db_name>;DFTPKGLIB=<library_name>;LANGUAGEID=ENU', 'UID=<user_name>', 'PWD=<password>')

Related

TypeError: can only concatenate str (not "DeferredAttribute") to str

I am wondering anyone can help me in one of the thing I cannot get my around it and really bothering as I spent last two on it but couldnt make it.
Basically, I am building an App (Django Python) to restore the information regarding all the network device e.g hostname, IP Address, S/N, Rack info etc. but I also to enable few options like Add, Edit, Delete and Connect next to device entery. I was able to create all the options except Connect option where I am completely stuck, I am trying to query database to get the IP address information and then using Popen module to open a putty window with the ssh to that IP Address device related, I tried everything I could but nothing worked, thereofrore, asking your help if you have any idea about this ? or any other alternative method for a user when he click on connect the putty or similar app will open and he just put the login credentials and get into the device.
I am sharing my code here, let me know if I am doing something wrong.
on the show all device page, i have this code, show.html
<td>Connect</td>
<!--<td>Connect</td>-->
I tried both ways, with id and ip address entry in the database
on view.py
def connect(request, ip_address):
hostlist_ip = HostList.ip_address
print(hostlist_ip)
Popen("putty.exe" + hostlist_ip)
return redirect('/show')
and in the url.py
path('connect/<str:ip_address>', views.connect),
or
path('connect/<str:ip_address>', views.connect),
Since I am also printing the the output on the terminal I notice that it is not returning the actually IP address but return this;
<django.db.models.query_utils.DeferredAttribute object at 0x04B77C50>
and on the web I receiving this error
TypeError at /connect/10.10.32.10
can only concatenate str (not "DeferredAttribute") to str
Request Method: GET
Request URL: http://localhost:8000/connect/10.10.32.10
Django Version: 2.2.3
Exception Type: TypeError
Exception Value:
can only concatenate str (not "DeferredAttribute") to str
let me know if you can help.
Just a F.Y.I I already tested the Popen via python but since we not getting the actual IP address from the database I am seeing this and I am a complete newbie with html/css and Djano, however I have some basic knowledge of python, so please ignore my any stupid comments in the post.
Many thanks
ahh I cannot believe I spend two day to troubleshoot this and just changed the name from ip_address to ip_add and it is working now :) i think as I mentioned above in the comment, it probably confusing with the built in module
here is simple solution:
views.py
def connect(request, ip_add):
import os
from subprocess import Popen
Popen("powershell putty.exe " + ip_add)
return redirect('/show')
url.py
path('connect/<str:ip_add>', views.connect),
I may have to find out a way if user is using the mac or linux, how I am going to change this powershell to something else. but anyhow it is working for windows
thanks all for the responses.

Rewring the connection for lucee

I have this code working for coldfusion, but when i port it to lucee it fails, i know that macromedia does not work in lucee, how can i make this a possibility in lucee and want to remove the connection string, but the result should be exactly like the how the function is returning me
// open a connection to the database
Class = createObject("java", "java.lang.Class");
Class.forName("macromedia.jdbc.sqlserver.SQLServerDriver");
manager = createObject("java", "java.sql.DriverManager");
connectionURL = "jdbc:macromedia:sqlserver://"& SESSION.USER.dbServer &":"& SESSION.USER.dbPortNumber & ";EncryptionMethod=SSL;ValidateServerCertificate=false;";
connection = manager.getConnection(connectionURL, SESSION.USER.dbUser, SESSION.USER.dbPass);
You might define this data source in the Admin instead of in the application code. One thing that screams "big red flag" in your existing code is that the database server name is defined in a cookie. Makes me wonder what other things are in cookie values that need to be refactored.
Read the documentation for defining a data source:
this.datasources["myds"] = {
class: 'org.gjt.mm.mysql.Driver'
, connectionString: 'jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useLegacyDatetimeCode=true'
, username: 'root'
, password: "encrypted:5120611ea34c6123fd85120a0c27ab23fd81ea34cb854"
};
The example is for MySQL, but you need to find the correct driver name for SQL Server used by Lucee. Go to the admin and create the DSN there to find the driver name.

C++ Poco ODBC Transactions - AutoCommit mode

I am currently attempting to use transactions in my C++ app, but I have a problem with the ODBC's auto commit mode.
I am using the POCO libaries to create a connection to a PostgreSQL database on the same machine. Currently, I can send data to this database as single statements, but I cannot get my head around how to use Poco's transaction libraries to be able to send this data more quickly.
As I have several thousand records to insert, and so continuing to use single insert statements is extrememly slow and inpractical - So I am trying to use Poco's transaction to speed this up a bit (a fair bit).
The error I am encountering is a theoretically a simple one - Poco is throwing the following error:
'Invalid access: Session is in auto commit mode.'
I understand, as a result of this, I should somehow set "auto commit" to false - as it only allows me to commit data to the database line by line, rather than as a single transaction.
The problem is how I set this.
Currently, I have a session created from Session.h, that looks alot like this:
session = new Poco::Data::Session(
"ODBC",
connection_data.str()
);
Where connection data is a simple stringstream with the login information, password, database, server and "Driver={PostgreSQL ANSI};" to tell ODBC to utilize PostgreSQL's driver.
I have tried just setting a property "autocommit" to false through the session's setFeature or setProperty settings, this, of course, was to no avail. (it was more of a ditch attempt at this point).
session->setFeature("AUTOCOMMIT", false);
Looking around, I saw a possible alternative method by creating a ODBC sessionImpl directly from ODBC/session/SessionImpl.h instead of using this generic method above, and then creating a new session object from this.
The benefits of this are that ODBC's sessionImpl has references to autocommit mode in the header, which would suggest it would be able to handle this:
void autoCommit(const std::string&, bool val);
/// Sets autocommit property for the session.
However, having not used sessionImpl before, I cannot garuntee if this will work or if can can get this to work with the limited documentation available.
I am using C++ 03 (Not 11), with Visual Studio 2015
Poco 1.7.5
Boost (Where needed)
Would any one know the correct way of setting this feature (above) or a alternative method to achieving this?
edit: Looking at the source of poco, at:
https://github.com/pocoproject/poco/blob/develop/Data/ODBC/src/SessionImpl.cpp#L153
The property seems be named autoCommit, and looking at
https://github.com/pocoproject/poco/blob/develop/Data/include/Poco/Data/AbstractSessionImpl.h#L120
the case of the property names seem to matter. So, does it help if you use session->setFeature("autoCommit", false);?
Cant you just call session->begin(); and session->end(); on the corresponding Session object?
What is returned by session->canTransact()?
According to the doc begin() will start a new transaction, the doc does not mention any property that needs to be set before or after.
See: https://pocoproject.org/docs/Poco.Data.Session.html
Also faced a similar issue.
First of all before begin() need:
m_ses.setFeature("autoCommit", false);
m_ses.begin();
And the second issue is that this feature stays "autoCommit" in false for all other sessions. So don't forget for the next session call
session.setFeature("autoCommit", true);

Mysql Connector connect() issues

I have a small C++ project and need to access a mySQL DB from it, so i have setup mySQL Connector for C++.
This is done on OS X 10.10, and i got no problems with the compilation/linking.
I have written a class for all the mysql stuff, and in the constructor i want to setup the connection to the db. However, this seems to be kinda hard.
Here is the relevant part from the class:
class mysql{
public:
mysql(std::string server, std::string user, std::string password);
private:
sql::mysql::MySQL_Driver *driver;
sql::Connection *con;
std::string last_error = "";
};
And here the implementation:
mysql::mysql(std::string server, std::string user, std::string password){
driver = sql::mysql::get_mysql_driver_instance();
try{
con = driver->connect(server, user, password);
last_error = "";
}
catch(sql::SQLException &e){
last_error = e.what();
}
}
However, when i create an object of that class like this:
mysql db("tcp://127.0.0.1:3306", "root", "secretsecret");
I then have this in my last_error string:
Unknown MySQL server host '???' (0)
The "host" sometimes differs even tho i dont change it in code. This seems like internally a different memory location is read out as it should be.
But even if i pass the connect() variables directly when i call it, i get this error. Same when saving those three variables internally in the mysql class and use those to call connect().
Anyone has an idea what could cause this? I have a similar implementation in a different project where this does work fine so im kinda confused :/
Here is a post that matches to your circumstances (The C++ connector works on linux and fails on OSX).
With using mysql logging/tracing or running it in debugger, you may be able to gather more information to report to mysql developers. You may have better luck.
After a long time of googeling i found this the most useful link: https://apple.stackexchange.com/questions/251290/weird-behaviour-of-mysql-connector-c-in-osx
Following the hints there, i recompiled the myscl c connector and then the mysql c++ connector (version 1.1.6 cause 1.1.7 caused a json error while compiling).
I also saw in the cmake logs of the c++ connector that Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ was used to compile the library.
So i used that one too for my compilation. It could be that this would work, tho im also including wxwisgeds in my project resulting in this error:
/usr/local/include/wx-3.0/wx/strvararg.h:30:18: fatal error: 'tr1/type_traits' file not found
#include <tr1/type_traits>
I found some hints for that one but they all just produced a massiv amount of new errors, so i stopped digging deeper here.
My best options would be to create two seperate programs, on to communicate with mysql and one to provide the gui and let them both communicate with each other either via sockets or files providing a very inefficient access to a mysql db.
Good luck to anyone who runs into the same thing..

mongodb terminates on any find command

I keep getting thrown out of my mongo session when I do queries like find. I am specifically trying to do a geo query (db.places.find( { loc : { $near : [50,50] } } ) but the issue seems to be with any find query.
I get this error:
Sun Dec 18 16:33:12 terminate() called in shell, printing stack:
0x80a8bc0 0x809dbd2 0xb77ca283 0xb77ca2bf 0xb77ca40e 0x80ecdd0 0x813b9c4 0x812e410 0xb7411450
mongo(_ZN5mongo15printStackTraceERSo+0x30) [0x80a8bc0]
mongo(_Z11myterminatev+0x52) [0x809dbd2]
/usr/lib/i386-linux-gnu/libstdc++.so.6(+0xaf283) [0xb77ca283]
/usr/lib/i386-linux-gnu/libstdc++.so.6(+0xaf2bf) [0xb77ca2bf]
/usr/lib/i386-linux-gnu/libstdc++.so.6(+0xaf40e) [0xb77ca40e]
mongo(_ZN5mongo9uassertedEiPKc+0x130) [0x80ecdd0]
mongo(_ZN5mongo9Convertor8toStringEP8JSString+0x2a4) [0x813b9c4]
mongo(_ZN5mongo12native_printEP9JSContextjPy+0xb0) [0x812e410]
/usr/lib/libmozjs185.so.1.0(+0xac450) [0xb7411450]
Anyone know what is going on here?
As a side note, I am inserting into mongo using a django-mongo engine interface.
It looks like either your database is corrupted or contains invalid UTF-8 string. Can you try to repair or verify your data?
BTW, Geo query shouldn't use javascript. Are you compiling the code yourself? Stacktrace doesn't look right too. It seems to use JS 1.8.5 instead of JS 1.7.