You are missing our premiere tool bar navigation system! Register and use it for FREE!

NukeCops  
•  Home •  Downloads •  Gallery •  Your Account •  Forums • 
Readme First
- Readme First! -

Read and follow the rules, otherwise your posts will be closed
Modules
· Home
· FAQ
· Buy a Theme
· Advertising
· AvantGo
· Bookmarks
· Columbia
· Community
· Donations
· Downloads
· Feedback
· Forums
· PHP-Nuke HOWTO
· Private Messages
· Search
· Statistics
· Stories Archive
· Submit News
· Surveys
· Theme Gallery
· Top
· Topics
· Your Account
Who's Online
There are currently, 49 guest(s) and 1 member(s) that are online.

You are Anonymous user. You can register for free by clicking here
Nuke Cops :: View topic - PhpNuke on MSSQL - working! (so far...) [ ]
 Forum FAQ  •  Search  •   •  Memberlist  •  Usergroups   •  Register  •  Profile •    •  Log in to check your private messages  •  Log in

 
Post new topic  Reply to topicprinter-friendly view
View previous topic Log in to check your private messages View next topic
Author Message
BarakRL
Nuke Cadet
Nuke Cadet


Joined: Jan 23, 2007
Posts: 6


PostPosted: Tue Jan 23, 2007 4:26 am Reply with quoteBack to top

I don't know if anyone have posted some kind of manual about mssql, but here's the why I've done it:

(Tested on Microsoft SQL Server 2000 Enterprise Edition.)

Part 1: Creating the database.

As you might know, the included .sql file doesn't work with MSSQL. To override this, I've:
a. installed MySQL and imported the .sql file.
b. installed MySQL ODBC Driver.
c. imported the databases from the MySQL server to the MSSQL server using the ODBC driver.
(d. Here something went wrong - The Auto Inc. fields weren't set as such so I had to manually set them the old way - one table at a time. you might wanna check the default value of the different fields while you're at it.)

Part 2: db\mssql.php.

It seems that the MSSQL layer has some issues that the phpbb team didn't handle. most of them are simple lower vs. upper case, but they also didn't know that the now() function should be replaced with getdate() in mssql. So to function sql_query() in mssql.php i've added at the beginning:

--- EDIT: Please see fix in newer post below. ---


Part 3: Reserved Words (bad programing=hard work)

There are many words that shouldn't have been used for programing as far as I see it, but it a bit too late now. Anyway, these are the reserved words (for mssql anyway) that I've found (i've added a 'n_' prefix to them in order to fix them, but it's a lot of work):

date *
position (btw, in the table "blocks", it was already called bposition...)
view
action *
time *
timeStamp
hour
year
month
var
count

* - be careful when renaming those, since they are also used for legit functions such as $time() and "<action=" in html.


4. Part 4: MSSQL - Null bug?

The last issue I came across was that if field of a query was a null, for some reason sometimes it was returned as " " (a space) or (0) (a zero). so in some cases, I had to change the code from -

if (<somefield> == '') {}

and such, to something like-

if (trim(<somefield>) == '') {}

--------------------------------

Anyway, this is what I've found so far. basic checks looks ok, but I guess there's still stuff to fix. I'll try to keep you updated.


Last edited by BarakRL on Fri Feb 02, 2007 2:31 am; edited 1 time in total
Find all posts by BarakRLView user's profileSend private message
BarakRL
Nuke Cadet
Nuke Cadet


Joined: Jan 23, 2007
Posts: 6


PostPosted: Tue Jan 23, 2007 2:33 pm Reply with quoteBack to top

well... It seems I spoke way too soon.

There's a BIG problem with the INSERT INTO queries which doesn't specify the "fields" into which the values are inserted [i.e. "insert into SomeTable values (list of values)" VS. "insert into SomeTable (list of fields) values (list of values)"]. The prblem is caused by the Auto number fields which while in MySQL could have been assigned a NULL which was ignored, this NULL triggers an error in MSSQL.
(google for SET IDENTITY_INSERT tablename ON/OFF.)

