Support for DB2 databases?
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
keeping things as simple as possible is fine. so if it works without jar, fine. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
If the file does need to be copied to sqllib, then I was thinking that the Installer could programmatically determine the sqllib location and copy the file there... I wouldn't think we need to ask the user to do the copying. Any suggestions about my test failures? It's really polluting my results. I ran 974 tests run, and about half of them are successful, but the tests that fail report 8,602 failures... that's about 16 errors per failing test. For example, the test "testChangeValues" is reporting 42 of these CLI0005W "failures". It'll take me days if not weeks to manually sift through all that chaff. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
but we needed the user to grant permission to copy the file and windows / IIS permissions are horrible for end users. @join CLI PHP Warning: maybe you can add in the adodb files or so. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
There's something weird here... the test continues to fail no matter what I set error_reporting to. I've tried: - error_reporting($oldErrorReporting & ~E_WARNING); and the error persists. I couldn't find an E_NONE or I would have tried it. I don't know if this is related, but I also see a warning that says my development environment is not correct. However, I'v verified that these setting are correct in my 'php.ini', so this warning is incorrect. PHP Setting Actual Value Expected Value(s) short_open_tag 1 off or 0 allow_call_time_pass_reference 1 off or 0 allow_url_fopen 1 off or 0 include_path .;C:\php5\pear /bogus |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
@development evironment: also, you should have error_reporting E_ALL in your php.ini we should really get rid of the CLI issues. we can't start suppressing all these warnings. better eliminate the warnings. what do the DB2 guys think about it? |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> probably you need to restart the webserver I have, many times. There originally were other incorrect settings as well, but I've fixed them. These last four however refuse to go away. I don't think they're related to the real problem, I just thought I should mention it. > also, you should have error_reporting E_ALL in your php.ini It is already so. > we should really get rid of the CLI issues I don't consider this a "CLI issue". Remember, the MS ODBC driver says it doesn't support joins at all (so I'm curious how these joins work in PostgreSQL and MySQL on Windows... does G2 not use the MS ODBC driver?). CLI considers this message a Warning, but PHP seems to insist on reporting it. I'll try to create a simple testcase to demonstrate this, and post it to the DB2 newsgroup. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
postgresql and mysql don't use odbc, they use their own php functions. in g2, we don't tolerate any PHP warnings / notices. so we must get rid of these odbc issues 'cause of that joins. thanks for posting it to the db2 newsgroups! any progress on the absolute path with colon front? |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
No (useful) answers to either of the two questions. Will let you know as soon as I hear anything. In the meantime, I might proceed with the "sqlj.install_jar()" solution in case I never get a good answer. Thanks for letting me know how PostgreSql and MySql work. I should have guessed that because the 'adodb-odbc.php.inc' file wasn't there. ;-) |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Got an answer about the CLI0005W. In a PHP-DB2-ODBC environment, the default cursor type is FOR UPDATE. The CLI0005W goes away if we specify FOR READ ONLY on the SQL statement itself. Adding FOR READ ONLY to my 'join' testcase does avoid the problem. I chose G2 test "testChangeValues" to test this change (it is currently getting CLI0005W). I added FOR READ ONLY to the failing statement (which is not a join), but it doesn't seem to help that test. Then when I re-run the whole suite of tests the number of errors falls slightly from 8,602 to 8,596. So there must be more than one case in which CLI0005W is raised. I'll keep working on it. FYI: Dan Scott (DB2/Linux product planner) says the 'ibm-db2' PHP extension does not have this problem. I presume he means the 'join' problem.) However, they have not yet added support for that extension to ADOdb... they're working on it. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
hmm, so you still get the same error in unit tests even with the READ ONLY appended, just a few errors less? what's keeping Dan Scott from releasing a adodb-ibm-db2 driver? too low priority? |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
I think I've isolated at least some (hopefully all) of the remaining CLI0005W problems to queries that reference the LONG VARCHAR columns (e.g., g2_pluginparametermap.g_parametervalue). Now waiting for a response to that in the newsgroup. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> still get the same error in unit tests even with the READ ONLY appended, just a few errors less Yeah, a whopping 6 errors were fixed. > what's keeping Dan Scott from releasing a adodb-ibm-db2 driver? too low priority? He hasn't said what the holdup is, but I do have first-hand knowledge of how things are within IBM DB2 development |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
if we can solve these adodb-db2 issues, fine... hope you get there an answer. if we need a ibm_db2 driver for adodb...: maybe ask Dan Scott if he already has started working on this / has a work in progress driver which we could copy and improve / complete. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> a work in progress driver which we could copy and improve / complete "we" meaning "me", I see. This has already taken much longer than I originally inteded to commit to. For the last 4 weeks I've been on the verge of abandoning this; only my stubbornness and my sense of obligation prevent me from doing so. Since my leaving IBM earlier this year (on terms that were not exactly hostile, but not exactly friendly either) I've already done a fair bit of 'volunteer' work for them, but signing up to complete the 'ibm-db2' driver is way over the line for me. If I had the solid skills and time required, then I might do consider doing so, but I definitely don't have the skills, and I can't guarantee I'll have the time either... I'm currently job-hunting, and if/when I land a job, the time I can devote to G2 will probably be drastically and immediately reduced. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
we means mainly you, since i can't help you on the db2 side (i don't know db2 and you need to know db2 to create such a adodb driver). i could start doing it myself and ask questions about everything db2 and not adodb / php related. and an initial driver wouldn't need bind support. but true, it's not a small task and i'd prefer to not have to write it. yep, this db2 story has been much more complicated than we thought. @long varchar columns: i'm curious ... @testing: |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Nope, I tried to add a gallery to it, and got an error. I'll keep testing it regardless of the unit test failures. BTW, I contacted Dan Scott, and (sort of) offered our services. His response: Quote:
I haven't heard anything from the folks that claimed they were going to implement an ibm_db2 driver for ADOdb, sorry. I'll send them a follow up note. As you can see, he is also excited about the prospect of adding DB2 support to Gallery. I'll let you know when I hear back from him regarding his follow-up. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> Runtime error creating items Ah, the error while creating the album was my own fault. ;-) It's actually working quite well I think. I've created an album called "George and Jojo" and added 4 pictures of my birds to it. I'm still confused by some of the things I see. For example: Why do I have 7 pages of albums (with 9 albums per page), most of which are named "Album: This is my title", and on the last page have 3 albums called "George and JoJo", the first 2 of which are empty? Also, one of the photos I tried to add contains an apostrophe in the file name... gallery didn't handle it very well... the image was imported, but its name is now only what occurred after the apostrophe. > ADOdb driver I've volunteered (to Dan Scott) to take a stab at porting the odbc driver to DB2, and he's agreed to help me out if I get stuck. Conversation was as follows: Quote:
From: Dan Scott So now I'm porting an ADOdb driver for DB2 after all. Sigh... |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
FYI, here's how it currently looks: |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
Quote:
Why do I have 7 pages of albums (with 9 albums per page) that's probably a by-product of the failed unit tests. usually you've got an empty g2 after installation. @apastrophe: @you porting adodb odbc to db2: |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Valiant, could you please confirm for me that you have checked in the changes I sent you on 11/23? If so, I'll get a new build, reconfirm the changes, and send you my latest tweaks. Thanks. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
no, i didn't commit those changes yet. i thought these java class thing was just around the corner, that's why i waited. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
OK, no prob. I'll keep using my current build. There's still no response regarding the 'class file absolute path' question. For the time being, I'll implement the jar file solution. When that's done, I'll resubmit the changes to you. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
great, thanks! |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Question: In the "call sqlj.install_jar()", we need to specify the URL to the jar file, which means specifying the absolute path to it. Is there a way to reference some existing variable for that in the 'createDb2Udfs.sql' file? If not, then that "call sqlj.install_jar()" will have to be done in DatabaseStorage::configureStore. In the example you quoted a while ago you said something like: $path = dirname(__FILE__) . $platform->getDirectorySeparator() . 'g2_db2_bit_or.jar'; execute("call sqlj.install_jar(file://$path, 'g2_db2_jar')"); But for the actual execute(), are you sure I shouldn't use something like: $ret = $this->_executeSql("call sqlj.install_jar(file://$path, 'g2_db2_jar')"); if ($ret->isError()) { return $ret->wrap(__FILE__, __LINE__); } |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
> If not, then that "call sqlj.install_jar()" will have to be done in DatabaseStorage::configureStore. yep, i'd do it like that. we can't use php vars in the CreateDb2Udfs.sql file (we'd have to load the file into php, and do some regexp magic). doing the call in php is much easier. @execute: use: $path = dirname(__FILE__) . $platform->getDirectorySeparator() . 'g2_db2_bit_or.jar'; $recordSet = $tmpDb->Execute("call sqlj.install_jar(file://$path, 'g2_db2_jar')"); just as in function cleanStore |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Any error checking? I notice there's none in cleanStore(). BTW, you probably already presumed this, but just so you know... only the "sqlj.install_jar()" is going into "db2DatabaseStorage.class"... the "CREATE FUNCTION ()" is staying in "createDb2Udfs.sql". (No variables in it.) |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
yep, i assumed you'd do it like that. just follow the same pattern. list ($ret, $tmpDb) = $this->_getConnection(true); $this->_traceStart(); unless you supply / find DB2 code to find out whether the UDFs already exist, we have to ignore errors there. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
FYI, I've hit a problem with running "CALL SQLJ_INSTALL(...)" from within PHP. I always get error: Quote:
PHP Warning: odbc_exec(): SQL error: [IBM][CLI Driver] CLI0119E Unexpected sys Don't know why they consider it a 'warning'... it's definitely fatal. I can't find any doc about this error, so I've posted a question to the DB2 newsgroup. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
doh. maybe Dan Scott knows why you get this error... probably he's in the DB2 newsgroup anyway |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Dan has been looking into the 'sqlj.install_jar()' problem with me. I've further narrowed it down. It appears to be happening in DB2's CLI, not in PHP. It occurs even in a C program that uses the CLI api to call that SP. I'll wait another day or two to see if Dan or anyone in the newsgroup comes up with anything helpful. But I'm starting to get a very bad feeling that we might have to come up with a Plan C. Or D. Or even E. We've hit so many dead-ends that I'm starting to think this just wasn't meant to be. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
and what about the db2_execute function (instead of odbc), would they have the same problem since they're using the same CLI? or not? alternatively, we'd have to ask the user to manually install the g2_bit_or udf, right? |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> db2_execute Yes, even Dan's 'ibm_db2' extension uses CLI. > alternatively, manual install God I hope it doesn't come to that. There's got to be a way to avoid that. I'll keep thinking about it for a while. Hopefully something will work out. If this turns out to be another bug or limitation in DB2, I'll be really disappointed. If it turns out to be something I'm doing wrong, then I'll be embarrassed but life goes on. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
I think I have another solution: Create a SQL file that contains the 'sqlj_install_jar(...)' call, and use PHP's 'system(...)' call to invoke DB2's Command Line Processor (or CLP) to run that SQL file. Quote:
system("db2cmd /c /w /i db2 -tvf \"c:\\temp\\install_jar.db2\""); I've verified that it works from the command line: Quote:
C:\temp>php cli0119e.php ... and in a browser: Quote:
Connecting to 'gallery2' database... Details not worked out yet: - How to suppress the output from being echoed to the browser. We would prefer to capture it and analyse it for success/failure. I just now realized that we can do this by using exec($command, $outputArray) instead of system($command). - The "db2cmd /c /w /i" is only required on Windows. On Linux/Unix it should not be there. - DB2 considers the CLP call to be a distinct application, so it requires its own connect and disconnect within the SQL file. This requires the database name, userid, and password to be included in the SQL file. I think that means the file will need to be dynamically created in db2DatabaseStorage::configureStore. If no better solution is suggested, does that sound acceptable to you? |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
system prints the output, you should use exec anyway. then it won't print the output to the screen. ($platform =& $gallery->getPlatform(); $platform->exec()) nice idea - you can identify unix / windows with: Quote:
DB2 considers the CLP call to be a distinct application, so it requires its own connect and disconnect within the SQL file. This requires the userid and password to be included in the SQL file. I think that means the file will need to be dynamically created in db2DatabaseStorage::configureStore. what SQL file? the command line call you have above doesn't have a SQL file in it... $fileName = $platform->tempnam($gallery->getConfig('data.gallery.tmp'), 'db2_'); |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> nice idea Actually it's a horrible, brutal way to have to do something that should be so simple, but... > exec() can be disabled in PHP Does system() have the same possible problem? Probably it does, but if not, could we use redirection like 'system(...) > outputFile' to suppress the output? > check if db2cmd is available for webserver user 'db2cmd.exe' is in the main DB2 executable directory, 'sqllib/bin', which has to be in the PATH of any DB2 user. Chances of that directory not being already in the PATH are miniscule to nil I think. > what SQL file? The very first line in my append: Quote:
Create a SQL file that contains the 'sqlj_install_jar(...)' call, and use PHP's 'system(...)' call to invoke DB2's Command Line Processor (or CLP) to run that SQL file. And the first 'quote' in that append: Quote:
system("db2cmd /c /w /i db2 -tvf \"c:\\temp\\install_jar.db2\""); I'll attach a copy of that file here. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Can we determine programmatically if exec() is disabled? If so, then we could prompt the user with something like: Quote:
Please run DB2 CLP command 'db2 -vf \"$path\\install_jar.db2\"' and ensure successful completion before continuing. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
if exec is disabled, system is most certainly too. yes we can determine whether it is disabled or not and present the user with instructions. but all these complications suck since they affect non DB2 code. oh well.. it's doable. $buf = sprintf("connect to gallery2 user %s using %s\n still hoping for some good news from Dan Scott / the newsgroups. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> still hoping for some good news from Dan Scott / the newsgroups Definitely agree with that. BTW, DB2's CLP can't process multiple commands in a single buffer... they need to be in a file and then run with "-f". |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
FYI, I have it working using the last-resort CLP solution. Of course, I haven't looked at the case where exec() is disabled though. Question: I have the following PHP code to determine if the 'call sqlj.install_jar()' was successful, but I'm not sure how to implement it into the g2 architecture. for ($ctr = 0; $ctr <= sizeof($outputArray) - 1; $ctr++) { // printf ("\nLine %d = \"%s\".\n", $ctr + 1, $outputArray[$ctr]); if ($checkNextLine == 1) { if ($outputArray[$ctr] == "DB20000I The CALL command completed successfully.") { printf ("$outputArray[$ctr]\n"); printf ("Call was apparently successful.\n"); } else { printf ("Call apparently failed.\n"); printf ("$outputArray[$ctr]\n"); } break; } if (substr($outputArray[$ctr], 0, 22) == 'CALL SQLJ.INSTALL_JAR(') { $checkNextLine = 1; printf ("$outputArray[$ctr]\n"); } } if ($checkNextLine == 0) { printf ("Looks like the 'call sqlj.install_jar()' was never called.\n"); } How would you like to see the error-checking for this done? |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
i assume $outputArray is your result from exec, right? are you sure "DB20000I The CALL command completed successfully." is not internalized / translated in different languages? [code] if (GalleryUtilities::isA($platform, 'WinNtPlatform')) { $fileName = $platform->tempnam($gallery->getConfig('data.gallery.tmp'), 'db2_'); ...of course you could also do a for or a while loop, but i guess that's fine. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> DB20000I Yes, you're absolutely right. Good catch. > $platform->exec(array(array($cmd, $fileName))); Why the "array()" castings? I just ran it like:
... and it worked OK. FYI, I prefer the for loop approach because I have to make sure it's the DB20000I that comes immediately the INSTALL call (as opposed to the one from the REMOVE call) that I'm catching. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Oh, also... How do we delete the temporary SQL file? It should be deleted ASAP because it contains a password. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
@why array: @how to remove: @check: $i = 0; if (!$ok) { |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> you must use the $platform->exec I can't get the ^$$@!*#^ thing to work. The stack trace in the browser isn't helpful, but in install.log the symptom looks like the CREATE FUNCTION is being run wthout the jar having been installed. So obviously the jar install is failing, but I don't know why. Install.log says:
But there's noting in that output file: C:\My Server\gallery2>type C:\WINDOWS\TEMP\g2d2D90.tmp The system cannot find the file specified. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
2> onyl redirects the error output. you're not interested in that. check $success and for debugging, use var_dump($results); |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Code: list ($success, $outputArray) = $platform->exec(array(array($cmd, $fileName))); printf("<br>\$success = \"$success\".\n"); printf("<br>\n"); var_dump($outputArray); Result: $success = "". array(0) { } |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
yep, $success = false in this case. (false prints as empty string). well, you're on windows. so it could also be a permission issue. are you using iis or apache? |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Using Apache 2.049. Ah, you may have just put me on the road to the answer. My g2data directory is not under my server (therefore not writable by it). Should it be? |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
g2data needs to be writable. but if it wasn't, the installer couldn0t have created the dir structure that is now in g2data. that's not it. and if you try it with a normal exec, does it work? (before in your original php script, it worked. but does it still with the generated sql file etcetc?) |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Yes it works with regular exec($cmd, $outputArray). Code: // Create a temporary file to hold the sql $fileName = $platform->tempnam($gallery->getConfig('data.gallery.tmp'), 'db2_'); $pathToJar = dirname(__FILE__) . $platform->getDirectorySeparator() . 'g2_db2_bit_or.jar'; $buf = sprintf("CONNECT TO gallery2 USER %s USING %s\n CALL SQLJ.REMOVE_JAR('g2_db2_jar')\n CALL SQLJ.INSTALL_JAR('file:%s', 'g2_db2_jar')\n CONNECT RESET", $this->_username, $this->_password, $pathToJar); $platform->atomicWrite($fileName, $buf); if (GalleryUtilities::isA($platform, 'WinNtPlatform')) { //$cmd = "db2cmd /c /w /i db2 -vf "; $cmd = "db2cmd /c /w /i db2 -vf $fileName"; } else { //$cmd = "db2 -vf "; $cmd = "db2 -vf $fileName"; } printf ("\$cmd = \"$cmd\".\n"); exec($cmd, $outputArray); // list ($success, $outputArray) = $platform->exec(array(array($cmd, $fileName))); //printf("<br>\$success = \"$success\".\n"); printf("<br>\n"); var_dump($outputArray); Results: $cmd = "db2cmd /c /w /i db2 -vf C:\WINDOWS\TEMP\db22DCF.tmp". array(21) { [0]=> string(38) " CONNECT TO gallery2 USER g2user USING" [1]=> string(0) "" [2]=> string(34) " Database Connection Information" [3]=> string(0) "" [4]=> string(38) " Database server = DB2/NT 8.2.2" [5]=> string(32) " SQL authorization ID = G2USER" [6]=> string(34) " Local database alias = GALLERY2" [7]=> string(0) "" [8]=> string(0) "" [9]=> string(34) "CALL SQLJ.REMOVE_JAR('g2_db2_jar')" [10]=> string(76) "SQL20201N The install, replace or remove of "G2USER .G2_DB2_JAR" failed as" [11]=> string(40) "the jar name is invalid. SQLSTATE=46002" [12]=> string(0) "" [13]=> string(0) "" [14]=> string(135) "CALL SQLJ.INSTALL_JAR('file:C:\My Server\gallery2\modules\core\classes\GalleryStorage\DatabaseStorage\g2_db2_bit_or.jar', 'g2_db2_jar')" [15]=> string(50) "DB20000I The CALL command completed successfully." [16]=> string(0) "" [17]=> string(0) "" [18]=> string(13) "CONNECT RESET" [19]=> string(49) "DB20000I The SQL command completed successfully." [20]=> string(0) "" } |
|