There is a horribly coded loop in this mod that runs a separate query for every forum you have and is based on MAX(id) that in reality can quickly become meaningless.  In index.php (MODDED):

REPLACE

$sfdb = array($_parent_id_, $_topics_, $_posts_, $_last_post_id_, $_last_poster_, $_last_post_);
$subforum = $db->query('SELECT MAX(id) FROM '.$db->prefix.'forums') or error('Unable to fetch sub forum info',__FILE__,__LINE__,$db->error());
for ($i = 0; $i < $db->result($subforum)+1; $i++)
{
 $forums_info = $db->query('SELECT num_topics, num_posts, parent_forum_id, last_post_id, last_poster, last_post FROM '.$db->prefix.'forums WHERE id='.$i) or error('Unable to fetch sub forum info',__FILE__,__LINE__,$db->error());
 $current = $db->fetch_assoc($forums_info);
 if ($current['parent_forum_id'] != 0)
  {
   $sfdb[$i][0] = $current['parent_forum_id'];
   $sfdb[$i][1] = $current['num_topics'];
   $sfdb[$i][2] = $current['num_posts'];
   $sfdb[$i][3] = $current['last_post_id'];
   $sfdb[$i][4] = $current['last_poster'];
   $sfdb[$i][5] = $current['last_post'];
  }
}

WITH

$i=0;
$sfdb = array($_parent_id_, $_topics_, $_posts_, $_last_post_id_, $_last_poster_, $_last_post_);
$forums_info = $db->query('SELECT num_topics, num_posts, parent_forum_id, last_post_id, last_poster, last_post FROM '.$db->prefix.'forums') or error(implode($db->error(),''),__FILE__,__LINE__,$db->error());
while($current = $db->fetch_assoc($forums_info)) {
 if ($current['parent_forum_id'] != 0)
  {
   $sfdb[$i][0] = $current['parent_forum_id'];
   $sfdb[$i][1] = $current['num_topics'];
   $sfdb[$i][2] = $current['num_posts'];
   $sfdb[$i][3] = $current['last_post_id'];
   $sfdb[$i][4] = $current['last_poster'];
   $sfdb[$i][5] = $current['last_post'];
  }
$i++;
}

And this is a good time to note:  after installing mods CHECK YOUR QUERIES AND QUERY COUNT!  After fixing this code block I went from 61 queries on index.php to 12.;

Frank H wrote:

in the rules, you could easily end up with more than 255 chars ... as you set them with

txt"jpg"jpeg"gif"bmp"tga"tiff"tif"zip"z01"z02"z03"z04"rar"r00"r01"r02
and so on...

(and since it doesn't store so many lines, I figured it would be ok ... as it's only a per forum and per group setting)


Thanks for the input though, it's always nice to get tips and such smile

Okay, I'll give you that it's possible, I guess I just changed it to something I knew would work for my particular situation because screw typing in that many extensions wink

Oh, there is also a matter of your AP_* file being pretty incompatible with Postgres.  In this case, one of the problems is changing tinyint(1) to Boolean (which I admit isn't actually necessary as INT works just fine, but from a semantic point of view using Boolean is better), so all your "WHERE 1" statements need to be changed to "WHERE true", though I see no reason for those statements anyway, I mean "true" is always "true" just like "1" is always "1", right?  Once again, I could be wrong here.  Also, for compatability reasons you should avoid using ` as a quote character, instead use ', ", or nothing as the case dictates.  I can supply a more compatible version of this file if you like. 

I think the JOIN is easily the best way to go, the only extra "gotcha" associated with it is the loop to delete duplicate posts, but if v1.3 has a "proper" templating system then you won't even need that.  There's quite a bit of optimization that could be done, but to be perfectly honest the only place it really matters is in viewtopic.php, all the other stuff either can't suffer from its time complexity or is an Admin area, and who cares how fast those are tongue

Good luck with the next version smile


EDIT:  Most of the Admin Plugin for this mod is incompatible with Postgres, too sad

I didn't read EVERY page of this thread, but here are a couple fixes (hopefully not already posted):

1) Get rid of excess queries for every post

Okay, part one here deals with this piece of code:

//fetch the rules of the forum, and check so that the user is allowed to download.
            $result_attach_two = $db->query('SELECT ar.rules FROM '.$db->prefix.'attach_2_rules AS ar WHERE ar.group_id=\''.$pun_user['group_id'].'\' AND ar.forum_id='.$cur_topic['forum_id'].' LIMIT 1')or error('Unable to fetch rules for the attachments', __FILE__, __LINE__, $db->error());
            if($db->num_rows($result_attach_two)==1){
                list($attach_rules)=$db->fetch_row($result_attach_two);
                $attach_allow_download = attach_rules($attach_rules,ATTACH_DOWNLOAD);
            }