SO, since I don't wanna go the "lets rewrite every insert into query" way, I'm writing a function which I'll add to the data layer that will add the names of the relevant fields to the problematic query (and will remove the invalid nulls).

Again, I'll be back.
Find all posts by BarakRLView user's profileSend private message
Evaders99
Site Admin
Site Admin


Joined: Aug 17, 2003
Posts: 12403


PostPosted: Tue Jan 23, 2007 11:00 pm Reply with quoteBack to top

Sounds like a lot of work to make compliant. Best of luck on this

_________________
Helping those that help themselves
Read FIRST or DIE!

"Fighting is terrible, but not as terrible as losing the will to fight."
Star Wars Rebellion Network - Need Help? Evaders Squadron Coding
Find all posts by Evaders99View user's profileSend private messageVisit poster's websiteAIM Address
BarakRL
Nuke Cadet
Nuke Cadet


Joined: Jan 23, 2007
Posts: 6


PostPosted: Thu Jan 25, 2007 6:44 am Reply with quoteBack to top

just a quick update.

I've erased most of the changes I've made to the sql_query() function, leaving only:

Code:
  $query=str_ireplace("now()", "getdate()" ,$query);
  $query=str_ireplace("\'", '\'\'' ,$query); //changing  \' -> ''


and changed
Code:
if( preg_match('#^SELECT(.*?)(LIMIT ([0-9]+)[, ]*([0-9]+)*)?$#s', $query, $limits) )

to
Code:
if( preg_match('#^SELECT(.*?)(LIMIT ([0-9]+)[, ]*([0-9]+)*)?$#si', trim($query), $limits) )

(Edited [01-02-07] adding case insensitive, and trim.)

