"COALESCE(parent2.parentid, parent1.parentid, parent0.parentid, parent0.categoryid) AS catidpath1, ".
"IF (parent2.parentid IS NOT NULL, parent1.parentid, IF (parent1.parentid IS NOT NULL, parent0.parentid, IF (parent0.parentid IS NOT NULL, parent0.categoryid, NULL))) AS catidpath2, ".
"IF (parent2.parentid IS NOT NULL, parent0.parentid, IF (parent1.parentid IS NOT NULL, parent0.categoryid, NULL)) AS catidpath3 ".
"FROM ^posts LEFT JOIN ^categories AS parent0 ON ^posts.categoryid=parent0.categoryid LEFT JOIN ^categories AS parent1 ON parent0.parentid=parent1.categoryid LEFT JOIN ^categories AS parent2 ON parent1.parentid=parent2.categoryid WHERE ^posts.postid BETWEEN # AND #) AS a SET x.catidpath1=a.catidpath1, x.catidpath2=a.catidpath2, x.catidpath3=a.catidpath3 WHERE x.postid=a.postid",
$firstpostid,$lastpostid
);// requires QA_CATEGORY_DEPTH=4
}
/**
* Get the full category path (including categoryid) for $postid
* @param $postid
* @return array|null
*/
functionqa_db_post_get_category_path($postid)
{
returnqa_db_read_one_assoc(qa_db_query_sub(
'SELECT categoryid, catidpath1, catidpath2, catidpath3 FROM ^posts WHERE postid=#',
$postid
));// requires QA_CATEGORY_DEPTH=4
}
/**
* Update the cached number of answers for $questionid in the database, along with the highest netvotes of any of its answers
* @param $questionid
*/
functionqa_db_post_acount_update($questionid)
{
if(qa_should_update_counts()){
qa_db_query_sub(
'INSERT INTO ^posts (categoryid, type, parentid, userid, cookieid, createip, title, content, format, tags, notify, name, created) '.
"UPDATE ^posts AS x, (SELECT COUNT(*) AS acount, COALESCE(GREATEST(MAX(netvotes), 0), 0) AS amaxvote FROM ^posts WHERE parentid=# AND type='A') AS a SET x.acount=a.acount, x.amaxvote=a.amaxvote WHERE x.postid=#",
// This seemed like the most sensible approach which avoids explicitly calculating the category's depth in the hierarchy
qa_db_query_sub(
"UPDATE ^posts AS x, (SELECT ^posts.postid, ".
"COALESCE(parent2.parentid, parent1.parentid, parent0.parentid, parent0.categoryid) AS catidpath1, ".
"IF (parent2.parentid IS NOT NULL, parent1.parentid, IF (parent1.parentid IS NOT NULL, parent0.parentid, IF (parent0.parentid IS NOT NULL, parent0.categoryid, NULL))) AS catidpath2, ".
"IF (parent2.parentid IS NOT NULL, parent0.parentid, IF (parent1.parentid IS NOT NULL, parent0.categoryid, NULL)) AS catidpath3 ".
"FROM ^posts LEFT JOIN ^categories AS parent0 ON ^posts.categoryid=parent0.categoryid LEFT JOIN ^categories AS parent1 ON parent0.parentid=parent1.categoryid LEFT JOIN ^categories AS parent2 ON parent1.parentid=parent2.categoryid WHERE ^posts.postid BETWEEN # AND #) AS a SET x.catidpath1=a.catidpath1, x.catidpath2=a.catidpath2, x.catidpath3=a.catidpath3 WHERE x.postid=a.postid",
$firstpostid,$lastpostid
"UPDATE ^categories SET qcount=GREATEST( (SELECT COUNT(*) FROM ^posts WHERE categoryid=# AND type='Q'), (SELECT COUNT(*) FROM ^posts WHERE catidpath1=# AND type='Q'), (SELECT COUNT(*) FROM ^posts WHERE catidpath2=# AND type='Q'), (SELECT COUNT(*) FROM ^posts WHERE catidpath3=# AND type='Q') ) WHERE categoryid=#",
Get the full category path (including categoryid) for $postid
*/
{
returnqa_db_read_one_assoc(qa_db_query_sub(
'SELECT categoryid, catidpath1, catidpath2, catidpath3 FROM ^posts WHERE postid=#',
$postid
));// requires QA_CATEGORY_DEPTH=4
}
functionqa_db_post_acount_update($questionid)
/*
Update the cached number of answers for $questionid in the database, along with the highest netvotes of any of its answers
*/
{
if(qa_should_update_counts())
qa_db_query_sub(
"UPDATE ^posts AS x, (SELECT COUNT(*) AS acount, COALESCE(GREATEST(MAX(netvotes), 0), 0) AS amaxvote FROM ^posts WHERE parentid=# AND type='A') AS a SET x.acount=a.acount, x.amaxvote=a.amaxvote WHERE x.postid=#",
$questionid,$questionid
);
qa_db_query_sub(
'INSERT INTO ^titlewords (postid, wordid) VALUES #',
$rowstoadd
);
}
}
/**
* Add rows into the database content index, where $postid (of $type, with the antecedent $questionid)
* has words as per the keys of $wordidcounts, and the corresponding number of those words in the values.
// This seemed like the most sensible approach which avoids explicitly calculating the category's depth in the hierarchy
qa_db_query_sub(
"UPDATE ^categories SET qcount=GREATEST( (SELECT COUNT(*) FROM ^posts WHERE categoryid=# AND type='Q'), (SELECT COUNT(*) FROM ^posts WHERE catidpath1=# AND type='Q'), (SELECT COUNT(*) FROM ^posts WHERE catidpath2=# AND type='Q'), (SELECT COUNT(*) FROM ^posts WHERE catidpath3=# AND type='Q') ) WHERE categoryid=#",
Add rows into the database index of whole tags, where $postid contains the tags $wordids
*/
{
if(count($wordids))
qa_db_query_sub(
'INSERT INTO ^posttags (postid, wordid, postcreated) SELECT postid, wordid, created FROM ^words, ^posts WHERE postid=# AND wordid IN ($)',
$postid,$wordids
);
}
/**
* Return an array mapping each word in $words to its corresponding wordid in the database, adding any that are missing
* @param $words
* @return array
*/
functionqa_db_word_mapto_ids_add($words)
{
$wordtoid=qa_db_word_mapto_ids($words);
functionqa_db_word_mapto_ids($words)
/*
Return an array mapping each word in $words to its corresponding wordid in the database
*/
{
if(count($words))
returnqa_db_read_all_assoc(qa_db_query_sub(
'SELECT wordid, word FROM ^words WHERE word IN ($)',$words
),'word','wordid');
else
returnarray();
$wordstoadd=array();
foreach($wordsas$word){
if(!isset($wordtoid[$word]))
$wordstoadd[]=$word;
}
if(count($wordstoadd)){
qa_db_query_sub('LOCK TABLES ^words WRITE');// to prevent two requests adding the same word
functionqa_db_word_mapto_ids_add($words)
/*
Return an array mapping each word in $words to its corresponding wordid in the database, adding any that are missing
*/
{
$wordtoid=qa_db_word_mapto_ids($words);
$wordtoid=qa_db_word_mapto_ids($words);// map it again in case table content changed before it was locked
$wordstoadd=array();
foreach($wordsas$word)
$rowstoadd=array();
foreach($wordsas$word){
if(!isset($wordtoid[$word]))
$wordstoadd[]=$word;
if(count($wordstoadd)){
qa_db_query_sub('LOCK TABLES ^words WRITE');// to prevent two requests adding the same word
$wordtoid=qa_db_word_mapto_ids($words);// map it again in case table content changed before it was locked
$rowstoadd=array();
foreach($wordsas$word)
if(!isset($wordtoid[$word]))
$rowstoadd[]=array($word);
qa_db_query_sub('INSERT IGNORE INTO ^words (word) VALUES $',$rowstoadd);
$rowstoadd[]=array($word);
}
qa_db_query_sub('UNLOCK TABLES');
qa_db_query_sub('INSERT IGNORE INTO ^words (word) VALUES $',$rowstoadd);
$wordtoid=qa_db_word_mapto_ids($words);// do it one last time
}
qa_db_query_sub('UNLOCK TABLES');
return$wordtoid;
$wordtoid=qa_db_word_mapto_ids($words);// do it one last time
}
return$wordtoid;
}
functionqa_db_word_titlecount_update($wordids)
/*
Update the titlecount column in the database for the words in $wordids, based on how many posts they appear in the title of
*/
{
if(qa_should_update_counts()&&count($wordids))
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^titlewords.wordid) AS titlecount FROM ^words LEFT JOIN ^titlewords ON ^titlewords.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.titlecount=a.titlecount WHERE x.wordid=a.wordid',
$wordids
);
/**
* Update the titlecount column in the database for the words in $wordids, based on how many posts they appear in the title of
* @param $wordids
*/
functionqa_db_word_titlecount_update($wordids)
{
if(qa_should_update_counts()&&count($wordids)){
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^titlewords.wordid) AS titlecount FROM ^words LEFT JOIN ^titlewords ON ^titlewords.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.titlecount=a.titlecount WHERE x.wordid=a.wordid',
$wordids
);
}
}
functionqa_db_word_contentcount_update($wordids)
/*
Update the contentcount column in the database for the words in $wordids, based on how many posts they appear in the content of
*/
{
if(qa_should_update_counts()&&count($wordids))
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^contentwords.wordid) AS contentcount FROM ^words LEFT JOIN ^contentwords ON ^contentwords.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.contentcount=a.contentcount WHERE x.wordid=a.wordid',
$wordids
);
/**
* Update the contentcount column in the database for the words in $wordids, based on how many posts they appear in the content of
* @param $wordids
*/
functionqa_db_word_contentcount_update($wordids)
{
if(qa_should_update_counts()&&count($wordids)){
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^contentwords.wordid) AS contentcount FROM ^words LEFT JOIN ^contentwords ON ^contentwords.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.contentcount=a.contentcount WHERE x.wordid=a.wordid',
$wordids
);
}
}
functionqa_db_word_tagwordcount_update($wordids)
/*
Update the tagwordcount column in the database for the individual tag words in $wordids, based on how many posts they appear in the tags of
*/
{
if(qa_should_update_counts()&&count($wordids))
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^tagwords.wordid) AS tagwordcount FROM ^words LEFT JOIN ^tagwords ON ^tagwords.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.tagwordcount=a.tagwordcount WHERE x.wordid=a.wordid',
$wordids
);
/**
* Update the tagwordcount column in the database for the individual tag words in $wordids, based on how many posts they appear in the tags of
* @param $wordids
*/
functionqa_db_word_tagwordcount_update($wordids)
{
if(qa_should_update_counts()&&count($wordids)){
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^tagwords.wordid) AS tagwordcount FROM ^words LEFT JOIN ^tagwords ON ^tagwords.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.tagwordcount=a.tagwordcount WHERE x.wordid=a.wordid',
$wordids
);
}
}
functionqa_db_word_tagcount_update($wordids)
/*
Update the tagcount column in the database for the whole tags in $wordids, based on how many posts they appear as tags of
*/
{
if(qa_should_update_counts()&&count($wordids))
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^posttags.wordid) AS tagcount FROM ^words LEFT JOIN ^posttags ON ^posttags.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.tagcount=a.tagcount WHERE x.wordid=a.wordid',
$wordids
);
/**
* Update the tagcount column in the database for the whole tags in $wordids, based on how many posts they appear as tags of
* @param $wordids
*/
functionqa_db_word_tagcount_update($wordids)
{
if(qa_should_update_counts()&&count($wordids)){
qa_db_query_sub(
'UPDATE ^words AS x, (SELECT ^words.wordid, COUNT(^posttags.wordid) AS tagcount FROM ^words LEFT JOIN ^posttags ON ^posttags.wordid=^words.wordid WHERE ^words.wordid IN (#) GROUP BY wordid) AS a SET x.tagcount=a.tagcount WHERE x.wordid=a.wordid',
$wordids
);
}
}
functionqa_db_qcount_update()
/*
Update the cached count in the database of the number of questions (excluding hidden/queued)
More about this license: http://www.question2answer.org/license.php
*/
if(!defined('QA_VERSION')){// don't allow this page to be requested directly from browser
header('Location: ../');
exit;
}
functionqa_db_uservote_set($postid,$userid,$vote)
/*
Set the vote for $userid on $postid to $vote in the database
*/
{
$vote=max(min(($vote),1),-1);
qa_db_query_sub(
'INSERT INTO ^uservotes (postid, userid, vote, flag) VALUES (#, #, #, 0) ON DUPLICATE KEY UPDATE vote=#',
$postid,$userid,$vote,$vote
);
}
functionqa_db_uservote_get($postid,$userid)
/*
Get the vote for $userid on $postid from the database (or NULL if none)
*/
{
returnqa_db_read_one_value(qa_db_query_sub(
'SELECT vote FROM ^uservotes WHERE postid=# AND userid=#',
$postid,$userid
),true);
}
functionqa_db_userflag_set($postid,$userid,$flag)
/*
Set the flag for $userid on $postid to $flag (true or false) in the database
*/
{
$flag=$flag?1:0;
if(!defined('QA_VERSION')){// don't allow this page to be requested directly from browser
header('Location: ../');
exit;
}
/**
* Set the vote for $userid on $postid to $vote in the database
* @param $postid
* @param $userid
* @param $vote
*/
functionqa_db_uservote_set($postid,$userid,$vote)
{
$vote=max(min(($vote),1),-1);
qa_db_query_sub(
'INSERT INTO ^uservotes (postid, userid, vote, flag) VALUES (#, #, #, 0) ON DUPLICATE KEY UPDATE vote=#',
$postid,$userid,$vote,$vote
);
}
/**
* Get the vote for $userid on $postid from the database (or NULL if none)
* @param $postid
* @param $userid
* @return mixed|null
*/
functionqa_db_uservote_get($postid,$userid)
{
returnqa_db_read_one_value(qa_db_query_sub(
'SELECT vote FROM ^uservotes WHERE postid=# AND userid=#',
$postid,$userid
),true);
}
/**
* Set the flag for $userid on $postid to $flag (true or false) in the database
* @param $postid
* @param $userid
* @param $flag
*/
functionqa_db_userflag_set($postid,$userid,$flag)
{
$flag=$flag?1:0;
qa_db_query_sub(
'INSERT INTO ^uservotes (postid, userid, vote, flag) VALUES (#, #, 0, #) ON DUPLICATE KEY UPDATE flag=#',
$postid,$userid,$flag,$flag
);
}
/**
* Clear all flags for $postid in the database
* @param $postid
*/
functionqa_db_userflags_clear_all($postid)
{
qa_db_query_sub(
'UPDATE ^uservotes SET flag=0 WHERE postid=#',
$postid
);
}
/**
* Recalculate the cached count of upvotes, downvotes and netvotes for $postid in the database
* @param $postid
*/
functionqa_db_post_recount_votes($postid)
{
if(qa_should_update_counts())
qa_db_query_sub(
'INSERT INTO ^uservotes (postid, userid, vote, flag) VALUES (#, #, 0, #) ON DUPLICATE KEY UPDATE flag=#',
$postid,$userid,$flag,$flag
'UPDATE ^posts AS x, (SELECT COALESCE(SUM(GREATEST(0,vote)),0) AS upvotes, -COALESCE(SUM(LEAST(0,vote)),0) AS downvotes FROM ^uservotes WHERE postid=#) AS a SET x.upvotes=a.upvotes, x.downvotes=a.downvotes, x.netvotes=a.upvotes-a.downvotes WHERE x.postid=#',
$postid,$postid
);
}
}
functionqa_db_userflags_clear_all($postid)
/*
Clear all flags for $postid in the database
*/
{
/**
* Recalculate the cached count of flags for $postid in the database
* @param $postid
*/
functionqa_db_post_recount_flags($postid)
{
if(qa_should_update_counts())
qa_db_query_sub(
'UPDATE ^uservotes SET flag=0 WHERE postid=#',
$postid
'UPDATE ^posts AS x, (SELECT COALESCE(SUM(IF(flag, 1, 0)),0) AS flagcount FROM ^uservotes WHERE postid=#) AS a SET x.flagcount=a.flagcount WHERE x.postid=#',
$postid,$postid
);
}
functionqa_db_post_recount_votes($postid)
/*
Recalculate the cached count of upvotes, downvotes and netvotes for $postid in the database
*/
{
if(qa_should_update_counts())
qa_db_query_sub(
'UPDATE ^posts AS x, (SELECT COALESCE(SUM(GREATEST(0,vote)),0) AS upvotes, -COALESCE(SUM(LEAST(0,vote)),0) AS downvotes FROM ^uservotes WHERE postid=#) AS a SET x.upvotes=a.upvotes, x.downvotes=a.downvotes, x.netvotes=a.upvotes-a.downvotes WHERE x.postid=#',
$postid,$postid
);
}
functionqa_db_post_recount_flags($postid)
/*
Recalculate the cached count of flags for $postid in the database
*/
{
if(qa_should_update_counts())
qa_db_query_sub(
'UPDATE ^posts AS x, (SELECT COALESCE(SUM(IF(flag, 1, 0)),0) AS flagcount FROM ^uservotes WHERE postid=#) AS a SET x.flagcount=a.flagcount WHERE x.postid=#',
$postid,$postid
);
}
functionqa_db_uservote_post_get($postid)
/*
Returns all non-zero votes on post $postid from the database as an array of [userid] => [vote]
*/
{
}
/**
* Returns all non-zero votes on post $postid from the database as an array of [userid] => [vote]
* @param $postid
* @return array
*/
functionqa_db_uservote_post_get($postid)
{
returnqa_db_read_all_assoc(qa_db_query_sub(
'SELECT userid, vote FROM ^uservotes WHERE postid=# AND vote!=0',
$postid
),'userid','vote');
}
/**
* Returns all the postids from the database for posts that $userid has voted on or flagged
* @param $userid
* @return array
*/
functionqa_db_uservoteflag_user_get($userid)
{
returnqa_db_read_all_values(qa_db_query_sub(
'SELECT postid FROM ^uservotes WHERE userid=# AND (vote!=0) OR (flag!=0)',
$userid
));
}
/**
* Return information about all the non-zero votes and/or flags on the posts in postids, including user handles for internal user management
* @param $postids
* @return array
*/
functionqa_db_uservoteflag_posts_get($postids)
{
if(QA_FINAL_EXTERNAL_USERS){
returnqa_db_read_all_assoc(qa_db_query_sub(
'SELECT userid, vote FROM ^uservotes WHERE postid=# AND vote!=0',
$postid
),'userid','vote');
}
functionqa_db_uservoteflag_user_get($userid)
/*
Returns all the postids from the database for posts that $userid has voted on or flagged
*/
{
returnqa_db_read_all_values(qa_db_query_sub(
'SELECT postid FROM ^uservotes WHERE userid=# AND (vote!=0) OR (flag!=0)',
$userid
'SELECT postid, userid, vote, flag FROM ^uservotes WHERE postid IN (#) AND ((vote!=0) OR (flag!=0))',
$postids
));
}else{
returnqa_db_read_all_assoc(qa_db_query_sub(
'SELECT postid, handle, vote, flag FROM ^uservotes LEFT JOIN ^users ON ^uservotes.userid=^users.userid WHERE postid IN (#) AND ((vote!=0) OR (flag!=0))',
$postids
));
}
functionqa_db_uservoteflag_posts_get($postids)
/*
Return information about all the non-zero votes and/or flags on the posts in postids, including user handles for internal user management
*/
{
if(QA_FINAL_EXTERNAL_USERS)
returnqa_db_read_all_assoc(qa_db_query_sub(
'SELECT postid, userid, vote, flag FROM ^uservotes WHERE postid IN (#) AND ((vote!=0) OR (flag!=0))',
$postids
));
else
returnqa_db_read_all_assoc(qa_db_query_sub(
'SELECT postid, handle, vote, flag FROM ^uservotes LEFT JOIN ^users ON ^uservotes.userid=^users.userid WHERE postid IN (#) AND ((vote!=0) OR (flag!=0))',
$postids
));
}
/**
* Remove all votes assigned to a post that had been cast by the owner of the post.
*
* @param int $postid The post ID from which the owner's votes will be removed.
*/
functionqa_db_uservote_remove_own($postid)
{
qa_db_query_sub(
'DELETE uv FROM ^uservotes uv JOIN ^posts p ON uv.postid=p.postid AND uv.userid=p.userid WHERE uv.postid=#',$postid
);
}
/*
Omit PHP closing tag to help avoid accidental output
*/
\ No newline at end of file
}
/**
* Remove all votes assigned to a post that had been cast by the owner of the post.
*
* @param int $postid The post ID from which the owner's votes will be removed.
*/
functionqa_db_uservote_remove_own($postid)
{
qa_db_query_sub(
'DELETE uv FROM ^uservotes uv JOIN ^posts p ON uv.postid=p.postid AND uv.userid=p.userid WHERE uv.postid=#',$postid