There is no conceivable reason why the attachment rules would need to be checked for every post because the user's group_id and forum_id don't change for each post.  The fix?  Move this above or below the SQL block beginning with "// Retrieve the posts (and their respective poster/online status)", whichever tickles your fancy.  Oh, and if I've somehow gotten this wrong and this query isn't run every post (since it's just completely silly to be doing it) I apologize, but it seems to me that it is smile

Now for part two, dealing with this:

// Check if this post has any attachments
    $result_attach = $db->query('SELECT af.id, af.filename, af.size, af.downloads FROM '.$db->prefix.'attach_2_files AS af WHERE af.post_id='.$cur_post['id']) or error('Unable to fetch if there were any attachments to the post', __FILE__, __LINE__, $db->error());
    $attach_num = $db->num_rows($result_attach);
    if($attach_num > 0){ ...

You can cut this part out pretty easily by adding the following to your post retrieval query

LEFT JOIN '.$db->prefix.'attach_2_files AS af ON af.post_id=p.id

This simply says "additionally, grab all posts that also have a corresponding attachment".  Of course, since you can have more than one attachment per post, we need to clean dupes.  Now, because of how PunBB is setup, we need to add a loop before the fact and get all the attachments for a specific post and clean dupes that way.  If you want an arguably faster solution, you could build all the info for posts prior to outputting the template for a post instead of having the html spit out every loop, but I won't go into that.

FIND

while($cur_posts = $db->fetch_assoc($result) 
{

REPLACE WITH

// i added this method to dblayer/pgsql.php, you could use <db>_fetch_all($result) also
$posts = $db->fetch_all($result);
$x = 0;
$post_ids = array();
foreach($posts as $post) 
{
    // if it has an attachment
    if($post['attach_id'] != '') 
    {
        // MAY NEED TO BE CHANGED! Or made dynamic, but I'm lazy.  This basically depends on how many mods you have that affect the posts query.
                // in reality the slice isn't even necessary, it just cuts down on array size
        $attachments[$post['id']][] = array_slice($post,22,4);
    }
    // if this post is a dupe
    if(in_array($post['id'],$post_ids))
    {
        // remove it
        array_splice($posts,$x,1);
    }
    $post_ids[] = $post['id'];
    $x++;
}
foreach ($posts as $cur_post)
{

From here it's just simple changes to the loop that generates $attach_output, and you're done!  I would paste those changes, but I haven't actually bothered to go through and make them yet (or even install the mod tongue)  I read that you didn't want to alter PunBB's posts query, but the fact is that almost all mods change the fundamental queries on pages, this is to limit the number of queries.  Near as I can tell, you're adding n*2 queries per viewtopic page, where n = # replies.  That number can add up pretty fast, and although JOINs add overhead to a query, it's not as bad as asking the DB for stuff 30 times per page or more.  However, I still respect your decisions for the mod and am posting this more for those who want to replace your queries with a quick LEFT JOIN and PHP loop.


2) PostgreSQL Install Support

Since no mod developer anywhere seems to understand that MySQL syntax != standard, I've taken the liberty of posting the raw SQL for creating your tables in PostgreSQL below.  Obvious changes need to be made (pun_ replaced by $db->prefix, etc).

CREATE SEQUENCE "public"."pun_attach_2_files_id_seq";

CREATE TABLE "public"."pun_attach_2_files" (
  "id" SERIAL, 
  "owner" INTEGER DEFAULT 0 NOT NULL, 
  "post_id" INTEGER DEFAULT 0 NOT NULL, 
  "filename" VARCHAR(20) DEFAULT 'error.file'::character varying NOT NULL, 
  "extension" VARCHAR(64) DEFAULT 'error.file'::character varying NOT NULL, 
  "mime" VARCHAR(64), 
  "location" TEXT, 
  "size" INTEGER DEFAULT 0 NOT NULL, 
  "downloads" INTEGER DEFAULT 0 NOT NULL, 
  CONSTRAINT "pun_attach_2_files_pkey" PRIMARY KEY("id")
);

CREATE SEQUENCE "public"."pun_attach_2_rules_id_seq";

CREATE TABLE "public"."pun_attach_2_rules" (
  "id" SERIAL, 
  "forum_id" INTEGER DEFAULT 0 NOT NULL, 
  "group_id" INTEGER DEFAULT 0 NOT NULL, 
  "rules" INTEGER DEFAULT 0 NOT NULL, 
  "size" INTEGER DEFAULT 0 NOT NULL, 
  "per_post" SMALLINT DEFAULT 1 NOT NULL, 
  "file_ext" VARCHAR(200), 
  CONSTRAINT "pun_attach_2_rules_pkey" PRIMARY KEY("id")
);

I went with a VARCHAR for the file_ext field because it's impossible that someone would need a TEXT block to enter some file extensions...


And of course, thanks for creating the mod big_smile

I recently got back into PunBB and I love it.  I'm working on a large project and I want to integrate parts of the forum with my site (logging in, registering, etc) and I found PunBB would be much better than vBulletin for this task because it's not as complicated or bloated (with vB you basically have to integrate your site into the forums, not the other way around!).  In general I don't like "spaghetti" PHP code (html mixed in with php and so forth), but I can't argue with how simple it is to mod.  My first question to the developer is this:  why didn't you use a mature DB abstraction layer like ADOdb? Besides having to write fewer (if any?) conditional queries, you get a lot of things for free like automatic data sanitization, caching, database session handling (better than relying on cookies alone which PunBB seems to, though I could be wrong here), different connection types, etc.  Secondly, I couldn't find any information on this so I figured I'd ask here:  Does PunBB make use of any native caching?  It looks like the config file is cached, but that seems to be about it. 

I think PunBB is great for both PHP veterans and newbies alike.  It's ridiculously easy to mod for veterans and is a great start for newbies to learn the scripting language.  Just as claimed, it's fast and not bloated with every feature you can possibly imagine.  Oh, and it actually supports PostgreSQL natively! *bow*

Thanks for making such a simple yet awesome basic forum system! I'm going to have a lot of fun hacking my PunBB to hell and back wink