and then, after the line:
Code:
else if( preg_match('#^INSERT #i', $query) )
{


adding this:
Code:
if (insert_has_fields($query)) {
   //remove null fields?
}
else {
   $nskip = insert_null_values_count($query);
   $nlimit = insert_values_count($query)-insert_null_values_count($query);
   $query= inject_insert_fields($query,get_fields(get_table($query),$nskip,$nlimit));
}


I'll post the new function soon.


Last edited by BarakRL on Fri Feb 02, 2007 2:33 am; edited 1 time in total
Find all posts by BarakRLView user's profileSend private message
BarakRL
Nuke Cadet
Nuke Cadet


Joined: Jan 23, 2007
Posts: 6


PostPosted: Thu Jan 25, 2007 8:55 am Reply with quoteBack to top

This is the first (and hopefully the last) version of the function I've added that are used by the MS-SQL layer.

(I've added them to db.php, but you can save them to a new file and use include or some thing like that...)

Code:
function get_table($query)
{
   if( preg_match('#^SELECT #i', $query) ) {
      $subject =explode('FROM',strtoupper($query),3);
      $subject =explode(' ',$subject[1] ,3);
   }
   else if( preg_match('#^INSERT #i',$query)) {
      $subject =explode('INTO',strtoupper($query),3);
      $subject =explode(' ',$subject[1] ,3);
   }
   return $subject[1];
}

function get_fields($table, $numskip = 0, $numlimit = -1)
{   
   global $db;
   $retval='';
   $num=1;
   $num_added=0;
   $result = $db->sql_query("SELECT * FROM $table LIMIT 1");
   while($fld = mssql_fetch_field($result)){
   if (($num > $numskip) && (($numlimit == -1) or ($num_added < $numlimit))) {
      if ($retval == '') {
         $retval = $fld->name;
      }
      else {
         $retval = $retval . ", " . $fld->name;       
      }
      $num_added=$num_added+1;
   }
   $num=$num+1;
   }
   return $retval;

}

function get_fields_count($table)
{   
   global $db;
   $retval=0;
   $result = $db->sql_query("SELECT * FROM $table LIMIT 1");
   while($fld = mssql_fetch_field($result)){
      $retval=$retval+1;      
   }
   return $retval;

}

function insert_has_fields($query)
{
   $retval=0;
   if( preg_match('#^INSERT #i',$query)) {
      $subject =spliti('INTO',$query,2);
      $subject =spliti(' ',$subject[1] ,3);
      $subject =spliti('VALUES',$subject[2] ,2);
      //$subject[0] = fields
      //$subject[1] = values
      if ($subject[0]) {
         $retval=1;
      }
   }
return $retval;
}

function insert_values_count($query)
{
   $retval=-1;
   if( preg_match('#^INSERT #i',$query)) {
      $subject =spliti('INTO',$query,2);
      $subject =spliti(' ',$subject[1] ,3);
      $subject =spliti('VALUES',$subject[2] ,2);
      //$subject[0] = fields
      //$subject[1] = values
      if ($subject[1]) {
         $retval=count(explode(',',$subject[1]));
      }
   }
return $retval;
}


function insert_null_values_count($query)
{
   $retval=-1;
   if( preg_match('#^INSERT #i',$query)) {
      $subject =spliti('INTO',$query,2);
      $subject =spliti(' ',$subject[1] ,3);
      $subject =spliti('VALUES',$subject[2] ,2);
      //$subject[0] = fields
      //$subject[1] = values
      if ($subject[1]) {
         $subject=explode(',',$subject[1]);         
         $cnt=0;
         while ( (str_replace(' ','',$subject[$cnt]) == "NULL") || (str_replace(' ','',$subject[$cnt]) == "(NULL") ) {            
            $cnt=$cnt+1;
         }
         $retval=$cnt;
      }
   }
return $retval;
}

function inject_insert_fields($query,$fields)
{
   $tablename=get_table($query);
   return "INSERT INTO $tablename (" . $fields . ") VALUES " . insert_remove_null_values($query);
}


function insert_remove_null_values($query)
{
// V.1.1 - fixed on 01/02/2007

   $retval='';
   if( preg_match('#^INSERT #i',$query)) {

      $subject =spliti('INTO',$query,2);
      $subject =spliti(' ',$subject[1] ,3);
      $subject =spliti('VALUES',$subject[2] ,2);
      //$subject[0] = fields
      //$subject[1] = values
      if ($subject[1]) {
         $subject=explode(',',$subject[1]);
         $vcnt=count($subject);
         $cnt=0;

         while ($cnt<$vcnt){
            if ((str_replace(' ','',$subject[$cnt]) == "NULL") || (str_replace(' ','',$subject[$cnt]) == "(NULL") ) {            
               //skip
            }
            else {
               if ($retval) {
                  $retval=$retval . ", ";
               }
               $retval=$retval . $subject[$cnt];
            }      
            $cnt=$cnt+1;   
         }
      }
   }
   if (substr($retval,0,1) != "(") {
      $retval="(" . $retval;
   }
   if (substr($retval,-1,1) != ")") {
      $retval= $retval . ")";
   }
return $retval;
}


And a quick note: the function only handles nulls at the beginning of the table, so make sure you keep the auto-numbered fields first.


Last edited by BarakRL on Thu Feb 01, 2007 9:53 am; edited 1 time in total
Find all posts by BarakRLView user's profileSend private message
BarakRL
Nuke Cadet
Nuke Cadet


Joined: Jan 23, 2007
Posts: 6


PostPosted: Thu Feb 01, 2007 9:47 am Reply with quoteBack to top

well, first of all I had a bug the insert_remove_null_values() function, so it has been edited.

And for the new problems:
1. dates.

well, MSSQL stores dates at its own will/format, so when ever you see -
Code:
ereg ("([0-9]{4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})", $VAR1, $VAR2);

You have to change it to:
Code:
ereg ("([0-9]{4})-([0-9]{1,2})-([0-9]{1,2}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})", date("Y-m-d H:i:s",strtotime($VAR1)), $VAR2);

(which to my opinion, this is how it should have been like anyway.)

if I'm not mistaken, this line appears 39 times in various files (with $time/$mydate/$ratingtimestamp/$editorialtimestamp as "$VAR1").

2. more on dates.

In modules\download\index.php, when querying a date, insted of using:
Code:
SELECT <whatever> from <sometable> WHERE n_date like '%<somedatevar>%'

it should be
Code:
SELECT <whatever> from <sometable> WHERE CONVERT(varchar(10), n_date, 121) like '%<somedatevar>%'


this will for the date to be converted to a string in a "YYYY-MM-DD" format and trim the time from it (since I used varchar(10)).

3. stupid extra space can cuz you serious headaches.

In the MSSQL.php file, I have added a trim() so change:
Code:
if( preg_match('#^SELECT(.*?)(LIMIT ([0-9]+)[, ]*([0-9]+)*)?$#si', $query, $limits) )

to:
Code:
if( preg_match('#^SELECT(.*?)(LIMIT ([0-9]+)[, ]*([0-9]+)*)?$#si', trim($query), $limits) )


(an extra space at the end of the query will prevent the LIMIT fix from working.)


well, that's all (for this week anyway...)
Find all posts by BarakRLView user's profileSend private message
rugbykp
Nuke Cadet
Nuke Cadet


Joined: Feb 05, 2007
Posts: 1


PostPosted: Mon Feb 05, 2007 9:06 am Reply with quoteBack to top

I can't seem to get it working with the mssql-odbc connection. I get this message on the admin.php page: "There seems to be a problem with the mssql-odbc server, sorry for the inconvenience." Here's my config:

$dbhost = "localhost";
$dbuname = "nuke_user"; #my sql 2005 user
$dbpass = "nuke_pwd";
$dbname = "my_nuke"; #the db name AND the System ODBC name
$prefix = "my_nuke"; #no clue if this is correct
$user_prefix = "nuke_user"; #no clue if this is correct
$dbtype = "mssql-odbc";
$sitekey = "SdFk*jkjbkuuz-dm98769.4b67DS+e4";
$gfx_chk = 0;
$subscription_url = "";
$admin_file = "admin";
$tipath = "images/topics/";
$nuke_editor = 1;
$display_errors = true;


Am I completely missing something here? I'm running this on Windows XP and Apache 2.2. I'm new to both PHP and Apache, so I apologize for the (probably) simple question.

Also, if the mssql-odbc DB layer is the problem, can you post or send me your working version? Thanks.
Find all posts by rugbykpView user's profileSend private message
BarakRL
Nuke Cadet
Nuke Cadet


Joined: Jan 23, 2007
Posts: 6


PostPosted: Tue Feb 06, 2007 8:12 am Reply with quoteBack to top

I haven't tried using MSSQL via ODBC, but directly so I use:

$dbhost = "localhost";
$dbuname = "MyUser";
$dbpass = "MyPass";
$dbname = "nuke";
$prefix = "nuke";
$user_prefix = "nuke";
$dbtype = "mssql";
$sitekey = "MySiteKey";
$gfx_chk = 0;
$subscription_url = "";
$admin_file = "admin";
$tipath = "images/topics/";
$nuke_editor = 1;
$display_errors = false;
Find all posts by BarakRLView user's profileSend private message
Display posts from previous:      
Post new topic  Reply to topicprinter-friendly view
View previous topic Log in to check your private messages View next topic
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum



Powered by phpBB © 2001, 2005 phpBB Group

Ported by Nuke Cops © 2003 www.nukecops.com
:: FI Theme :: PHP-Nuke theme by coldblooded (www.nukemods.com) ::
Powered by · TOGETHER TEAM srl ITALY http://www.togetherteam.it · DONDELEO E-COMMERCE http://www.DonDeLeo.com
Web site engine's code is Copyright © 2002 by PHP-Nuke. All Rights Reserved. PHP-Nuke is Free Software released under the GNU/GPL license.
Page Generation: 0.211 Seconds - 331 pages served in past 5 minutes. Nuke Cops Founded by Paul Laudanski (Zhen-Xjell)
:: FI Theme :: PHP-Nuke theme by coldblooded (www.nukemods.com) ::