qa_fatal_error('qa_db_count_active_users() called for unknown table');
break;
}
returnqa_db_read_one_value(qa_db_query_sub(
'SELECT COUNT(DISTINCT(userid)) FROM ^'.$table
));
}
functionqa_db_count_categories()
/*
Return number of categories in the database
*/
{
returnqa_db_read_one_value(qa_db_query_sub(
'SELECT COUNT(*) FROM ^categories'
));
}
functionqa_db_count_categoryid_qs($categoryid)
/*
Return number of questions in the database in $categoryid exactly, and not one of its subcategories
*/
{
returnqa_db_read_one_value(qa_db_query_sub(
"SELECT COUNT(*) FROM ^posts WHERE categoryid<=># AND type='Q'",
$categoryid
));
}
functionqa_db_get_user_visible_postids($userid)
/*
Return list of postids of visible or queued posts by $userid
*/
{
returnqa_db_read_all_values(qa_db_query_sub(
"SELECT postid FROM ^posts WHERE userid=# AND type IN ('Q', 'A', 'C', 'Q_QUEUED', 'A_QUEUED', 'C_QUEUED')",
$userid
));
}
functionqa_db_get_ip_visible_postids($ip)
/*
Return list of postids of visible or queued posts from $ip address
*/
{
returnqa_db_read_all_values(qa_db_query_sub(
"SELECT postid FROM ^posts WHERE createip=$ AND type IN ('Q', 'A', 'C', 'Q_QUEUED', 'A_QUEUED', 'C_QUEUED')",
@inet_pton($ip)
));
}
functionqa_db_postids_count_dependents($postids)
/*
Return an array whose keys contain the $postids which exist, and whose elements contain the number of other posts depending on each one
*/
{
if(count($postids))
returnqa_db_read_all_assoc(qa_db_query_sub(
"SELECT postid, COALESCE(childcount, 0) AS count FROM ^posts LEFT JOIN (SELECT parentid, COUNT(*) AS childcount FROM ^posts WHERE parentid IN (#) AND LEFT(type, 1) IN ('A', 'C') GROUP BY parentid) x ON postid=x.parentid WHERE postid IN (#)",
$postids,$postids
),'postid','count');
if(!defined('QA_VERSION')){// don't allow this page to be requested directly from browser
Return an array of the (up to) $count most recently created users who are awaiting approval and have not been blocked.
The array element for each user includes a 'profile' key whose value is an array of non-empty profile fields of the user.
*/
{
$results=qa_db_read_all_assoc(qa_db_query_sub(
"SELECT ^users.userid, UNIX_TIMESTAMP(created) AS created, createip, email, handle, flags, title, content FROM ^users LEFT JOIN ^userprofile ON ^users.userid=^userprofile.userid AND LENGTH(content)>0 WHERE level<# AND NOT (flags&#) ORDER BY created DESC LIMIT #",
Return whether there are any blobs whose content has been stored as a file on disk
*/
{
returnqa_db_read_one_value(qa_db_query_sub('SELECT blobid FROM ^blobs WHERE content IS NULL LIMIT 1'),true)!=null;
}
functionqa_db_has_blobs_in_db()
/*
Return whether there are any blobs whose content has been stored in the database
*/
{
returnqa_db_read_one_value(qa_db_query_sub('SELECT blobid FROM ^blobs WHERE content IS NOT NULL LIMIT 1'),true)!=null;
}
functionqa_db_category_last_pos($parentid)
/*
Return the maximum position of the categories with $parentid
*/
{
returnqa_db_read_one_value(qa_db_query_sub(
'SELECT COALESCE(MAX(position), 0) FROM ^categories WHERE parentid<=>#',
$parentid
));
}
functionqa_db_category_child_depth($categoryid)
/*
Return how many levels of subcategory there are below $categoryid
*/
{
// This is potentially a very slow query since it counts all the multi-generational offspring of a particular category
// But it's only used for admin purposes when moving a category around so I don't think it's worth making more efficient
// (Incidentally, this could be done by keeping a count for every category of how many generations of offspring it has.)
$result=qa_db_read_one_assoc(qa_db_query_sub(
'SELECT COUNT(child1.categoryid) AS count1, COUNT(child2.categoryid) AS count2, COUNT(child3.categoryid) AS count3 FROM ^categories AS child1 LEFT JOIN ^categories AS child2 ON child2.parentid=child1.categoryid LEFT JOIN ^categories AS child3 ON child3.parentid=child2.categoryid WHERE child1.parentid=#;',// requires QA_CATEGORY_DEPTH=4
Recalculate the backpath columns for all categories from $firstcategoryid to $lastcategoryid (if specified)
*/
{
if(!isset($lastcategoryid))
$lastcategoryid=$firstcategoryid;
qa_db_query_sub(
"UPDATE ^categories AS x, (SELECT cat1.categoryid, CONCAT_WS('/', cat1.tags, cat2.tags, cat3.tags, cat4.tags) AS backpath FROM ^categories AS cat1 LEFT JOIN ^categories AS cat2 ON cat1.parentid=cat2.categoryid LEFT JOIN ^categories AS cat3 ON cat2.parentid=cat3.categoryid LEFT JOIN ^categories AS cat4 ON cat3.parentid=cat4.categoryid WHERE cat1.categoryid BETWEEN # AND #) AS a SET x.backpath=a.backpath WHERE x.categoryid=a.categoryid",
* Return number of active users in database $table
* @param $table
* @return mixed|null
*/
functionqa_db_count_active_users($table)
{
switch($table){
case'posts':
case'uservotes':
case'userpoints':
break;
default:
qa_fatal_error('qa_db_count_active_users() called for unknown table');
break;
}
returnqa_db_read_one_value(qa_db_query_sub(
'SELECT COUNT(DISTINCT(userid)) FROM ^'.$table
));
}
/**
* Return number of categories in the database
*/
functionqa_db_count_categories()
{
returnqa_db_read_one_value(qa_db_query_sub(
'SELECT COUNT(*) FROM ^categories'
));
}
/**
* Return number of questions in the database in $categoryid exactly, and not one of its subcategories
* @param $categoryid
* @return mixed|null
*/
functionqa_db_count_categoryid_qs($categoryid)
{
returnqa_db_read_one_value(qa_db_query_sub(
"SELECT COUNT(*) FROM ^posts WHERE categoryid<=># AND type='Q'",
$categoryid
));
}
/**
* Return list of postids of visible or queued posts by $userid
* @param $userid
* @return array
*/
functionqa_db_get_user_visible_postids($userid)
{
returnqa_db_read_all_values(qa_db_query_sub(
"SELECT postid FROM ^posts WHERE userid=# AND type IN ('Q', 'A', 'C', 'Q_QUEUED', 'A_QUEUED', 'C_QUEUED')",
$userid
));
}
/**
* Return list of postids of visible or queued posts from $ip address
* @param $ip
* @return array
*/
functionqa_db_get_ip_visible_postids($ip)
{
returnqa_db_read_all_values(qa_db_query_sub(
"SELECT postid FROM ^posts WHERE createip=$ AND type IN ('Q', 'A', 'C', 'Q_QUEUED', 'A_QUEUED', 'C_QUEUED')",
@inet_pton($ip)
));
}
/**
* Return an array whose keys contain the $postids which exist, and whose elements contain the number of other posts depending on each one
* @param $postids
* @return array
*/
functionqa_db_postids_count_dependents($postids)
{
if(count($postids))
returnqa_db_read_all_assoc(qa_db_query_sub(
"SELECT postid, COALESCE(childcount, 0) AS count FROM ^posts LEFT JOIN (SELECT parentid, COUNT(*) AS childcount FROM ^posts WHERE parentid IN (#) AND LEFT(type, 1) IN ('A', 'C') GROUP BY parentid) x ON postid=x.parentid WHERE postid IN (#)",
$postids,$postids
),'postid','count');
else
returnarray();
}
/**
* Return an array of the (up to) $count most recently created users who are awaiting approval and have not been blocked.
* The array element for each user includes a 'profile' key whose value is an array of non-empty profile fields of the user.
* @param $count
* @return array
*/
functionqa_db_get_unapproved_users($count)
{
$results=qa_db_read_all_assoc(qa_db_query_sub(
"SELECT ^users.userid, UNIX_TIMESTAMP(created) AS created, createip, email, handle, flags, title, content FROM ^users LEFT JOIN ^userprofile ON ^users.userid=^userprofile.userid AND LENGTH(content)>0 WHERE level<# AND NOT (flags&#) ORDER BY created DESC LIMIT #",
* Return whether there are any blobs whose content has been stored as a file on disk
*/
functionqa_db_has_blobs_on_disk()
{
returnqa_db_read_one_value(qa_db_query_sub('SELECT blobid FROM ^blobs WHERE content IS NULL LIMIT 1'),true)!=null;
}
/**
* Return whether there are any blobs whose content has been stored in the database
*/
functionqa_db_has_blobs_in_db()
{
returnqa_db_read_one_value(qa_db_query_sub('SELECT blobid FROM ^blobs WHERE content IS NOT NULL LIMIT 1'),true)!=null;
}
/**
* Return the maximum position of the categories with $parentid
* @param $parentid
* @return mixed|null
*/
functionqa_db_category_last_pos($parentid)
{
returnqa_db_read_one_value(qa_db_query_sub(
'SELECT COALESCE(MAX(position), 0) FROM ^categories WHERE parentid<=>#',
$parentid
));
}
/**
* Return how many levels of subcategory there are below $categoryid
* @param $categoryid
* @return int
*/
functionqa_db_category_child_depth($categoryid)
{
// This is potentially a very slow query since it counts all the multi-generational offspring of a particular category
// But it's only used for admin purposes when moving a category around so I don't think it's worth making more efficient
// (Incidentally, this could be done by keeping a count for every category of how many generations of offspring it has.)
$result=qa_db_read_one_assoc(qa_db_query_sub(
'SELECT COUNT(child1.categoryid) AS count1, COUNT(child2.categoryid) AS count2, COUNT(child3.categoryid) AS count3 FROM ^categories AS child1 LEFT JOIN ^categories AS child2 ON child2.parentid=child1.categoryid LEFT JOIN ^categories AS child3 ON child3.parentid=child2.categoryid WHERE child1.parentid=#;',// requires QA_CATEGORY_DEPTH=4
"UPDATE ^categories AS x, (SELECT cat1.categoryid, CONCAT_WS('/', cat1.tags, cat2.tags, cat3.tags, cat4.tags) AS backpath FROM ^categories AS cat1 LEFT JOIN ^categories AS cat2 ON cat1.parentid=cat2.categoryid LEFT JOIN ^categories AS cat3 ON cat2.parentid=cat3.categoryid LEFT JOIN ^categories AS cat4 ON cat3.parentid=cat4.categoryid WHERE cat1.categoryid BETWEEN # AND #) AS a SET x.backpath=a.backpath WHERE x.categoryid=a.categoryid",
Move the entity identified by $idcolumn=$id into position $newposition (within optional $conditionsql) in $table in the database
*/
{
$andsql=isset($conditionsql)?(' AND '.$conditionsql):'';
qa_db_query_sub('LOCK TABLES ^'.$table.' WRITE');
$oldposition=qa_db_read_one_value(qa_db_query_sub('SELECT position FROM ^'.$table.' WHERE '.$idcolumn.'=#'.$andsql,$id));
if($newposition!=$oldposition){
$lastposition=qa_db_read_one_value(qa_db_query_sub('SELECT MAX(position) FROM ^'.$table.' WHERE TRUE'.$andsql));
$newposition=max(1,min($newposition,$lastposition));// constrain it to within range
qa_db_query_sub('UPDATE ^'.$table.' SET position=# WHERE '.$idcolumn.'=#'.$andsql,1+$lastposition,$id);
// move it temporarily off the top because we have a unique key on the position column
if($newposition<$oldposition)
qa_db_query_sub('UPDATE ^'.$table.' SET position=position+1 WHERE position BETWEEN # AND #'.$andsql.' ORDER BY position DESC',$newposition,$oldposition);
else
qa_db_query_sub('UPDATE ^'.$table.' SET position=position-1 WHERE position BETWEEN # AND #'.$andsql.' ORDER BY position',$oldposition,$newposition);
qa_db_query_sub('UPDATE ^'.$table.' SET position=# WHERE '.$idcolumn.'=#'.$andsql,$newposition,$id);
$andsql=isset($conditionsql)?(' AND '.$conditionsql):'';
qa_db_query_sub('LOCK TABLES ^'.$table.' WRITE');
$oldposition=qa_db_read_one_value(qa_db_query_sub('SELECT position FROM ^'.$table.' WHERE '.$idcolumn.'=#'.$andsql,$id));
if($newposition!=$oldposition){
$lastposition=qa_db_read_one_value(qa_db_query_sub('SELECT MAX(position) FROM ^'.$table.' WHERE TRUE'.$andsql));
$newposition=max(1,min($newposition,$lastposition));// constrain it to within range
// move it temporarily off the top because we have a unique key on the position column
qa_db_query_sub('UPDATE ^'.$table.' SET position=# WHERE '.$idcolumn.'=#'.$andsql,1+$lastposition,$id);
if($newposition<$oldposition)
qa_db_query_sub('UPDATE ^'.$table.' SET position=position+1 WHERE position BETWEEN # AND #'.$andsql.' ORDER BY position DESC',$newposition,$oldposition);
else
qa_db_query_sub('UPDATE ^'.$table.' SET position=position-1 WHERE position BETWEEN # AND #'.$andsql.' ORDER BY position',$oldposition,$newposition);
qa_db_query_sub('UPDATE ^'.$table.' SET position=# WHERE '.$idcolumn.'=#'.$andsql,$newposition,$id);
}
qa_db_query_sub('UNLOCK TABLES');
}
/**
* Delete the entity identified by $idcolumn=$id (and optional $conditionsql) in $table in the database
Return the information required to reindex up to $count posts starting from $startpostid in the database
*/
{
returnqa_db_read_all_assoc(qa_db_query_sub(
"SELECT ^posts.postid, ^posts.title, ^posts.content, ^posts.format, ^posts.tags, ^posts.categoryid, ^posts.type, IF (^posts.type='Q', ^posts.postid, IF(parent.type='Q', parent.postid, grandparent.postid)) AS questionid, ^posts.parentid FROM ^posts LEFT JOIN ^posts AS parent ON ^posts.parentid=parent.postid LEFT JOIN ^posts as grandparent ON parent.parentid=grandparent.postid WHERE ^posts.postid>=# AND ( (^posts.type='Q') OR (^posts.type='A' AND parent.type<=>'Q') OR (^posts.type='C' AND parent.type<=>'Q') OR (^posts.type='C' AND parent.type<=>'A' AND grandparent.type<=>'Q') ) ORDER BY postid LIMIT #",
"SELECT ^posts.postid, ^posts.title, ^posts.content, ^posts.format, ^posts.tags, ^posts.categoryid, ^posts.type, IF (^posts.type='Q', ^posts.postid, IF(parent.type='Q', parent.postid, grandparent.postid)) AS questionid, ^posts.parentid FROM ^posts LEFT JOIN ^posts AS parent ON ^posts.parentid=parent.postid LEFT JOIN ^posts as grandparent ON parent.parentid=grandparent.postid WHERE ^posts.postid>=# AND ( (^posts.type='Q') OR (^posts.type='A' AND parent.type<=>'Q') OR (^posts.type='C' AND parent.type<=>'Q') OR (^posts.type='C' AND parent.type<=>'A' AND grandparent.type<=>'Q') ) ORDER BY postid LIMIT #",
$startpostid,$count
),'postid');
}
/**
* Prepare posts $firstpostid to $lastpostid for reindexing in the database by removing their prior index entries
'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>=# AND ^words.wordid<=# GROUP BY wordid) AS a SET x.titlecount=a.titlecount WHERE x.wordid=a.wordid',
$firstwordid,$lastwordid
);
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>=# AND ^words.wordid<=# GROUP BY wordid) AS a SET x.contentcount=a.contentcount WHERE x.wordid=a.wordid',
$firstwordid,$lastwordid
);
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>=# AND ^words.wordid<=# GROUP BY wordid) AS a SET x.tagwordcount=a.tagwordcount WHERE x.wordid=a.wordid',
$firstwordid,$lastwordid
);
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>=# AND ^words.wordid<=# GROUP BY wordid) AS a SET x.tagcount=a.tagcount WHERE x.wordid=a.wordid',
$firstwordid,$lastwordid
);
qa_db_query_sub(
'DELETE FROM ^words WHERE wordid>=# AND wordid<=# AND titlecount=0 AND contentcount=0 AND tagwordcount=0 AND tagcount=0',
$firstwordid,$lastwordid
);
}
// For recalculating numbers of votes and answers for questions...
/**
* Return the ids of up to $count posts in the database starting from $startpostid
'UPDATE ^posts AS x, (SELECT ^posts.postid, COALESCE(SUM(GREATEST(0,^uservotes.vote)),0) AS upvotes, -COALESCE(SUM(LEAST(0,^uservotes.vote)),0) AS downvotes, COALESCE(SUM(IF(^uservotes.flag, 1, 0)),0) AS flagcount FROM ^posts LEFT JOIN ^uservotes ON ^uservotes.postid=^posts.postid WHERE ^posts.postid>=# AND ^posts.postid<=# GROUP BY postid) AS a SET x.upvotes=a.upvotes, x.downvotes=a.downvotes, x.netvotes=a.upvotes-a.downvotes, x.flagcount=a.flagcount WHERE x.postid=a.postid',
$firstpostid,$lastpostid
);
qa_db_hotness_update($firstpostid,$lastpostid);
}
/**
* Recalculate the cached answer counts for posts $firstpostid to $lastpostid in the database, along with the highest netvotes of any of their answers
'UPDATE ^posts AS x, (SELECT parents.postid, COUNT(children.postid) AS acount, COALESCE(GREATEST(MAX(children.netvotes), 0), 0) AS amaxvote FROM ^posts AS parents LEFT JOIN ^posts AS children ON parents.postid=children.parentid AND children.type=\'A\' WHERE parents.postid>=# AND parents.postid<=# GROUP BY postid) AS a SET x.acount=a.acount, x.amaxvote=a.amaxvote WHERE x.postid=a.postid',
$firstpostid,$lastpostid
);
qa_db_hotness_update($firstpostid,$lastpostid);
}
// For recalculating user points...
/**
* Return the ids of up to $count users in the database starting from $startuserid
* If using single sign-on integration, base this on user activity rather than the users table which we don't have
'SELECT wordid FROM ^words WHERE wordid>=# ORDER BY wordid LIMIT #',
$startwordid,$count
'SELECT userid FROM ((SELECT DISTINCT userid FROM ^posts WHERE userid>=# ORDER BY userid LIMIT #) UNION (SELECT DISTINCT userid FROM ^uservotes WHERE userid>=# ORDER BY userid LIMIT #)) x ORDER BY userid LIMIT #',
Recalculate the cached counts for words $firstwordid to $lastwordid in the database
*/
{
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>=# AND ^words.wordid<=# GROUP BY wordid) AS a SET x.titlecount=a.titlecount WHERE x.wordid=a.wordid',
$firstwordid,$lastwordid
);
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>=# AND ^words.wordid<=# GROUP BY wordid) AS a SET x.contentcount=a.contentcount WHERE x.wordid=a.wordid',
$firstwordid,$lastwordid
);
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>=# AND ^words.wordid<=# GROUP BY wordid) AS a SET x.tagwordcount=a.tagwordcount WHERE x.wordid=a.wordid',
$firstwordid,$lastwordid
);
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>=# AND ^words.wordid<=# GROUP BY wordid) AS a SET x.tagcount=a.tagcount WHERE x.wordid=a.wordid',
$firstwordid,$lastwordid
);
qa_db_query_sub(
'DELETE FROM ^words WHERE wordid>=# AND wordid<=# AND titlecount=0 AND contentcount=0 AND tagwordcount=0 AND tagcount=0',
$firstwordid,$lastwordid
);
}
// For recalculating numbers of votes and answers for questions...
Recalculate the cached vote counts for posts $firstpostid to $lastpostid in the database
*/
{
qa_db_query_sub(
'UPDATE ^posts AS x, (SELECT ^posts.postid, COALESCE(SUM(GREATEST(0,^uservotes.vote)),0) AS upvotes, -COALESCE(SUM(LEAST(0,^uservotes.vote)),0) AS downvotes, COALESCE(SUM(IF(^uservotes.flag, 1, 0)),0) AS flagcount FROM ^posts LEFT JOIN ^uservotes ON ^uservotes.postid=^posts.postid WHERE ^posts.postid>=# AND ^posts.postid<=# GROUP BY postid) AS a SET x.upvotes=a.upvotes, x.downvotes=a.downvotes, x.netvotes=a.upvotes-a.downvotes, x.flagcount=a.flagcount WHERE x.postid=a.postid',
'UPDATE ^posts AS x, (SELECT parents.postid, COUNT(children.postid) AS acount, COALESCE(GREATEST(MAX(children.netvotes), 0), 0) AS amaxvote FROM ^posts AS parents LEFT JOIN ^posts AS children ON parents.postid=children.parentid AND children.type=\'A\' WHERE parents.postid>=# AND parents.postid<=# GROUP BY postid) AS a SET x.acount=a.acount, x.amaxvote=a.amaxvote WHERE x.postid=a.postid',
Return the ids of up to $count users in the database starting from $startuserid
If using single sign-on integration, base this on user activity rather than the users table which we don't have
*/
{
if(QA_FINAL_EXTERNAL_USERS)
returnqa_db_read_all_values(qa_db_query_sub(
'SELECT userid FROM ((SELECT DISTINCT userid FROM ^posts WHERE userid>=# ORDER BY userid LIMIT #) UNION (SELECT DISTINCT userid FROM ^uservotes WHERE userid>=# ORDER BY userid LIMIT #)) x ORDER BY userid LIMIT #',
$startuserid,$count,$startuserid,$count,$count
));
else
returnqa_db_read_all_values(qa_db_query_sub(
'SELECT DISTINCT userid FROM ^users WHERE userid>=# ORDER BY userid LIMIT #',
'UPDATE ^userpoints SET '.$zeropoints.' WHERE userid>=# AND userid<=#',// zero out the rest
$firstuserid,$lastuserid
);
if(QA_FINAL_EXTERNAL_USERS)
qa_db_query_sub(
'DELETE FROM ^userpoints WHERE userid>=# AND userid<=# AND bonus=0',// delete those with no bonus
$firstuserid,$lastuserid
'INSERT IGNORE INTO ^userpoints (userid) SELECT DISTINCT userid FROM ^posts WHERE userid>=# AND userid<=# UNION SELECT DISTINCT userid FROM ^uservotes WHERE userid>=# AND userid<=#',
'UPDATE ^userpoints SET '.$zeropoints.' WHERE userid>=# AND userid<=#',// zero out the rest
'INSERT IGNORE INTO ^userpoints (userid) SELECT DISTINCT userid FROM ^users WHERE userid>=# AND userid<=#',
$firstuserid,$lastuserid
);
if(QA_FINAL_EXTERNAL_USERS)
qa_db_query_sub(
'INSERT IGNORE INTO ^userpoints (userid) SELECT DISTINCT userid FROM ^posts WHERE userid>=# AND userid<=# UNION SELECT DISTINCT userid FROM ^uservotes WHERE userid>=# AND userid<=#',
$firstuserid,$lastuserid,$firstuserid,$lastuserid
);
else
qa_db_query_sub(
'INSERT IGNORE INTO ^userpoints (userid) SELECT DISTINCT userid FROM ^users WHERE userid>=# AND userid<=#',
Recalculate the (exact) categoryid for the posts (including queued/hidden) between $firstpostid and $lastpostid
in the database, where the category of comments and answers is set by the category of the antecedent question
*/
{
qa_db_query_sub(
"UPDATE ^posts AS x, (SELECT ^posts.postid, IF(LEFT(parent.type, 1)='Q', parent.categoryid, grandparent.categoryid) AS categoryid FROM ^posts LEFT JOIN ^posts AS parent ON ^posts.parentid=parent.postid LEFT JOIN ^posts AS grandparent ON parent.parentid=grandparent.postid WHERE ^posts.postid BETWEEN # AND # AND LEFT(^posts.type, 1)!='Q') AS a SET x.categoryid=a.categoryid WHERE x.postid=a.postid",
Return the ids of up to $limit posts of $type that can be deleted from the database (i.e. have no dependents)
*/
{
$limitsql=isset($limit)?(' ORDER BY ^posts.postid LIMIT '.(int)$limit):'';
returnqa_db_read_all_values(qa_db_query_sub(
"SELECT ^posts.postid FROM ^posts LEFT JOIN ^posts AS child ON child.parentid=^posts.postid LEFT JOIN ^posts AS dupe ON dupe.closedbyid=^posts.postid WHERE ^posts.type=$ AND ^posts.postid>=# AND child.postid IS NULL AND dupe.postid IS NULL".$limitsql,
$type.'_HIDDEN',$startpostid
));
}
// For moving blobs between database and disk...
functionqa_db_count_blobs_in_db()
/*
Return the number of blobs whose content is stored in the database, rather than on disk
*/
{
returnqa_db_read_one_value(qa_db_query_sub('SELECT COUNT(*) FROM ^blobs WHERE content IS NOT NULL'));
}
functionqa_db_get_next_blob_in_db($startblobid)
/*
Return the id, content and format of the first blob whose content is stored in the database starting from $startblobid
*/
{
returnqa_db_read_one_assoc(qa_db_query_sub(
'SELECT blobid, content, format FROM ^blobs WHERE blobid>=# AND content IS NOT NULL LIMIT 1',
$startblobid
),true);
}
functionqa_db_count_blobs_on_disk()
/*
Return the number of blobs whose content is stored on disk, rather than in the database
*/
{
returnqa_db_read_one_value(qa_db_query_sub('SELECT COUNT(*) FROM ^blobs WHERE content IS NULL'));
}
functionqa_db_get_next_blob_on_disk($startblobid)
/*
Return the id and format of the first blob whose content is stored on disk starting from $startblobid
*/
{
returnqa_db_read_one_assoc(qa_db_query_sub(
'SELECT blobid, format FROM ^blobs WHERE blobid>=# AND content IS NULL LIMIT 1',
$startblobid
),true);
}
/*
Omit PHP closing tag to help avoid accidental output
*/
qa_db_query_sub(
'UPDATE ^userpoints SET points='.$updatepoints.'+bonus WHERE userid>=# AND userid<=#',
$firstuserid,$lastuserid
);
}
/**
* Remove any rows in the userpoints table where userid is greater than $lastuserid
* @param $lastuserid
*/
functionqa_db_truncate_userpoints($lastuserid)
{
qa_db_query_sub(
'DELETE FROM ^userpoints WHERE userid>#',
$lastuserid
);
}
// For refilling event streams...
/**
* Return the ids of up to $count questions in the database starting from $startpostid
"UPDATE ^posts AS x, (SELECT ^posts.postid, IF(LEFT(parent.type, 1)='Q', parent.categoryid, grandparent.categoryid) AS categoryid FROM ^posts LEFT JOIN ^posts AS parent ON ^posts.parentid=parent.postid LEFT JOIN ^posts AS grandparent ON parent.parentid=grandparent.postid WHERE ^posts.postid BETWEEN # AND # AND LEFT(^posts.type, 1)!='Q') AS a SET x.categoryid=a.categoryid WHERE x.postid=a.postid",
$firstpostid,$lastpostid
);
}
/**
* Return the ids of up to $count categories in the database starting from $startcategoryid
$limitsql=isset($limit)?(' ORDER BY ^posts.postid LIMIT '.(int)$limit):'';
returnqa_db_read_all_values(qa_db_query_sub(
"SELECT ^posts.postid FROM ^posts LEFT JOIN ^posts AS child ON child.parentid=^posts.postid LEFT JOIN ^posts AS dupe ON dupe.closedbyid=^posts.postid WHERE ^posts.type=$ AND ^posts.postid>=# AND child.postid IS NULL AND dupe.postid IS NULL".$limitsql,
$type.'_HIDDEN',$startpostid
));
}
// For moving blobs between database and disk...
/**
* Return the number of blobs whose content is stored in the database, rather than on disk
*/
functionqa_db_count_blobs_in_db()
{
returnqa_db_read_one_value(qa_db_query_sub('SELECT COUNT(*) FROM ^blobs WHERE content IS NOT NULL'));
}
/**
* Return the id, content and format of the first blob whose content is stored in the database starting from $startblobid
* @param $startblobid
* @return array|null
*/
functionqa_db_get_next_blob_in_db($startblobid)
{
returnqa_db_read_one_assoc(qa_db_query_sub(
'SELECT blobid, content, format FROM ^blobs WHERE blobid>=# AND content IS NOT NULL LIMIT 1',
$startblobid
),true);
}
/**
* Return the number of blobs whose content is stored on disk, rather than in the database
*/
functionqa_db_count_blobs_on_disk()
{
returnqa_db_read_one_value(qa_db_query_sub('SELECT COUNT(*) FROM ^blobs WHERE content IS NULL'));
}
/**
* Return the id and format of the first blob whose content is stored on disk starting from $startblobid
* @param $startblobid
* @return array|null
*/
functionqa_db_get_next_blob_on_disk($startblobid)
{
returnqa_db_read_one_assoc(qa_db_query_sub(
'SELECT blobid, format FROM ^blobs WHERE blobid>=# AND content IS NULL LIMIT 1',