You can subscribe to this list here.
| 2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(34) |
Aug
(215) |
Sep
(180) |
Oct
(135) |
Nov
(105) |
Dec
(81) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2002 |
Jan
(76) |
Feb
(22) |
Mar
(154) |
Apr
(149) |
May
(128) |
Jun
(94) |
Jul
(14) |
Aug
(24) |
Sep
(77) |
Oct
(52) |
Nov
(22) |
Dec
(6) |
| 2003 |
Jan
(4) |
Feb
(10) |
Mar
(6) |
Apr
(29) |
May
(10) |
Jun
(37) |
Jul
(39) |
Aug
(13) |
Sep
(23) |
Oct
(3) |
Nov
(7) |
Dec
(2) |
| 2004 |
Jan
|
Feb
(10) |
Mar
(4) |
Apr
|
May
(35) |
Jun
(4) |
Jul
(17) |
Aug
(6) |
Sep
(14) |
Oct
(18) |
Nov
(2) |
Dec
(14) |
| 2005 |
Jan
(9) |
Feb
(30) |
Mar
(6) |
Apr
|
May
(38) |
Jun
(23) |
Jul
(21) |
Aug
(76) |
Sep
(50) |
Oct
(51) |
Nov
(13) |
Dec
|
|
From: Ulf E. <ulf...@us...> - 2005-05-30 19:32:36
|
Update of /cvsroot/phpbt/phpbt/inc/db In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15033/inc/db Added Files: mysqli.php Log Message: Added MySQL-i support. --- NEW FILE: mysqli.php --- <?php $QUERY = array( 'admin-list-groups' => 'select ag.group_id, group_name, locked, '. 'count(ug.group_id) as count, assignable '. 'from '.TBL_AUTH_GROUP.' ag '. 'left join '.TBL_USER_GROUP.' ug using (group_id) '. 'left join '.TBL_AUTH_USER.' using (user_id) '. 'group by ag.group_id, group_name, locked, assignable '. 'order by %s %s', 'admin-list-oses' => 'select s.os_id, os_name, regex, sort_order, '. 'count(bug_id) as bug_count '. 'from '.TBL_OS.' s '. 'left join '.TBL_BUG.' using (os_id) '. 'group by s.os_id, os_name, regex, sort_order '. 'order by %s %s', 'admin-show-version' => 'select v.*, p.project_name as project_name '. 'from '.TBL_VERSION.' v left join '.TBL_PROJECT.' p using(project_id) '. 'where version_id = \'%s\'', 'admin-show-component' => 'select c.*, p.project_name as project_name '. 'from '.TBL_COMPONENT.' c left join '.TBL_PROJECT.' p using (project_id) '. 'where component_id = \'%s\'', 'admin-list-resolutions' => 'select s.resolution_id, resolution_name, '. 'resolution_desc, sort_order, count(bug_id) as bug_count '. 'from '.TBL_RESOLUTION. ' s left join '.TBL_BUG.' using (resolution_id) '. 'group by s.resolution_id, resolution_name, resolution_desc, sort_order '. 'order by %s %s', 'admin-list-severities' => 'select s.severity_id, severity_name, '. 'severity_desc, severity_color, sort_order, count(bug_id) as bug_count '. 'from '.TBL_SEVERITY. ' s left join '.TBL_BUG.' using (severity_id) '. 'group by s.severity_id, severity_name, severity_desc, severity_color, '. 'sort_order '. 'order by %s %s', 'admin-list-databases' => 'select d.database_id, database_name, '. 'sort_order, count(bug_id) as bug_count '. 'from '.TBL_DATABASE. ' d left join '.TBL_BUG.' using (database_id) '. 'group by d.database_id, database_name, sort_order '. 'order by %s %s', 'admin-list-sites' => 'select s.site_id, site_name, sort_order, '. 'count(bug_id) as bug_count from '.TBL_SITE. ' s left join '. TBL_BUG.' using (site_id) group by s.site_id, site_name, sort_order '. 'order by %s %s', 'admin-list-statuses' => 'select s.status_id, status_name, status_desc, '. 'sort_order, bug_open, count(bug_id) as bug_count '. 'from '.TBL_STATUS.' s left join '. TBL_BUG.' using (status_id) '. 'group by s.status_id, status_name, status_desc, sort_order '. 'order by %s %s', 'admin-user-groups' => 'select ug.group_id '. 'from '.TBL_USER_GROUP.' ug left join '.TBL_AUTH_GROUP.' g using (group_id) '. 'where user_id = %s and group_name <> \'User\'', 'bug-history' => 'select bh.*, login '. 'from '.TBL_BUG_HISTORY.' bh '. 'left join '. TBL_AUTH_USER.' on bh.created_by = user_id '. 'where bug_id = %s order by bh.created_date', 'bug-cc-list' => 'select email '. 'from '.TBL_BUG_CC.' left join '. TBL_AUTH_USER.' u using(user_id), '. TBL_USER_PREF.' p '. 'where bug_id = %s and u.user_id = p.user_id and email_notices = 1', 'bug-printable' => 'select b.*, reporter.login as reporter, '. 'owner.login as owner, project_name, component_name, version_name, '. 'severity_name, os_name, status_name, resolution_name '. 'from '.TBL_BUG.' b '. 'left join '.TBL_AUTH_USER.' owner on b.assigned_to = owner.user_id '. 'left join '.TBL_AUTH_USER.' reporter on b.created_by = reporter.user_id '. 'left join '.TBL_RESOLUTION.' r on b.resolution_id = r.resolution_id, '. TBL_SEVERITY.' sv, '.TBL_STATUS.' st, '.TBL_OS.' os, '. TBL_VERSION.' v, '. TBL_COMPONENT.' c, '.TBL_PROJECT.' p '. 'where bug_id = %s and b.project_id not in (%s) '. 'and b.severity_id = sv.severity_id '. 'and b.os_id = os.os_id and b.version_id = v.version_id '. 'and b.component_id = c.component_id and b.project_id = p.project_id '. 'and b.status_id = st.status_id', 'bug-prev-next' => 'select bug_id, reporter.login as reporter, '. 'owner.login as owner '. 'from '.TBL_BUG.' b '. 'left join '.TBL_AUTH_USER.' owner on b.assigned_to = owner.user_id '. 'left join '.TBL_AUTH_USER.' reporter on b.created_by = reporter.user_id '. 'left join '.TBL_AUTH_USER.' lastmodifier on b.last_modified_by = lastmodifier.user_id '. 'left join '.TBL_RESOLUTION.' resolution on b.resolution_id = resolution.resolution_id '. 'left join '.TBL_DATABASE.' on b.database_id = '.TBL_DATABASE.'.database_id '. 'left join '.TBL_VERSION.' version2 on b.to_be_closed_in_version_id = version2.version_id '. 'left join '.TBL_VERSION.' version3 on b.closed_in_version_id = version3.version_id, '. TBL_SEVERITY.' severity, '.TBL_STATUS.' status, '.TBL_OS.' os, '. TBL_VERSION.' version, '.TBL_COMPONENT.' component, '. TBL_PROJECT.' project, '.TBL_SITE.' site '. 'where b.severity_id = severity.severity_id '. 'and b.status_id = status.status_id and b.os_id = os.os_id '. 'and b.version_id = version.version_id '. 'and b.component_id = component.component_id '. 'and b.project_id = project.project_id and %s '. 'and b.site_id = site.site_id '. 'and bug_id <> %s '. 'order by %s %s, bug_id asc', 'bug-show-bug' => 'select b.*, reporter.login as reporter, '. 'owner.login as owner, status_name, resolution_name '. 'from '.TBL_BUG.' b '. 'left join '.TBL_AUTH_USER.' owner on b.assigned_to = owner.user_id '. 'left join '.TBL_AUTH_USER.' reporter on b.created_by = reporter.user_id '. 'left join '.TBL_RESOLUTION.' r on b.resolution_id = r.resolution_id, '. TBL_SEVERITY.' sv, '.TBL_STATUS.' st, '.TBL_SITE.' site '. 'where bug_id = %s and b.project_id not in (%s) '. 'and b.site_id = site.site_id '. 'and b.severity_id = sv.severity_id and b.status_id = st.status_id', 'functions-bug-cc' => 'select b.user_id, login '. 'from '.TBL_BUG_CC.' b left join '. TBL_AUTH_USER.' using(user_id) '. 'where bug_id = %s', 'functions-project-js' => 'select p.project_id, project_name '. 'from '.TBL_PROJECT. ' p '. 'left join '.TBL_PROJECT_GROUP.' pg using(project_id) '. 'where active = 1 and (pg.project_id is null or pg.group_id in (%s)) '. 'group by p.project_id, p.project_name '. 'order by project_name', 'include-template-owner' => "SELECT sum(CASE WHEN s.status_id ". "in (".OPEN_BUG_STATUSES.") THEN 1 ELSE 0 END ) , ". "sum(CASE WHEN s.status_id ". "not in (".OPEN_BUG_STATUSES.") THEN 1 ELSE 0 END ) ". "from ".TBL_BUG." b left join ".TBL_STATUS." s using(status_id) ". "where assigned_to = %s", 'include-template-reporter' => "SELECT sum(CASE WHEN s.status_id in (".OPEN_BUG_STATUSES.") THEN 1 ELSE 0 END ) , ". "sum(CASE WHEN s.status_id not in (".OPEN_BUG_STATUSES.") THEN 1 ELSE 0 END ) ". "from ".TBL_BUG." b left join ".TBL_STATUS." s using(status_id) ". "where created_by = %s", 'index-projsummary-1' => 'select project_name as "Project", '. 'sum(case when resolution_id = 0 then 1 else 0 end) as "Open"', 'index-projsummary-2' => "select resolution_name, ", 'index-projsummary-3' => "', sum(case when resolution_id = '", 'index-projsummary-4' => "' then 1 else 0 end) as \"'", 'index-projsummary-5' => " from ".TBL_RESOLUTION, 'index-projsummary-6' => '%s, count(bug_id) as "Total" '. 'from '.TBL_BUG. ' b left join '.TBL_PROJECT.' p using (project_id) '. 'where b.project_id not in (%s) group by b.project_id, project_name '. 'order by project_name', 'query-list-bugs-count' => 'select count(*) '. 'from '.TBL_BUG.' b '. 'left join '.TBL_AUTH_USER.' owner on b.assigned_to = owner.user_id '. 'left join '.TBL_AUTH_USER.' reporter on b.created_by = reporter.user_id ', 'query-list-bugs-count-join' => 'where ', 'query-list-bugs' => 'select %s '. 'from '.TBL_BUG.' b '. 'left join '.TBL_AUTH_USER.' owner on b.assigned_to = owner.user_id '. 'left join '.TBL_AUTH_USER.' reporter on b.created_by = reporter.user_id '. 'left join '.TBL_AUTH_USER.' lastmodifier on b.last_modified_by = lastmodifier.user_id '. 'left join '.TBL_RESOLUTION.' resolution on b.resolution_id = resolution.resolution_id '. 'left join '.TBL_DATABASE.' on b.database_id = '.TBL_DATABASE.'.database_id '. 'left join '.TBL_VERSION.' version2 on b.to_be_closed_in_version_id = version2.version_id '. 'left join '.TBL_VERSION.' version3 on b.closed_in_version_id = version3.version_id, '. TBL_SEVERITY.' severity, '.TBL_STATUS.' status, '.TBL_OS.' os, '.TBL_SITE.' site, '. TBL_VERSION.' version, '.TBL_COMPONENT.' component, '.TBL_PROJECT.' project '. 'where b.severity_id = severity.severity_id '. 'and b.status_id = status.status_id and b.os_id = os.os_id '. 'and b.site_id = site.site_id and b.version_id = version.version_id '. 'and b.component_id = component.component_id '. 'and b.project_id = project.project_id %s '. 'order by %s %s, bug_id asc', 'report-resbyeng-1' => 'select email as "Assigned To", '. 'sum(case when resolution_id = 0 then 1 else 0 end) as "Open"', 'report-resbyeng-2' => "select resolution_name, ", 'report-resbyeng-3' => "', sum(case when resolution_id = '", 'report-resbyeng-4' => "' then 1 else 0 end) as \"'", 'report-resbyeng-5' => " from ".TBL_RESOLUTION, 'report-resbyeng-6' => '%s, count(bug_id) as "Total" '. 'from '.TBL_BUG. ' b '. 'left join '.TBL_AUTH_USER.' u on assigned_to = user_id %s '. 'group by assigned_to, u.email', 'join-where' => 'where', 'admin-list-components' => 'select c.component_id, component_name, '. 'c.created_date, active, count(bug_id) as bug_count '. 'from '.TBL_COMPONENT.' c left join '.TBL_BUG.' b using(component_id) '. 'where c.project_id = %s '. 'group by c.component_id, c.component_name, c.created_date, c.active', 'admin-list-versions' => 'select v.version_id, version_name, '. 'v.created_date, active, count(bug_id) as bug_count '. 'from '.TBL_VERSION.' v left join '.TBL_BUG.' b using(version_id) '. 'where v.project_id = %s '. 'group by v.version_id, v.version_name, v.created_date, v.active', ); ?> |
|
From: Ulf E. <ulf...@us...> - 2005-05-30 19:32:36
|
Update of /cvsroot/phpbt/phpbt In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15033 Modified Files: install.php upgrade.php Log Message: Added MySQL-i support. Index: install.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/install.php,v retrieving revision 1.42 retrieving revision 1.43 diff -u -r1.42 -r1.43 --- install.php 24 May 2005 20:53:33 -0000 1.42 +++ install.php 30 May 2005 19:32:26 -0000 1.43 @@ -57,7 +57,8 @@ 'template_path' => 'templates/default')); $db_types = array( - 'mysql' => 'MySQL', + 'mysql' => 'MySQL < 4.1', + 'mysqli' => 'MySQL >= 4.1', 'oci8' => 'Oracle 8.1.x', 'pgsql' => 'PostgreSQL'); @@ -272,4 +273,4 @@ show_front(); } // Any whitespace below the end tag will disrupt config.php -?> +?> \ No newline at end of file Index: upgrade.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/upgrade.php,v retrieving revision 1.37 retrieving revision 1.38 diff -u -r1.37 -r1.38 --- upgrade.php 25 Oct 2004 12:06:58 -0000 1.37 +++ upgrade.php 30 May 2005 19:32:27 -0000 1.38 @@ -54,6 +54,7 @@ $db->query("ALTER TABLE ".TBL_STATUS." alter bug_open set NOT NULL"); } break; + case 'mysqli' : case 'mysql' : $db->query("create table if not exists ".TBL_PROJECT_PERM." ( project_id int(11) NOT NULL default '0', user_id int(11) NOT NULL default '0' )"); if ($thisvers < 2) { |
|
From: Benjamin C. <bc...@us...> - 2005-05-28 18:12:00
|
Update of /cvsroot/phpbt/phpbt In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10524 Modified Files: attachment.php bug.php Log Message: Added some query quoting Index: attachment.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/attachment.php,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- attachment.php 25 Oct 2004 12:39:56 -0000 1.23 +++ attachment.php 28 May 2005 18:11:52 -0000 1.24 @@ -28,7 +28,7 @@ global $db; if (list($filename, $mimetype) = grab_attachment($attachid)) { - $db->query("delete from ".TBL_ATTACHMENT." where attachment_id = $attachid"); + $db->query("delete from ".TBL_ATTACHMENT." where attachment_id = ".$db->quote($attachid)); unlink($filename); header("Location: {$_SERVER['HTTP_REFERER']}"); } @@ -86,7 +86,7 @@ } // Check for a previously-uploaded attachment with the same name, bug, and project - $rs = $db->query("select a.bug_id, project_id from ".TBL_ATTACHMENT." a, ".TBL_BUG." b where file_name = '{$_FILES['attachment']['name']}' and a.bug_id = b.bug_id"); + $rs = $db->query("select a.bug_id, project_id from ".TBL_ATTACHMENT." a, ".TBL_BUG." b where file_name = ".$db->quote($_FILES['attachment']['name'])." and a.bug_id = b.bug_id"); while ($rs->fetchInto($ainfo)) { if ($bugid == $ainfo['bug_id'] && $projectid == $ainfo['project_id']) { show_attachment_form($bugid, translate("That attachment already exists for this bug")); @@ -119,7 +119,7 @@ } @chmod("$filepath/$projectid/$filename", 0766); - $db->query("insert into ".TBL_ATTACHMENT." (attachment_id, bug_id, file_name, description, file_size, mime_type, created_by, created_date) values (".join(', ', array($db->nextId(TBL_ATTACHMENT), $bugid, $db->quote($_FILES['attachment']['name']), $db->quote(stripslashes($description)), $_FILES['attachment']['size'], $db->quote($_FILES['attachment']['type']), $u, $now)).")"); + $db->query("insert into ".TBL_ATTACHMENT." (attachment_id, bug_id, file_name, description, file_size, mime_type, created_by, created_date) values (".join(', ', array($db->nextId(TBL_ATTACHMENT), $db->quote($bugid), $db->quote($_FILES['attachment']['name']), $db->quote(stripslashes($description)), $db->quote($_FILES['attachment']['size']), $db->quote($_FILES['attachment']['type']), $u, $now)).")"); if ($_POST['use_js']) { $t->render('admin/edit-submit.html'); Index: bug.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/bug.php,v retrieving revision 1.137 retrieving revision 1.138 diff -u -r1.137 -r1.138 --- bug.php 22 Jan 2005 16:03:48 -0000 1.137 +++ bug.php 28 May 2005 18:11:52 -0000 1.138 @@ -39,7 +39,7 @@ global $u, $db, $now; // Check to see if the user already voted on this bug - if ($db->getOne("select count(*) from ".TBL_BUG_VOTE." where bug_id = $bug_id and user_id = $u")) { + if ($db->getOne("select count(*) from ".TBL_BUG_VOTE." where bug_id = ".$db->quote($bug_id)." and user_id = $u")) { show_bug($bug_id, array('vote' => translate("You have already voted for this bug"))); return; } @@ -51,17 +51,17 @@ } // Record the vote - $db->query("insert into ".TBL_BUG_VOTE." (user_id, bug_id, created_date) values ($u, $bug_id, $now)"); + $db->query("insert into ".TBL_BUG_VOTE." (user_id, bug_id, created_date) values ($u, ".$db->quote($bug_id).", $now)"); // Proceed only if promoting by votes is turned on if (PROMOTE_VOTES) { // Has this bug already been promoted? - $bug_is_new = $db->getOne("select count(*) from ".TBL_BUG." b, ".TBL_STATUS." s where bug_id = $bug_id and b.status_id = s.status_id and status_name = 'New'"); + $bug_is_new = $db->getOne("select count(*) from ".TBL_BUG." b, ".TBL_STATUS." s where bug_id = ".$db->quote($bug_id)." and b.status_id = s.status_id and status_name = 'New'"); // If a number of votes are required to promote a bug, check for promotion - if (!$bug_is_new and $db->getOne("select count(*) from ".TBL_BUG_VOTE." where bug_id = $bug_id") == PROMOTE_VOTES) { + if (!$bug_is_new and $db->getOne("select count(*) from ".TBL_BUG_VOTE." where bug_id = ".$db->quote($bug_id)) == PROMOTE_VOTES) { $status_id = BUG_PROMOTED; - $buginfo = $db->getOne("select * from ".TBL_BUG." where bug_id = $bug_id"); + $buginfo = $db->getOne("select * from ".TBL_BUG." where bug_id = ".$db->quote($bug_id)); $changedfields = array('status_id' => $status_id); do_changedfields($u, $buginfo, $changedfields); } @@ -106,7 +106,7 @@ return; } - $t->assign('history', $db->getAll(sprintf($QUERY['bug-history'], $bugid))); + $t->assign('history', $db->getAll(sprintf($QUERY['bug-history'], $db->quote($bugid)))); $t->render('bughistory.html', translate("Bug History")); } |
|
From: Benjamin C. <bc...@us...> - 2005-05-28 18:09:47
|
Update of /cvsroot/phpbt/phpbt/inc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8913/inc Modified Files: functions.php Log Message: Fixed a bug in the bug deletion function. Added logging of database errors Index: functions.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/inc/functions.php,v retrieving revision 1.51 retrieving revision 1.52 diff -u -r1.51 -r1.52 --- functions.php 28 May 2005 17:53:37 -0000 1.51 +++ functions.php 28 May 2005 18:09:39 -0000 1.52 @@ -525,6 +525,7 @@ } else { show_text(htmlentities($obj->message).'<br>'.htmlentities($obj->userinfo)); } + error_log($obj->message." -- ".htmlentities($obj->userinfo)); exit; } @@ -669,7 +670,7 @@ " from ".TBL_ATTACHMENT." a, ".TBL_BUG." b". " where a.bug_id = b.bug_id and b.bug_id = ".$db->quote($bug_id)); foreach ($attary as $att) { - unlink(join('/', array(ATTACHMENT_PATH, + @unlink(join('/', array(ATTACHMENT_PATH, $att['project_id'], "$bug_id-{$att['file_name']}"))); } $db->query("delete from ".TBL_ATTACHMENT." where bug_id = ".$db->quote($bug_id)); @@ -685,13 +686,16 @@ " where bug_id = ".$db->quote($bug_id)." or depends_on = ".$db->quote($bug_id)); // Groups - $db->query("delete from ".TBL_GROUP." where bug_id = ".$db->quote($bug_id)); + $db->query("delete from ".TBL_BUG_GROUP." where bug_id = ".$db->quote($bug_id)); // Histories $db->query("delete from ".TBL_BUG_HISTORY." where bug_id = ".$db->quote($bug_id)); // Votes $db->query("delete from ".TBL_BUG_VOTE." where bug_id = ".$db->quote($bug_id)); + + // And the bug itself + $db->query("delete from ".TBL_BUG." where bug_id = ".$db->quote($bug_id)); } ?> |
|
From: Benjamin C. <bc...@us...> - 2005-05-28 17:53:48
|
Update of /cvsroot/phpbt/phpbt/inc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31733/inc Modified Files: functions.php Log Message: Added a bunch of db quoting of parameters. Added a bug deletion function, by popular demand Index: functions.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/inc/functions.php,v retrieving revision 1.50 retrieving revision 1.51 diff -u -r1.50 -r1.51 --- functions.php 25 May 2005 18:07:43 -0000 1.50 +++ functions.php 28 May 2005 17:53:37 -0000 1.51 @@ -88,14 +88,14 @@ 'resolution' => $querystart.$querymid, 'project' => $perm->have_perm('Admin') ? $querystart." where ". - ($selected ? "(active > 0 or project_id in ($selected))" : 'active > 0'). + ($selected ? "(active > 0 or project_id in (".$db->quote($selected)."))" : 'active > 0'). " order by {$box}_name" - : $querystart." where project_id not in ($restricted_projects)". + : $querystart." where project_id not in (".$db->quote($restricted_projects).")". " and ". - ($selected ? " (active > 0 or project_id in ($selected))" : 'active > 0'). + ($selected ? " (active > 0 or project_id in (".$db->quote($selected)."))" : 'active > 0'). " order by {$box}_name", - 'component' => $querystart." where project_id = $project and active = 1 order by {$box}_name", - 'version' => $querystart." where project_id = $project and active = 1 order by {$box}_id desc", + 'component' => $querystart." where project_id = ".$db->quote($project)." and active = 1 order by {$box}_name", + 'version' => $querystart." where project_id = ".$db->quote($project)." and active = 1 order by {$box}_id desc", 'database' => $querystart.$querymid ); } @@ -194,7 +194,7 @@ } break; case 'bug_cc': - $rs = $db->query(sprintf($QUERY['functions-bug-cc'], $selected)); + $rs = $db->query(sprintf($QUERY['functions-bug-cc'], $db->quote($selected))); while (list($uid, $user) = $rs->fetchRow(DB_FETCHMODE_ORDERED)) { $text .= "<option value=\"$uid\">".maskemail($user).'</option>'; } @@ -307,7 +307,7 @@ switch($var) { case 'assigned_to' : - return maskemail($db->getOne("select login from ".TBL_AUTH_USER." where user_id = $val")); + return maskemail($db->getOne("select login from ".TBL_AUTH_USER." where user_id = ".$db->quote($val))); break; } } @@ -326,7 +326,7 @@ $page = 0; } else { if ($perm->check_auth('group', 'Users')) - $selrange = $db->getOne('select def_results from '.TBL_USER_PREF.' where user_id = '.$u); + $selrange = $db->getOne('select def_results from '.TBL_USER_PREF.' where user_id = '.$db->quote($u)); $llimit = ($page-1)*$selrange; } if ($nr) $npages = ceil($nr/$selrange); @@ -452,7 +452,7 @@ $rs = $db->query("select project_id, project_name from ".TBL_PROJECT." where active = 1 order by project_name"); } else { $rs = $db->query(sprintf($QUERY['functions-project-js'], - @join(',', $_SESSION['group_ids']))); + $db->quote(@join(',', $_SESSION['group_ids'])))); } while (list($pid, $pname) = $rs->fetchRow(DB_FETCHMODE_ORDERED)) { $pname = addslashes($pname); @@ -462,7 +462,7 @@ $js2 = "closedversions['$pname'] = new Array(". ((!isset($no_all) or !$no_all) ? "new Array('','All')," : "new Array(0, 'Choose One'),"); - $rs2 = $db->query("select version_name, version_id from ".TBL_VERSION." where project_id = $pid and active = 1"); + $rs2 = $db->query("select version_name, version_id from ".TBL_VERSION." where project_id = ".$db->quote($pid)." and active = 1"); while (list($version,$vid) = $rs2->fetchRow(DB_FETCHMODE_ORDERED)) { $version = addslashes($version); $js .= "new Array($vid,'$version'),"; @@ -477,7 +477,7 @@ // Component array $js .= "components['$pname'] = new Array("; $js .= (!isset($no_all) || !$no_all) ? "new Array('','All')," : ''; - $rs2 = $db->query("select component_name, component_id from ".TBL_COMPONENT." where project_id = $pid and active = 1"); + $rs2 = $db->query("select component_name, component_id from ".TBL_COMPONENT." where project_id = ".$db->quote($pid)." and active = 1"); while (list($comp,$cid) = $rs2->fetchRow(DB_FETCHMODE_ORDERED)) { $comp = addslashes($comp); $js .= "new Array($cid,'$comp'),"; @@ -644,7 +644,7 @@ function is_closed($status_id) { global $db; - if ($db->getOne('SELECT status_id FROM '.TBL_STATUS.' WHERE bug_open = 0 AND status_id = '.$status_id)) { + if ($db->getOne('SELECT status_id FROM '.TBL_STATUS.' WHERE bug_open = 0 AND status_id = '.$db->quote($status_id))) { return true; } else { return false; @@ -660,4 +660,38 @@ return $id; } +// Delete a bug and all associated records from the database +function delete_bug($bug_id) { + global $db; + + // Attachments + $attary = $db->getAll("select file_name, project_id". + " from ".TBL_ATTACHMENT." a, ".TBL_BUG." b". + " where a.bug_id = b.bug_id and b.bug_id = ".$db->quote($bug_id)); + foreach ($attary as $att) { + unlink(join('/', array(ATTACHMENT_PATH, + $att['project_id'], "$bug_id-{$att['file_name']}"))); + } + $db->query("delete from ".TBL_ATTACHMENT." where bug_id = ".$db->quote($bug_id)); + + // CCs + $db->query("delete from ".TBL_BUG_CC." where bug_id = ".$db->quote($bug_id)); + + // Comments + $db->query("delete from ".TBL_COMMENT." where bug_id = ".$db->quote($bug_id)); + + // Dependencies + $db->query("delete from ".TBL_BUG_DEPENDENCY. + " where bug_id = ".$db->quote($bug_id)." or depends_on = ".$db->quote($bug_id)); + + // Groups + $db->query("delete from ".TBL_GROUP." where bug_id = ".$db->quote($bug_id)); + + // Histories + $db->query("delete from ".TBL_BUG_HISTORY." where bug_id = ".$db->quote($bug_id)); + + // Votes + $db->query("delete from ".TBL_BUG_VOTE." where bug_id = ".$db->quote($bug_id)); +} + ?> |
|
From: Ulf E. <ulf...@us...> - 2005-05-25 18:07:53
|
Update of /cvsroot/phpbt/phpbt/inc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1685/inc Modified Files: functions.php Log Message: Allow error messages also when templates are unavailable (due to errors) Index: functions.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/inc/functions.php,v retrieving revision 1.49 retrieving revision 1.50 diff -u -r1.49 -r1.50 --- functions.php 15 Feb 2005 13:34:20 -0000 1.49 +++ functions.php 25 May 2005 18:07:43 -0000 1.50 @@ -37,6 +37,11 @@ function show_text($text, $iserror = false) { global $t; + if (!is_object($t)) { + echo "<div class=\"error\">$text</div>"; + exit; + } + $t->assign(array( 'text' => $text, 'iserror' => $iserror |
|
From: Ulf E. <ulf...@us...> - 2005-05-25 18:04:56
|
Update of /cvsroot/phpbt/phpbt/inc/db In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1224/inc/db Modified Files: mysql.php oci8.php Log Message: Patch 989398 - Sequence and assignable field fixes, by Antti Merenluoto Index: mysql.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/inc/db/mysql.php,v retrieving revision 1.19 retrieving revision 1.20 diff -u -r1.19 -r1.20 --- mysql.php 25 Oct 2004 12:07:01 -0000 1.19 +++ mysql.php 25 May 2005 18:04:48 -0000 1.20 @@ -5,7 +5,7 @@ 'from '.TBL_AUTH_GROUP.' ag '. 'left join '.TBL_USER_GROUP.' ug using (group_id) '. 'left join '.TBL_AUTH_USER.' using (user_id) '. - 'group by ag.group_id, group_name, locked '. + 'group by ag.group_id, group_name, locked, assignable '. 'order by %s %s', 'admin-list-oses' => 'select s.os_id, os_name, regex, sort_order, '. 'count(bug_id) as bug_count '. Index: oci8.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/inc/db/oci8.php,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- oci8.php 25 Oct 2004 12:07:01 -0000 1.16 +++ oci8.php 25 May 2005 18:04:48 -0000 1.17 @@ -2,10 +2,10 @@ $QUERY = array( 'admin-list-groups' => 'select ag.group_id, ag.group_name, ag.locked, '. - 'count(ug.group_id) as count, asssignable '. + 'count(ug.group_id) as count, assignable '. 'from '.TBL_AUTH_GROUP.' ag, '.TBL_USER_GROUP.' ug,'.TBL_AUTH_USER.' au '. 'where ag.group_id = ug.group_id(+) and ug.user_id = au.user_id(+) '. - 'group by ag.group_id, ag.group_name, ag.locked '. + 'group by ag.group_id, ag.group_name, ag.locked, ag.assignable '. 'order by %s %s', 'admin-list-oses' => 'select s.os_id, s.os_name, s.regex, s.sort_order, '. 'count(b.bug_id) as bug_count '. |
|
From: Ulf E. <ulf...@us...> - 2005-05-25 18:04:56
|
Update of /cvsroot/phpbt/phpbt/schemas In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1224/schemas Modified Files: mysql.in oci8.in pgsql.in Log Message: Patch 989398 - Sequence and assignable field fixes, by Antti Merenluoto Index: mysql.in =================================================================== RCS file: /cvsroot/phpbt/phpbt/schemas/mysql.in,v retrieving revision 1.44 retrieving revision 1.45 diff -u -r1.44 -r1.45 --- mysql.in 25 Oct 2004 12:07:02 -0000 1.44 +++ mysql.in 25 May 2005 18:04:48 -0000 1.45 @@ -419,3 +419,15 @@ INSERT INTO TBL_SITE VALUES (4,'Test site - location 2',5); create table TBL_SITE_seq (id int unsigned auto_increment not null primary key); insert into TBL_SITE_seq values (4); + +#-- Sequences for the tables with no initial entries +create table TBL_BUG_seq (id int unsigned auto_increment not null primary key); +insert into TBL_BUG_seq values(1); +create table TBL_COMMENT_seq (id int unsigned auto_increment not null primary key); +insert into TBL_COMMENT_seq values(1); +create table TBL_COMPONENT_seq (id int unsigned auto_increment not null primary key); +insert into TBL_COMPONENT_seq values(1); +create table TBL_PROJECT_seq (id int unsigned auto_increment not null primary key); +insert into TBL_PROJECT_seq values(1); +create table TBL_VERSION_seq (id int unsigned auto_increment not null primary key); +insert into TBL_VERSION_seq values(1); Index: oci8.in =================================================================== RCS file: /cvsroot/phpbt/phpbt/schemas/oci8.in,v retrieving revision 1.25 retrieving revision 1.26 diff -u -r1.25 -r1.26 --- oci8.in 4 Jun 2003 18:47:21 -0000 1.25 +++ oci8.in 25 May 2005 18:04:48 -0000 1.26 @@ -20,6 +20,7 @@ group_id number(10) default '0' NOT NULL, group_name varchar2(80) default '' NOT NULL, locked number(1) default '0' NOT NULL, + assignable number(1) default '0' NOT NULL, created_by number(10) default '0' NOT NULL, created_date number(20) default '0' NOT NULL, last_modified_by number(10) default '0' NOT NULL, @@ -409,3 +410,10 @@ INSERT INTO TBL_SITE VALUES (3,'Test site - location 1',4); INSERT INTO TBL_SITE VALUES (4,'Test site - location 2',5); CREATE SEQUENCE TBL_SITE_seq START WITH 5 NOCACHE; + +-- Sequences for the tables with no initial entries +CREATE SEQUENCE TBL_BUG_seq START WITH 1 NOCACHE; +CREATE SEQUENCE TBL_COMMENT_seq START WITH 1 NOCACHE; +CREATE SEQUENCE TBL_COMPONENT_seq START WITH 1 NOCACHE; +CREATE SEQUENCE TBL_PROJECT_seq START WITH 1 NOCACHE; +CREATE SEQUENCE TBL_VERSION_seq START WITH 1 NOCACHE; Index: pgsql.in =================================================================== RCS file: /cvsroot/phpbt/phpbt/schemas/pgsql.in,v retrieving revision 1.46 retrieving revision 1.47 diff -u -r1.46 -r1.47 --- pgsql.in 25 Oct 2004 12:27:57 -0000 1.46 +++ pgsql.in 25 May 2005 18:04:48 -0000 1.47 @@ -433,32 +433,15 @@ CREATE INDEX group_id_TBL_BUG_GROUP_index ON TBL_BUG_GROUP (group_id); -CREATE SEQUENCE phpbt_auth_user_seq; -CREATE SEQUENCE phpbt_auth_group_seq; -CREATE SEQUENCE phpbt_os_seq; -CREATE SEQUENCE phpbt_resolution_seq; -CREATE SEQUENCE phpbt_severity_seq; -CREATE SEQUENCE phpbt_status_seq; -CREATE SEQUENCE phpbt_database_server_seq; -CREATE SEQUENCE phpbt_site_seq; -CREATE SEQUENCE phpbt_version_seq; -CREATE SEQUENCE phpbt_component_seq; -CREATE SEQUENCE phpbt_bug_seq; -CREATE SEQUENCE phpbt_attachment_seq; -CREATE SEQUENCE phpbt_auth_perm_seq; -CREATE SEQUENCE phpbt_bug_cc_seq; -CREATE SEQUENCE phpbt_bug_dependency_seq; -CREATE SEQUENCE phpbt_bug_group_seq; -CREATE SEQUENCE phpbt_bug_history_seq; -CREATE SEQUENCE phpbt_bug_vote_seq; -CREATE SEQUENCE phpbt_comment_seq; -CREATE SEQUENCE phpbt_group_perm_seq; -CREATE SEQUENCE phpbt_project_seq; -CREATE SEQUENCE phpbt_project_group_seq; -CREATE SEQUENCE phpbt_saved_query_seq; -CREATE SEQUENCE phpbt_user_group_seq; -CREATE SEQUENCE phpbt_user_perm_seq; -CREATE SEQUENCE phpbt_user_pref_seq; +-- Sequences for the tables with no initial entries +-- +CREATE SEQUENCE TBL_BUG_seq; +CREATE SEQUENCE TBL_COMMENT_seq; +CREATE SEQUENCE TBL_COMPONENT_seq; +CREATE SEQUENCE TBL_PROJECT_seq; +CREATE SEQUENCE TBL_VERSION_seq; + +-- COMMIT; |
|
From: Ulf E. <ulf...@fa...> - 2005-05-24 21:04:01
|
* Ulf Erikson [2005-05-23 16:42]: > * Ben Curtis [2005-05-19 17:34]: >>Actually, I don't have a list of blocking issues. I think the code is >>basically ready to go for a 1.0 release. Of course, I could be >>forgetting something. :) I'd rather do 1.0 than RC6. I think the only >>thing holding me back is really someone (besides me) giving me the >>thumbs up that the upgrade script works just fine for a 0.9.x database. > > Hmm.. There have actually been a number of tumbs down for installer and > upgrade scripts lately.. I suspect that this partly could be due to > newer versions of php and/or mysql. I'll try to come up with something > there (including the error and warning log we talked about earlier). I have updated PEAR and DB in CVS now, as well as changed all error checking to use DB::isError. For me this was enough to get phpBT running with PHP5 earlier (can't test that right now, but it still works with PHP4 here). Logs for install and upgrade will come later. Probably something along these lines: http://sourceforge.net/mailarchive/message.php?msg_id=11121869 Let me know if I managed to fix or break something ;-) /Ulf |
|
From: Ulf E. <ulf...@us...> - 2005-05-24 20:53:44
|
Update of /cvsroot/phpbt/phpbt In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17243 Modified Files: install.php Log Message: Move TBL_CONFIGURATION into the text string Index: install.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/install.php,v retrieving revision 1.41 retrieving revision 1.42 diff -u -r1.41 -r1.42 --- install.php 24 May 2005 20:49:55 -0000 1.41 +++ install.php 24 May 2005 20:53:33 -0000 1.42 @@ -182,7 +182,7 @@ $do_query = ''; } /*!! BAD! Must figure out how to get db_version from config-dist.php... */ - $query = preg_replace(array_keys($tables), array_values($tables), 'INSERT INTO '.TBL_CONFIGURATION.' (varname,varvalue,description,vartype) VALUES (\'DB_VERSION\', './*!!!*/4/*!!!*/.', \'Database Version <b>Warning:</b> Changing this might make things go horribly wrong, so don\\\'t change it.\', \'mixed\')'); + $query = preg_replace(array_keys($tables), array_values($tables), 'INSERT INTO TBL_CONFIGURATION (varname,varvalue,description,vartype) VALUES (\'DB_VERSION\', './*!!!*/4/*!!!*/.', \'Database Version <b>Warning:</b> Changing this might make things go horribly wrong, so don\\\'t change it.\', \'mixed\')'); $res = $db->query($query); if (DB::isError($res)) { echo 'DB_VERSION not set!'; |
|
From: Ulf E. <ulf...@us...> - 2005-05-24 20:51:09
|
Update of /cvsroot/phpbt/phpbt/templates/default In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16751 Modified Files: install-dbsuccess.html install-dbfailure.html Log Message: Emphasize success and failure messages Index: install-dbsuccess.html =================================================================== RCS file: /cvsroot/phpbt/phpbt/templates/default/install-dbsuccess.html,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- install-dbsuccess.html 25 Oct 2004 12:07:04 -0000 1.2 +++ install-dbsuccess.html 24 May 2005 20:50:58 -0000 1.3 @@ -4,7 +4,11 @@ <link rel="StyleSheet" href="styles/default.css" type="text/css"> </head> <body> - <br><br> + <br> + <div align="center"> + <?php echo translate("DB Test Success"); ?> + </div> + <br> <div align="center"> <?php printf(translate("The installation script successfully connected to the database <b>%s</b> on the host <b>%s</b> using the specified username and password.<br>Congratulations!"), $params['db_database'], $params['db_host']); ?> <br> Index: install-dbfailure.html =================================================================== RCS file: /cvsroot/phpbt/phpbt/templates/default/install-dbfailure.html,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- install-dbfailure.html 25 Oct 2004 12:07:04 -0000 1.2 +++ install-dbfailure.html 24 May 2005 20:50:58 -0000 1.3 @@ -4,7 +4,11 @@ <link rel="StyleSheet" href="styles/default.css" type="text/css"> </head> <body> - <br><br> + <br> + <div class="error"> + <?php echo translate("DB Test Failure"); ?> + </div> + <br> <div align="center"> <?php printf(translate("The installation script could not connect to the database <b>%s</b> on the host <b>%s</b> using the specified username and password.<br>Please check these details are correct and that the database already exists then retry."), $params['db_database'], $params['db_host']); ?> <br> |
|
From: Ulf E. <ulf...@us...> - 2005-05-24 20:50:03
|
Update of /cvsroot/phpbt/phpbt In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16539 Modified Files: install.php Log Message: Use DB::isError for error checking Index: install.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/install.php,v retrieving revision 1.40 retrieving revision 1.41 diff -u -r1.40 -r1.41 --- install.php 25 Oct 2004 12:06:57 -0000 1.40 +++ install.php 24 May 2005 20:49:55 -0000 1.41 @@ -148,7 +148,7 @@ $db = DB::Connect($dsn); // Simple error checking on returned DB object to check connection to db - if (get_class($db) == 'db_error') { + if (DB::isError($db)) { include('templates/default/install-dbfailure.html'); exit; } else { @@ -184,7 +184,7 @@ /*!! BAD! Must figure out how to get db_version from config-dist.php... */ $query = preg_replace(array_keys($tables), array_values($tables), 'INSERT INTO '.TBL_CONFIGURATION.' (varname,varvalue,description,vartype) VALUES (\'DB_VERSION\', './*!!!*/4/*!!!*/.', \'Database Version <b>Warning:</b> Changing this might make things go horribly wrong, so don\\\'t change it.\', \'mixed\')'); $res = $db->query($query); - if (PEAR::isError($res)) { + if (DB::isError($res)) { echo 'DB_VERSION not set!'; } } |
|
From: Ulf E. <ulf...@us...> - 2005-05-24 20:48:01
|
Update of /cvsroot/phpbt/phpbt/inc/pear In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16014 Modified Files: DB.php Log Message: Update to PEAR DB 1.7.6 Index: DB.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/inc/pear/DB.php,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- DB.php 11 Oct 2002 20:54:43 -0000 1.2 +++ DB.php 24 May 2005 20:47:49 -0000 1.3 @@ -1,170 +1,409 @@ <?php -/* vim: set expandtab tabstop=4 shiftwidth=4: */ -// +----------------------------------------------------------------------+ -// | PHP Version 4 | -// +----------------------------------------------------------------------+ -// | Copyright (c) 1997-2002 The PHP Group | -// +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | -// | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | [...1737 lines suppressed...] { - for (reset($arr); $key = key($arr); next($arr)) { + foreach ($arr as $key => $value) { $this->$key = &$arr[$key]; } } + + // }}} } +// }}} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + ?> |
|
From: Ulf E. <ulf...@us...> - 2005-05-24 20:48:01
|
Update of /cvsroot/phpbt/phpbt/inc/pear/DB In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16014/DB Modified Files: common.php dbase.php fbsql.php ibase.php ifx.php msql.php mssql.php mysql.php oci8.php odbc.php pgsql.php storage.php sybase.php Added Files: mysqli.php sqlite.php Log Message: Update to PEAR DB 1.7.6 --- NEW FILE: mysqli.php --- <?php /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ /** * The PEAR DB driver for PHP's mysqli extension * for interacting with MySQL databases * * PHP versions 4 and 5 * * LICENSE: This source file is subject to version 3.0 of the PHP license * that is available through the world-wide-web at the following URI: * http://www.php.net/license/3_0.txt. If you did not receive a copy of * the PHP License and are unable to obtain it through the web, please * send a note to li...@ph... so we can mail you a copy immediately. * * @category Database * @package DB * @author Daniel Convissor <da...@ph...> [...1037 lines suppressed...] return 'SELECT DISTINCT User FROM mysql.user'; case 'databases': return 'SHOW DATABASES'; default: return null; } } // }}} } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: */ ?> --- NEW FILE: sqlite.php --- <?php /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ /** * The PEAR DB driver for PHP's sqlite extension * for interacting with SQLite databases * * PHP versions 4 and 5 * * LICENSE: This source file is subject to version 3.0 of the PHP license * that is available through the world-wide-web at the following URI: * http://www.php.net/license/3_0.txt. If you did not receive a copy of * the PHP License and are unable to obtain it through the web, please * send a note to li...@ph... so we can mail you a copy immediately. * * @category Database * @package DB * @author Urs Gehrig <ur...@ci...> * @author Mika Tuupola <tu...@ap...> * @author Daniel Convissor <da...@ph...> * @copyright 1997-2005 The PHP Group * @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0 * @version CVS: $Id: sqlite.php,v 1.1 2005/05/24 20:47:49 ulferikson Exp $ * @link http://pear.php.net/package/DB */ /** * Obtain the DB_common class so it can be extended from */ require_once PEAR_PATH.'DB/common.php'; /** * The methods PEAR DB uses to interact with PHP's sqlite extension * for interacting with SQLite databases * * These methods overload the ones declared in DB_common. * * NOTICE: This driver needs PHP's track_errors ini setting to be on. * It is automatically turned on when connecting to the database. * Make sure your scripts don't turn it off. * * @category Database * @package DB * @author Urs Gehrig <ur...@ci...> * @author Mika Tuupola <tu...@ap...> * @author Daniel Convissor <da...@ph...> * @copyright 1997-2005 The PHP Group * @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0 * @version Release: @package_version@ * @link http://pear.php.net/package/DB */ class DB_sqlite extends DB_common { // {{{ properties /** * The DB driver type (mysql, oci8, odbc, etc.) * @var string */ var $phptype = 'sqlite'; /** * The database syntax variant to be used (db2, access, etc.), if any * @var string */ var $dbsyntax = 'sqlite'; /** * The capabilities of this DB implementation * * The 'new_link' element contains the PHP version that first provided * new_link support for this DBMS. Contains false if it's unsupported. * * Meaning of the 'limit' element: * + 'emulate' = emulate with fetch row by number * + 'alter' = alter the query * + false = skip rows * * @var array */ var $features = array( 'limit' => 'alter', 'new_link' => false, 'numrows' => true, 'pconnect' => true, 'prepare' => false, 'ssl' => false, 'transactions' => false, ); /** * A mapping of native error codes to DB error codes * * {@internal Error codes according to sqlite_exec. See the online * manual at http://sqlite.org/c_interface.html for info. * This error handling based on sqlite_exec is not yet implemented.}} * * @var array */ var $errorcode_map = array( ); /** * The raw database connection created by PHP * @var resource */ var $connection; /** * The DSN information for connecting to a database * @var array */ var $dsn = array(); /** * SQLite data types * * @link http://www.sqlite.org/datatypes.html * * @var array */ var $keywords = array ( 'BLOB' => '', 'BOOLEAN' => '', 'CHARACTER' => '', 'CLOB' => '', 'FLOAT' => '', 'INTEGER' => '', 'KEY' => '', 'NATIONAL' => '', 'NUMERIC' => '', 'NVARCHAR' => '', 'PRIMARY' => '', 'TEXT' => '', 'TIMESTAMP' => '', 'UNIQUE' => '', 'VARCHAR' => '', 'VARYING' => '', ); /** * The most recent error message from $php_errormsg * @var string * @access private */ var $_lasterror = ''; // }}} // {{{ constructor /** * This constructor calls <kbd>$this->DB_common()</kbd> * * @return void */ function DB_sqlite() { $this->DB_common(); } // }}} // {{{ connect() /** * Connect to the database server, log in and open the database * * Don't call this method directly. Use DB::connect() instead. * * PEAR DB's sqlite driver supports the following extra DSN options: * + mode The permissions for the database file, in four digit * chmod octal format (eg "0600"). * * Example of connecting to a database in read-only mode: * <code> * require_once 'DB.php'; * * $dsn = 'sqlite:///path/and/name/of/db/file?mode=0400'; * $options = array( * 'portability' => DB_PORTABILITY_ALL, * ); * * $db =& DB::connect($dsn, $options); * if (PEAR::isError($db)) { * die($db->getMessage()); * } * </code> * * @param array $dsn the data source name * @param bool $persistent should the connection be persistent? * * @return int DB_OK on success. A DB_Error object on failure. */ function connect($dsn, $persistent = false) { if (!PEAR::loadExtension('sqlite')) { return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); } $this->dsn = $dsn; if ($dsn['dbsyntax']) { $this->dbsyntax = $dsn['dbsyntax']; } if ($dsn['database']) { if (!file_exists($dsn['database'])) { if (!touch($dsn['database'])) { return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); } if (!isset($dsn['mode']) || !is_numeric($dsn['mode'])) { $mode = 0644; } else { $mode = octdec($dsn['mode']); } if (!chmod($dsn['database'], $mode)) { return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); } if (!file_exists($dsn['database'])) { return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); } } if (!is_file($dsn['database'])) { return $this->sqliteRaiseError(DB_ERROR_INVALID); } if (!is_readable($dsn['database'])) { return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION); } } else { return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION); } $connect_function = $persistent ? 'sqlite_popen' : 'sqlite_open'; // track_errors must remain on for simpleQuery() ini_set('track_errors', 1); $php_errormsg = ''; if (!$this->connection = @$connect_function($dsn['database'])) { return $this->raiseError(DB_ERROR_NODBSELECTED, null, null, null, $php_errormsg); } return DB_OK; } // }}} // {{{ disconnect() /** * Disconnects from the database server * * @return bool TRUE on success, FALSE on failure */ function disconnect() { $ret = @sqlite_close($this->connection); $this->connection = null; return $ret; } // }}} // {{{ simpleQuery() /** * Sends a query to the database server * * NOTICE: This method needs PHP's track_errors ini setting to be on. * It is automatically turned on when connecting to the database. * Make sure your scripts don't turn it off. * * @param string the SQL query string * * @return mixed + a PHP result resrouce for successful SELECT queries * + the DB_OK constant for other successful queries * + a DB_Error object on failure */ function simpleQuery($query) { $ismanip = DB::isManip($query); $this->last_query = $query; $query = $this->modifyQuery($query); $php_errormsg = ''; $result = @sqlite_query($query, $this->connection); $this->_lasterror = $php_errormsg ? $php_errormsg : ''; $this->result = $result; if (!$this->result) { return $this->sqliteRaiseError(null); } // sqlite_query() seems to allways return a resource // so cant use that. Using $ismanip instead if (!$ismanip) { $numRows = $this->numRows($result); if (is_object($numRows)) { // we've got PEAR_Error return $numRows; } return $result; } return DB_OK; } // }}} // {{{ nextResult() /** * Move the internal sqlite result pointer to the next available result * * @param resource $result the valid sqlite result resource * * @return bool true if a result is available otherwise return false */ function nextResult($result) { return false; } // }}} // {{{ fetchInto() /** * Places a row from the result set into the given array * * Formating of the array and the data therein are configurable. * See DB_result::fetchInto() for more information. * * This method is not meant to be called directly. Use * DB_result::fetchInto() instead. It can't be declared "protected" * because DB_result is a separate object. * * @param resource $result the query result resource * @param array $arr the referenced array to put the data in * @param int $fetchmode how the resulting array should be indexed * @param int $rownum the row number to fetch (0 = first row) * * @return mixed DB_OK on success, NULL when the end of a result set is * reached or on failure * * @see DB_result::fetchInto() */ function fetchInto($result, &$arr, $fetchmode, $rownum = null) { if ($rownum !== null) { if (!@sqlite_seek($this->result, $rownum)) { return null; } } if ($fetchmode & DB_FETCHMODE_ASSOC) { $arr = @sqlite_fetch_array($result, SQLITE_ASSOC); if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { $arr = array_change_key_case($arr, CASE_LOWER); } } else { $arr = @sqlite_fetch_array($result, SQLITE_NUM); } if (!$arr) { return null; } if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { /* * Even though this DBMS already trims output, we do this because * a field might have intentional whitespace at the end that * gets removed by DB_PORTABILITY_RTRIM under another driver. */ $this->_rtrimArrayValues($arr); } if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { $this->_convertNullArrayValuesToEmpty($arr); } return DB_OK; } // }}} // {{{ freeResult() /** * Deletes the result set and frees the memory occupied by the result set * * This method is not meant to be called directly. Use * DB_result::free() instead. It can't be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource * * @return bool TRUE on success, FALSE if $result is invalid * * @see DB_result::free() */ function freeResult(&$result) { // XXX No native free? if (!is_resource($result)) { return false; } $result = null; return true; } // }}} // {{{ numCols() /** * Gets the number of columns in a result set * * This method is not meant to be called directly. Use * DB_result::numCols() instead. It can't be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource * * @return int the number of columns. A DB_Error object on failure. * * @see DB_result::numCols() */ function numCols($result) { $cols = @sqlite_num_fields($result); if (!$cols) { return $this->sqliteRaiseError(); } return $cols; } // }}} // {{{ numRows() /** * Gets the number of rows in a result set * * This method is not meant to be called directly. Use * DB_result::numRows() instead. It can't be declared "protected" * because DB_result is a separate object. * * @param resource $result PHP's query result resource * * @return int the number of rows. A DB_Error object on failure. * * @see DB_result::numRows() */ function numRows($result) { $rows = @sqlite_num_rows($result); if ($rows === null) { return $this->sqliteRaiseError(); } return $rows; } // }}} // {{{ affected() /** * Determines the number of rows affected by a data maniuplation query * * 0 is returned for queries that don't manipulate data. * * @return int the number of rows. A DB_Error object on failure. */ function affectedRows() { return @sqlite_changes($this->connection); } // }}} // {{{ dropSequence() /** * Deletes a sequence * * @param string $seq_name name of the sequence to be deleted * * @return int DB_OK on success. A DB_Error object on failure. * * @see DB_common::dropSequence(), DB_common::getSequenceName(), * DB_sqlite::nextID(), DB_sqlite::createSequence() */ function dropSequence($seq_name) { return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); } /** * Creates a new sequence * * @param string $seq_name name of the new sequence * * @return int DB_OK on success. A DB_Error object on failure. * * @see DB_common::createSequence(), DB_common::getSequenceName(), * DB_sqlite::nextID(), DB_sqlite::dropSequence() */ function createSequence($seq_name) { $seqname = $this->getSequenceName($seq_name); $query = 'CREATE TABLE ' . $seqname . ' (id INTEGER UNSIGNED PRIMARY KEY) '; $result = $this->query($query); if (DB::isError($result)) { return($result); } $query = "CREATE TRIGGER ${seqname}_cleanup AFTER INSERT ON $seqname BEGIN DELETE FROM $seqname WHERE id<LAST_INSERT_ROWID(); END "; $result = $this->query($query); if (DB::isError($result)) { return($result); } } // }}} // {{{ nextId() /** * Returns the next free id in a sequence * * @param string $seq_name name of the sequence * @param boolean $ondemand when true, the seqence is automatically * created if it does not exist * * @return int the next id number in the sequence. * A DB_Error object on failure. * * @see DB_common::nextID(), DB_common::getSequenceName(), * DB_sqlite::createSequence(), DB_sqlite::dropSequence() */ function nextId($seq_name, $ondemand = true) { $seqname = $this->getSequenceName($seq_name); do { $repeat = 0; $this->pushErrorHandling(PEAR_ERROR_RETURN); $result = $this->query("INSERT INTO $seqname (id) VALUES (NULL)"); $this->popErrorHandling(); if ($result === DB_OK) { $id = @sqlite_last_insert_rowid($this->connection); if ($id != 0) { return $id; } } elseif ($ondemand && DB::isError($result) && $result->getCode() == DB_ERROR_NOSUCHTABLE) { $result = $this->createSequence($seq_name); if (DB::isError($result)) { return $this->raiseError($result); } else { $repeat = 1; } } } while ($repeat); return $this->raiseError($result); } // }}} // {{{ getDbFileStats() /** * Get the file stats for the current database * * Possible arguments are dev, ino, mode, nlink, uid, gid, rdev, size, * atime, mtime, ctime, blksize, blocks or a numeric key between * 0 and 12. * * @param string $arg the array key for stats() * * @return mixed an array on an unspecified key, integer on a passed * arg and false at a stats error */ function getDbFileStats($arg = '') { $stats = stat($this->dsn['database']); if ($stats == false) { return false; } if (is_array($stats)) { if (is_numeric($arg)) { if (((int)$arg <= 12) & ((int)$arg >= 0)) { return false; } return $stats[$arg ]; } if (array_key_exists(trim($arg), $stats)) { return $stats[$arg ]; } } return $stats; } // }}} // {{{ escapeSimple() /** * Escapes a string according to the current DBMS's standards * * In SQLite, this makes things safe for inserts/updates, but may * cause problems when performing text comparisons against columns * containing binary data. See the * {@link http://php.net/sqlite_escape_string PHP manual} for more info. * * @param string $str the string to be escaped * * @return string the escaped string * * @since Method available since Release 1.6.1 * @see DB_common::escapeSimple() */ function escapeSimple($str) { return @sqlite_escape_string($str); } // }}} // {{{ modifyLimitQuery() /** * Adds LIMIT clauses to a query string according to current DBMS standards * * @param string $query the query to modify * @param int $from the row to start to fetching (0 = the first row) * @param int $count the numbers of rows to fetch * @param mixed $params array, string or numeric data to be used in * execution of the statement. Quantity of items * passed must match quantity of placeholders in * query: meaning 1 placeholder for non-array * parameters or 1 placeholder per array element. * * @return string the query string with LIMIT clauses added * * @access protected */ function modifyLimitQuery($query, $from, $count, $params = array()) { return "$query LIMIT $count OFFSET $from"; } // }}} // {{{ modifyQuery() /** * Changes a query string for various DBMS specific reasons * * This little hack lets you know how many rows were deleted * when running a "DELETE FROM table" query. Only implemented * if the DB_PORTABILITY_DELETE_COUNT portability option is on. * * @param string $query the query string to modify * * @return string the modified query string * * @access protected * @see DB_common::setOption() */ function modifyQuery($query) { if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) { if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) { $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', 'DELETE FROM \1 WHERE 1=1', $query); } } return $query; } // }}} // {{{ sqliteRaiseError() /** * Produces a DB_Error object regarding the current problem * * @param int $errno if the error is being manually raised pass a * DB_ERROR* constant here. If this isn't passed * the error information gathered from the DBMS. * * @return object the DB_Error object * * @see DB_common::raiseError(), * DB_sqlite::errorNative(), DB_sqlite::errorCode() */ function sqliteRaiseError($errno = null) { $native = $this->errorNative(); if ($errno === null) { $errno = $this->errorCode($native); } $errorcode = @sqlite_last_error($this->connection); $userinfo = "$errorcode ** $this->last_query"; return $this->raiseError($errno, null, null, $userinfo, $native); } // }}} // {{{ errorNative() /** * Gets the DBMS' native error message produced by the last query * * {@internal This is used to retrieve more meaningfull error messages * because sqlite_last_error() does not provide adequate info.}} * * @return string the DBMS' error message */ function errorNative() { return $this->_lasterror; } // }}} // {{{ errorCode() /** * Determines PEAR::DB error code from the database's text error message * * @param string $errormsg the error message returned from the database * * @return integer the DB error number */ function errorCode($errormsg) { static $error_regexps; if (!isset($error_regexps)) { $error_regexps = array( '/^no such table:/' => DB_ERROR_NOSUCHTABLE, '/^no such index:/' => DB_ERROR_NOT_FOUND, '/^(table|index) .* already exists$/' => DB_ERROR_ALREADY_EXISTS, '/PRIMARY KEY must be unique/i' => DB_ERROR_CONSTRAINT, '/is not unique/' => DB_ERROR_CONSTRAINT, '/columns .* are not unique/i' => DB_ERROR_CONSTRAINT, '/uniqueness constraint failed/' => DB_ERROR_CONSTRAINT, '/may not be NULL/' => DB_ERROR_CONSTRAINT_NOT_NULL, '/^no such column:/' => DB_ERROR_NOSUCHFIELD, '/column not present in both tables/i' => DB_ERROR_NOSUCHFIELD, '/^near ".*": syntax error$/' => DB_ERROR_SYNTAX, '/[0-9]+ values for [0-9]+ columns/i' => DB_ERROR_VALUE_COUNT_ON_ROW, ); } foreach ($error_regexps as $regexp => $code) { if (preg_match($regexp, $errormsg)) { return $code; } } // Fall back to DB_ERROR if there was no mapping. return DB_ERROR; } // }}} // {{{ tableInfo() /** * Returns information about a table * * @param string $result a string containing the name of a table * @param int $mode a valid tableInfo mode * * @return array an associative array with the information requested. * A DB_Error object on failure. * * @see DB_common::tableInfo() * @since Method available since Release 1.7.0 */ function tableInfo($result, $mode = null) { if (is_string($result)) { /* * Probably received a table name. * Create a result resource identifier. */ $id = @sqlite_array_query($this->connection, "PRAGMA table_info('$result');", SQLITE_ASSOC); $got_string = true; } else { $this->last_query = ''; return $this->raiseError(DB_ERROR_NOT_CAPABLE, null, null, null, 'This DBMS can not obtain tableInfo' . ' from result sets'); } if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { $case_func = 'strtolower'; } else { $case_func = 'strval'; } $count = count($id); $res = array(); if ($mode) { $res['num_fields'] = $count; } for ($i = 0; $i < $count; $i++) { if (strpos($id[$i]['type'], '(') !== false) { $bits = explode('(', $id[$i]['type']); $type = $bits[0]; $len = rtrim($bits[1],')'); } else { $type = $id[$i]['type']; $len = 0; } $flags = ''; if ($id[$i]['pk']) { $flags .= 'primary_key '; } if ($id[$i]['notnull']) { $flags .= 'not_null '; } if ($id[$i]['dflt_value'] !== null) { $flags .= 'default_' . rawurlencode($id[$i]['dflt_value']); } $flags = trim($flags); $res[$i] = array( 'table' => $case_func($result), 'name' => $case_func($id[$i]['name']), 'type' => $type, 'len' => $len, 'flags' => $flags, ); if ($mode & DB_TABLEINFO_ORDER) { $res['order'][$res[$i]['name']] = $i; } if ($mode & DB_TABLEINFO_ORDERTABLE) { $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; } } return $res; } // }}} // {{{ getSpecialQuery() /** * Obtains the query string needed for listing a given type of objects * * @param string $type the kind of objects you want to retrieve * @param array $args SQLITE DRIVER ONLY: a private array of arguments * used by the getSpecialQuery(). Do not use * this directly. * * @return string the SQL query string or null if the driver doesn't * support the object type requested * * @access protected * @see DB_common::getListOf() */ function getSpecialQuery($type, $args = array()) { if (!is_array($args)) { return $this->raiseError('no key specified', null, null, null, 'Argument has to be an array.'); } switch ($type) { case 'master': return 'SELECT * FROM sqlite_master;'; case 'tables': return "SELECT name FROM sqlite_master WHERE type='table' " . 'UNION ALL SELECT name FROM sqlite_temp_master ' . "WHERE type='table' ORDER BY name;"; case 'schema': return 'SELECT sql FROM (SELECT * FROM sqlite_master ' . 'UNION ALL SELECT * FROM sqlite_temp_master) ' . "WHERE type!='meta' " . 'ORDER BY tbl_name, type DESC, name;'; case 'schemax': case 'schema_x': /* * Use like: * $res = $db->query($db->getSpecialQuery('schema_x', * array('table' => 'table3'))); */ return 'SELECT sql FROM (SELECT * FROM sqlite_master ' . 'UNION ALL SELECT * FROM sqlite_temp_master) ' . "WHERE tbl_name LIKE '{$args['table']}' " . "AND type!='meta' " . 'ORDER BY type DESC, name;'; case 'alter': /* * SQLite does not support ALTER TABLE; this is a helper query * to handle this. 'table' represents the table name, 'rows' * the news rows to create, 'save' the row(s) to keep _with_ * the data. * * Use like: * $args = array( * 'table' => $table, * 'rows' => "id INTEGER PRIMARY KEY, firstname TEXT, surname TEXT, datetime TEXT", * 'save' => "NULL, titel, content, datetime" * ); * $res = $db->query( $db->getSpecialQuery('alter', $args)); */ $rows = strtr($args['rows'], $this->keywords); $q = array( 'BEGIN TRANSACTION', "CREATE TEMPORARY TABLE {$args['table']}_backup ({$args['rows']})", "INSERT INTO {$args['table']}_backup SELECT {$args['save']} FROM {$args['table']}", "DROP TABLE {$args['table']}", "CREATE TABLE {$args['table']} ({$args['rows']})", "INSERT INTO {$args['table']} SELECT {$rows} FROM {$args['table']}_backup", "DROP TABLE {$args['table']}_backup", 'COMMIT', ); /* * This is a dirty hack, since the above query will not get * executed with a single query call so here the query method * will be called directly and return a select instead. */ foreach ($q as $query) { $this->query($query); } return "SELECT * FROM {$args['table']};"; default: return null; } } // }}} } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: */ ?> Index: common.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/inc/pear/DB/common.php,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- common.php 13 Sep 2002 18:07:51 -0000 1.1 +++ common.php 24 May 2005 20:47:49 -0000 1.2 @@ -1,154 +1,248 @@ <?php -// -// +----------------------------------------------------------------------+ -// | PHP Version 4 | -// +----------------------------------------------------------------------+ -// | Copyright (c) 1997-2002 The PHP Group | -// +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | -// | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | [...2703 lines suppressed...] + if (is_null($value)) { + $array[$key] = ''; + } } - return $ret; } + + // }}} } -?> \ No newline at end of file +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> Index: dbase.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/inc/pear/DB/dbase.php,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- dbase.php 11 Oct 2002 20:54:43 -0000 1.2 +++ dbase.php 24 May 2005 20:47:49 -0000 1.3 @@ -1,123 +1,510 @@ <?php -// -// +----------------------------------------------------------------------+ -// | PHP Version 4 | -// +----------------------------------------------------------------------+ -// | Copyright (c) 1997-2002 The PHP Group | -// +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | -// | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | -// | If you did not receive a copy of the PHP license and are unable to | -// | obtain it through the world-wide-web, please send a note to | -// | li...@ph... so we can mail you a copy immediately. | -// +----------------------------------------------------------------------+ -// | Author: Tomas V.V.Cox <co...@id...> | -// +----------------------------------------------------------------------+ -// -// $Id$ -// -// Database independent query interface definition for PHP's dbase -// extension. -// -// XXX legend: -// You have to compile your PHP with the --enable-dbase option -// -require_once PEAR_PATH."DB/common.php"; +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ +/** + * The PEAR DB driver for PHP's dbase extension + * for interacting with dBase databases + * + * PHP versions 4 and 5 + * + * LICENSE: This source file is subject to version 3.0 of the PHP license + * that is available through the world-wide-web at the following URI: + * http://www.php.net/license/3_0.txt. If you did not receive a copy of + * the PHP License and are unable to obtain it through the web, please + * send a note to li...@ph... so we can mail you a copy immediately. + * + * @category Database + * @package DB + * @author Tomas V.V. Cox <co...@id...> + * @author Daniel Convissor <da...@ph...> + * @copyright 1997-2005 The PHP Group + * @license http://www.php.net/license/3_0.txt PHP License 3.0 + * @version CVS: $Id$ + * @link http://pear.php.net/package/DB + */ + +/** + * Obtain the DB_common class so it can be extended from + */ +require_once PEAR_PATH.'DB/common.php'; + +/** + * The methods PEAR DB uses to interact with PHP's dbase extension + * for interacting with dBase databases + * + * These methods overload the ones declared in DB_common. + * + * @category Database + * @package DB + * @author Tomas V.V. Cox <co...@id...> + * @author Daniel Convissor <da...@ph...> + * @copyright 1997-2005 The PHP Group + * @license http://www.php.net/license/3_0.txt PHP License 3.0 + * @version Release: @package_version@ + * @link http://pear.php.net/package/DB + */ class DB_dbase extends DB_common { // {{{ properties + /** + * The DB driver type (mysql, oci8, odbc, etc.) + * @var string + */ + var $phptype = 'dbase'; + + /** + * The database syntax variant to be used (db2, access, etc.), if any + * @var string + */ + var $dbsyntax = 'dbase'; + + /** + * The capabilities of this DB implementation + * + * The 'new_link' element contains the PHP version that first provided + * new_link support for this DBMS. Contains false if it's unsupported. + * + * Meaning of the 'limit' element: + * + 'emulate' = emulate with fetch row by number + * + 'alter' = alter the query + * + false = skip rows + * + * @var array + */ + var $features = array( + 'limit' => false, + 'new_link' => false, + 'numrows' => true, + 'pconnect' => false, + 'prepare' => false, + 'ssl' => false, + 'transactions' => false, + ); + + /** + * A mapping of native error codes to DB error codes + * @var array + */ + var $errorcode_map = array( + ); + + /** + * The raw database connection created by PHP + * @var resource + */ var $connection; - var $phptype, $dbsyntax; - var $prepare_tokens = array(); - var $prepare_types = array(); - var $transaction_opcount = 0; + + /** + * The DSN information for connecting to a database + * @var array + */ + var $dsn = array(); + + + /** + * A means of emulating result resources + * @var array + */ var $res_row = array(); + + /** + * The quantity of results so far + * + * For emulating result resources. + * + * @var integer + */ var $result = 0; + /** + * Maps dbase data type id's to human readable strings + * + * The human readable values are based on the output of PHP's + * dbase_get_header_info() function. + * + * @var array + * @since Property available since Release 1.7.0 + */ + var $types = array( + 'C' => 'character', + 'D' => 'date', + 'L' => 'boolean', + 'M' => 'memo', + 'N' => 'number', + ); + + // }}} // {{{ constructor /** - * DB_mysql constructor. + * This constructor calls <kbd>$this->DB_common()</kbd> * - * @access public + * @return void */ - function DB_dbase() { $this->DB_common(); - $this->phptype = 'dbase'; - $this->dbsyntax = 'dbase'; - $this->features = array( - 'prepare' => false, - 'pconnect' => false, - 'transactions' => false, - 'limit' => false - ); - $this->errorcode_map = array(); } - function connect($dsninfo, $persistent = false) + // }}} + // {{{ connect() + + /** + * Connect to the database and create it if it doesn't exist + * + * Don't call this method directly. Use DB::connect() instead. + * + * PEAR DB's dbase driver supports the following extra DSN options: + * + mode An integer specifying the read/write mode to use + * (0 = read only, 1 = write only, 2 = read/write). + * Available since PEAR DB 1.7.0. + * + fields An array of arrays that PHP's dbase_create() function needs + * to create a new database. This information is used if the + * dBase file specified in the "database" segment of the DSN + * does not exist. For more info, see the PHP manual's + * {@link http://php.net/dbase_create dbase_create()} page. + * Available since PEAR DB 1.7.0. + * + * Example of how to connect and establish a new dBase file if necessary: + * <code> + * require_once 'DB.php'; + * + * $dsn = array( + * 'phptype' => 'dbase', + * 'database' => '/path/and/name/of/dbase/file', + * 'mode' => 2, + * 'fields' => array( + * array('a', 'N', 5, 0), + * array('b', 'C', 40), + * array('c', 'C', 255), + * array('d', 'C', 20), + * ), + * ); + * $options = array( + * 'debug' => 2, + * 'portability' => DB_PORTABILITY_ALL, + * ); + * + * $db =& DB::connect($dsn, $options); + * if (PEAR::isError($db)) { + * die($db->getMessage()); + * } + * </code> + * + * @param array $dsn the data source name + * @param bool $persistent should the connection be persistent? + * + * @return int DB_OK on success. A DB_Error object on failure. + */ + function connect($dsn, $persistent = false) { - if (!DB::assertExtension('dbase')) { + if (!PEAR::loadExtension('dbase')) { return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); } - $this->dsn = $dsninfo; - ob_start(); - $conn = dbase_open($dsninfo['database'], 0); - $error = ob_get_contents(); - ob_end_clean(); - if (!$conn) { - return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, - null, null, strip_tags($error)); + + $this->dsn = $dsn; + if ($dsn['dbsyntax']) { + $this->dbsyntax = $dsn['dbsyntax']; + } + + /* + * Turn track_errors on for entire script since $php_errormsg + * is the only way to find errors from the dbase extension. + */ + ini_set('track_errors', 1); + $php_errormsg = ''; + + if (!file_exists($dsn['database'])) { + $this->dsn['mode'] = 2; + if (empty($dsn['fields']) || !is_array($dsn['fields'])) { + return $this->raiseError(DB_ERROR_CONNECT_FAILED, + null, null, null, + 'the dbase file does not exist and ' + . 'it could not be created because ' + . 'the "fields" element of the DSN ' + . 'is not properly set'); + } + $this->connection = @dbase_create($dsn['database'], + $dsn['fields']); + if (!$this->connection) { + return $this->raiseError(DB_ERROR_CONNECT_FAILED, + null, null, null, + 'the dbase file does not exist and ' + . 'the attempt to create it failed: ' + . $php_errormsg); + } + } else { + if (!isset($this->dsn['mode'])) { + $this->dsn['mode'] = 0; + } + $this->connection = @dbase_open($dsn['database'], + $this->dsn['mode']); + if (!$this->connection) { + return $this->raiseError(DB_ERROR_CONNECT_FAILED, + null, null, null, + $php_errormsg); + } } - $this->connection = $conn; return DB_OK; } + // }}} + // {{{ disconnect() + + /** + * Disconnects from the database server + * + * @return bool TRUE on success, FALSE on failure + */ function disconnect() { - $ret = dbase_close($this->connection); + $ret = @dbase_close($this->connection); $this->connection = null; return $ret; } + // }}} + // {{{ &query() + function &query($query = null) { // emulate result resources - $this->res_row[$this->result] = 0; - return new DB_result($this, $this->result++); + $this->res_row[(int)$this->result] = 0; + $tmp =& new DB_result($this, $this->result++); + return $tmp; } - function fetchInto($res, &$row, $fetchmode, $rownum = null) + // }}} + // {{{ fetchInto() + + /** + * Places a row from the result set into the given array + * + * Formating of the array and the data therein are configurable. + * See DB_result::fetchInto() for more information. + * + * This method is not meant to be called directly. Use + * DB_result::fetchInto() instead. It can't be declared "protected" + * because DB_result is a separate object. + * + * @param resource $result the query result resource + * @param array $arr the referenced array to put the data in + * @param int $fetchmode how the resulting array should be indexed + * @param int $rownum the row number to fetch (0 = first row) + * + * @return mixed DB_OK on success, NULL when the end of a result set is + * reached or on failure + * + * @see DB_result::fetchInto() + */ + function fetchInto($result, &$arr, $fetchmode, $rownum = null) { if ($rownum === null) { - $rownum = $this->res_row[$res]++; + $rownum = $this->res_row[(int)$result]++; } if ($fetchmode & DB_FETCHMODE_ASSOC) { - $row = @dbase_get_record_with_names($this->connection, $rownum); + $arr = @dbase_get_record_with_names($this->connection, $rownum); + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { + $arr = array_change_key_case($arr, CASE_LOWER); + } } else { - $row = @dbase_get_record($this->connection, $rownum); + $arr = @dbase_get_record($this->connection, $rownum); } - if (!$row) { + if (!$arr) { return null; } + if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { + $this->_rtrimArrayValues($arr); + } + if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { + $this->_convertNullArrayValuesToEmpty($arr); + } return DB_OK; } + // }}} + // {{{ numCols() + + /** + * Gets the number of columns in a result set + * + * This method is not meant to be called directly. Use + * DB_result::numCols() instead. It can't be declared "protected" + * because DB_result is a separate object. + * + * @param resource $result PHP's query result resource + * + * @return int the number of columns. A DB_Error object on failure. + * + * @see DB_result::numCols() + */ function numCols($foo) { - return dbase_numfields($this->connection); + return @dbase_numfields($this->connection); } + // }}} + // {{{ numRows() + + /** + * Gets the number of rows in a result set + * + * This method is not meant to be called directly. Use + * DB_result::numRows() instead. It can't be declared "protected" + * because DB_result is a separate object. + * + * @param resource $result PHP's query result resource + * + * @return int the number of rows. A DB_Error object on failure. + * + * @see DB_result::numRows() + */ function numRows($foo) { - return dbase_numrecords($this->connection); + return @dbase_numrecords($this->connection); } + + // }}} + // {{{ quoteSmart() + + /** + * Formats input so it can be safely used in a query + * + * @param mixed $in the data to be formatted + * + * @return mixed the formatted data. The format depends on the input's + * PHP type: + * + null = the string <samp>NULL</samp> + * + boolean = <samp>T</samp> if true or + * <samp>F</samp> if false. Use the <kbd>Logical</kbd> + * data type. + * + integer or double = the unquoted number + * + other (including strings and numeric strings) = + * the data with single quotes escaped by preceeding + * single quotes then the whole string is encapsulated + * between single quotes + * + * @see DB_common::quoteSmart() + * @since Method available since Release 1.6.0 + */ + function quoteSmart($in) + { + if (is_int($in) || is_double($in)) { + return $in; + } elseif (is_bool($in)) { + return $in ? 'T' : 'F'; + } elseif (is_null($in)) { + return 'NULL'; + } else { + return "'" . $this->escapeSimple($in) . "'"; + } + } + + // }}} + // {{{ tableInfo() + + /** + * Returns information about the current database + * + * @param mixed $result THIS IS UNUSED IN DBASE. The current database + * is examined regardless of what is provided here. + * @param int $mode a valid tableInfo mode + * + * @return array an associative array with the information requested. + * A DB_Error object on failure. + * + * @see DB_common::tableInfo() + * @since Method available since Release 1.7.0 + */ + function tableInfo($result = null, $mode = null) + { + if (function_exists('dbase_get_header_info')) { + $id = @dbase_get_header_info($this->connection); + if (!$id && $php_errormsg) { + return $this->raiseError(DB_ERROR, + null, null, null, + $php_errormsg); + } + } else { + /* + * This segment for PHP 4 is loosely based on code by + * Hadi Rusiah <de...@ya...> in the comments on + * the dBase reference page in the PHP manual. + */ + $db = @fopen($this->dsn['database'], 'r'); + if (!$db) { + return $this->raiseError(DB_ERROR_CONNECT_FAILED, + null, null, null, + $php_errormsg); + } + + $id = array(); + $i = 0; + + $line = fread($db, 32); + while (!feof($db)) { + $line = fread($db, 32); + if (substr($line, 0, 1) == chr(13)) { + break; + } else { + $pos = strpos(substr($line, 0, 10), chr(0)); + $pos = ($pos == 0 ? 10 : $pos); + $id[$i] = array( + 'name' => substr($line, 0, $pos), + 'type' => $this->types[substr($line, 11, 1)], + 'length' => ord(substr($line, 16, 1)), + 'precision' => ord(substr($line, 17, 1)), + ); + } + $i++; + } + + fclose($db); + } + + if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { + $case_func = 'strtolower'; + } else { + $case_func = 'strval'; + } + + $res = array(); + $count = count($id); + + if ($mode) { + $res['num_fields'] = $count; + } + + for ($i = 0; $i < $count; $i++) { + $res[$i] = array( + 'table' => $this->dsn['database'], + 'name' => $case_func($id[$i]['name']), + 'type' => $id[$i]['type'], + 'len' => $id[$i]['length'], + 'flags' => '' + ); + if ($mode & DB_TABLEINFO_ORDER) { + $res['order'][$res[$i]['name']] = $i; + } + if ($mode & DB_TABLEINFO_ORDERTABLE) { + $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; + } + } + + return $res; + } + + // }}} } -?> \ No newline at end of file + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + +?> Index: fbsql.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/inc/pear/DB/fbsql.php,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- fbsql.php 11 Oct 2002 20:54:43 -0000 1.2 +++ fbsql.php 24 May 2005 20:47:49 -0000 1.3 @@ -1,138 +1,194 @@ <?php -// -// +----------------------------------------------------------------------+ -// | PHP Version 4 | -// +----------------------------------------------------------------------+ -// | Copyright (c) 1997-2002 The PHP Group | -// +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | -// | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | [...1020 lines suppressed...] } - return $sql; } // }}} } -// TODO/wishlist: -// longReadlen -// binmode +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ -?> \ No newline at end of file +?> Index: ibase.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/inc/pear/DB/ibase.php,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ibase.php 11 Oct 2002 20:54:43 -0000 1.2 +++ ibase.php 24 May 2005 20:47:49 -0000 1.3 @@ -1,117 +1,259 @@ <?php -// -// +----------------------------------------------------------------------+ -// | PHP Version 4 | -// +----------------------------------------------------------------------+ -// | Copyright (c) 1997-2002 The PHP Group | -// +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | -// | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | [...1397 lines suppressed...] + case 'tables': + return 'SELECT DISTINCT R.RDB$RELATION_NAME FROM ' + . 'RDB$RELATION_FIELDS R WHERE R.RDB$SYSTEM_FLAG=0'; + case 'views': + return 'SELECT DISTINCT RDB$VIEW_NAME from RDB$VIEW_RELATIONS'; + case 'users': + return 'SELECT DISTINCT RDB$USER FROM RDB$USER_PRIVILEGES'; + default: + return null; + } } // }}} @@ -589,4 +1068,4 @@ * End: */ -?> \ No newline at end of file +?> Index: ifx.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/inc/pear/DB/ifx.php,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- ifx.php 11 Oct 2002 20:54:43 -0000 1.2 +++ ifx.php 24 May 2005 20:47:49 -0000 1.3 @@ -1,101 +1,226 @@ <?php -// -// +----------------------------------------------------------------------+ -// | PHP Version 4 | -// +----------------------------------------------------------------------+ -// | Copyright (c) 1997-2002 The PHP Group | -// +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | -// | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | -// | If you did not receive a copy of the PHP license and are unable to | -// | obtain it through the world-wide-web, please send a note to | -// | li...@ph... so we can mail you a copy immediately. | -// +----------------------------------------------------------------------+ -// | Author: Tomas V.V.Cox <co...@id...> | -// +----------------------------------------------------------------------+ -// -// $Id$ -// -// Database independent query interface definition for PHP's Informix -// extension. -// - -// Legend: -// For more info on Informix errors see: -// http://www.informix.com/answers/english/ierrors.htm -// -// TODO: -// - set needed env Informix vars on connect -// - implement native prepare/execute +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * The PEAR DB driver for PHP's ifx extension + * for interacting with Informix databases + * + * PHP versions 4 and 5 + * + * LICENSE: This source file is subject to version 3.0 of the PHP license + * that is available through the world-wide-web at the following URI: + * http://www.php.net/license/3_0.txt. If you did not receive a copy of + * the PHP License and are unable to obtain it through the web, please + * send a note to li...@ph... so we can mail you a copy immediately. + * + * @category Database + * @package DB + * @author Tomas V.V.Cox <co...@id...> + * @author Daniel Convissor <da...@ph...> + * @copyright 1997-2005 The PHP Group + * @license http://www.php.net/license/3_0.txt PHP License 3.0 + * @version CVS: $Id$ + * @link http://pear.php.net/package/DB + */ + +/** + * Obtain the DB_common class so it can be extended from + */ require_once PEAR_PATH.'DB/common.php'; +/** + * The methods PEAR DB uses to interact with PHP's ifx extension + * for interacting with Informix databases + * + * These methods overload the ones declared in DB_common. + * + * More info on Informix errors can be found at: + * http://www.informix.com/answers/english/ierrors.htm + * + * TODO: + * - set needed env Informix vars on connect + * - implement native prepare/execute + * + * @category Database + * @package DB + * @author Tomas V.V.Cox <co...@id...> + * @author Daniel Convissor <da...@ph...> + * @copyright 1997-2005 The PHP Group + * @license http://www.php.net/license/3_0.txt PHP License 3.0 + * @version Release: @package_version@ + * @link http://pear.php.net/package/DB + */ class DB_ifx extends DB_common { + // {{{ properties + + /** + * The DB driver type (mysql, oci8, odbc, etc.) + * @var string + */ + var $phptype = 'ifx'; + + /** + * The database syntax variant to be used (db2, access, etc.), if any + * @var string + */ + var $dbsyntax = 'ifx'; + + /** + * The capabilities of this DB implementation + * + * The 'new_link' element contains the PHP version that first provided + * new_link support for this DBMS. Contains false if it's unsupported. + * + * Meaning of the 'limit' element: + * + 'emulate' = emulate with fetch row by number + * + 'alter' = alter the query + * + false = skip rows + * + * @var array + */ + var $features = array( + 'limit' => 'emulate', + 'new_link' => false, + 'numrows' => 'emulate', + 'pconnect' => true, + 'prepare' => false, + 'ssl' => false, + 'transactions' => true, + ); + + /** + * A mapping of native error codes to DB error codes + * @var array + */ + var $errorcode_map = array( + '-201' => DB_ERROR_SYNTAX, + '-206' => DB_ERROR_NOSUCHTABLE, + '-217' => DB_ERROR_NOSUCHFIELD, + '-236' => DB_ERROR_VALUE_COUNT_ON_ROW, + '-239' => DB_ERROR_CONSTRAINT, + '-253' => DB_ERROR_SYNTAX, + '-292' => DB_ERROR_CONSTRAINT_NOT_NULL, + '-310' => DB_ERROR_ALREADY_EXISTS, + '-316' => DB_ERROR_ALREADY_EXISTS, + '-319' => DB_ERROR_NOT_FOUND, + '-329' => DB_ERROR_NODBSELECTED, + '-346' => DB_ERROR_CONSTRAINT, + '-386' => DB_ERROR_CONSTRAINT_NOT_NULL, + '-391' => DB_ERROR_CONSTRAINT_NOT_NULL, + '-554' => DB_ERROR_SYNTAX, + '-691' => DB_ERROR_CONSTRAINT, + '-692' => DB_ERROR_CONSTRAINT, + '-703' => DB_ERROR_CONSTRAINT_NOT_NULL, + '-1204' => DB_ERROR_INVALID_DATE, + '-1205' => DB_ERROR_INVALID_DATE, + '-1206' => DB_ERROR_INVALID_DATE, + '-1209' => DB_ERROR_INVALID_DATE, + '-1210' => DB_ERROR_INVALID_DATE, + '-1212' => DB_ERROR_INVALID_DATE, + '-1213' => DB_ERROR_INVALID_NUMBER, + ); + + /** +... [truncated message content] |
|
From: Ulf E. <ulf...@us...> - 2005-05-24 20:46:12
|
Update of /cvsroot/phpbt/phpbt/inc/pear In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15519 Modified Files: PEAR.php Log Message: Update to PEAR 1.3.5 Index: PEAR.php =================================================================== RCS file: /cvsroot/phpbt/phpbt/inc/pear/PEAR.php,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- PEAR.php 13 Sep 2002 18:07:51 -0000 1.1 +++ PEAR.php 24 May 2005 20:45:59 -0000 1.2 @@ -1,31 +1,38 @@ <?php // -// +----------------------------------------------------------------------+ -// | PHP Version 4 | -// +----------------------------------------------------------------------+ -// | Copyright (c) 1997-2002 The PHP Group | -// +----------------------------------------------------------------------+ -// | This source file is subject to version 2.0 of the PHP license, | -// | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | -// | If you did not receive a copy of the PHP license and are unable to | -// | obtain it through the world-wide-web, please send a note to | -// | li...@ph... so we can mail you a copy immediately. | -// +----------------------------------------------------------------------+ -// | Authors: Sterling Hughes <ste...@ph...> | -// | Stig Bakken <ss...@fa...> | -// | Tomas V.V.Cox <co...@id...> | -// +----------------------------------------------------------------------+ +// +--------------------------------------------------------------------+ +// | PEAR, the PHP Extension and Application Repository | +// +--------------------------------------------------------------------+ +// | Copyright (c) 1997-2004 The PHP Group | +// +--------------------------------------------------------------------+ +// | This source file is subject to version 3.0 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | li...@ph... so we can mail you a copy immediately. | +// +--------------------------------------------------------------------+ +// | Authors: Sterling Hughes <ste...@ph...> | +// | Stig Bakken <ss...@ph...> | +// | Tomas V.V.Cox <co...@id...> | +// +--------------------------------------------------------------------+ // // $Id$ // -define('PEAR_ERROR_RETURN', 1); -define('PEAR_ERROR_PRINT', 2); -define('PEAR_ERROR_TRIGGER', 4); -define('PEAR_ERROR_DIE', 8); -define('PEAR_ERROR_CALLBACK', 16); +define('PEAR_ERROR_RETURN', 1); +define('PEAR_ERROR_PRINT', 2); +define('PEAR_ERROR_TRIGGER', 4); +define('PEAR_ERROR_DIE', 8); +define('PEAR_ERROR_CALLBACK', 16); +/** + * WARNING: obsolete + * @deprecated + */ +define('PEAR_ERROR_EXCEPTION', 32); +define('PEAR_ZE2', (function_exists('version_compare') && + version_compare(zend_version(), "2-dev", "ge"))); if (substr(PHP_OS, 0, 3) == 'WIN') { define('OS_WINDOWS', true); @@ -37,14 +44,22 @@ define('PEAR_OS', 'Unix'); // blatant assumption } +// instant backwards compatibility +if (!defined('PATH_SEPARATOR')) { + if (OS_WINDOWS) { + define('PATH_SEPARATOR', ';'); + } else { + define('PATH_SEPARATOR', ':'); + } +} + $GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; $GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; -$GLOBALS['_PEAR_default_error_callback'] = ''; $GLOBALS['_PEAR_destructor_object_list'] = array(); +$GLOBALS['_PEAR_shutdown_funcs'] = array(); +$GLOBALS['_PEAR_error_handler_stack'] = array(); -// -// Tests needed: - PEAR inheritance -// +@ini_set('track_errors', true); /** * Base class for other PEAR classes. Provides rudimentary @@ -60,8 +75,12 @@ * discarded. If you need to get any debug information from your * destructor, use error_log(), syslog() or something similar. * + * IMPORTANT! To use the emulated destructors you need to create the + * objects by reference: $obj =& new PEAR_child; + * * @since PHP 4.0.2 - * @author Stig Bakken <ss...@fa...> + * @author Stig Bakken <ss...@ph...> + * @see http://pear.php.net/manual/ */ class PEAR { @@ -126,25 +145,29 @@ * $_PEAR_destructor_object_list for destructor emulation if a * destructor object exists. * - * @param string (optional) which class to use for error objects, - * defaults to PEAR_Error. + * @param string $error_class (optional) which class to use for + * error objects, defaults to PEAR_Error. * @access public * @return void */ function PEAR($error_class = null) { - $classname = get_class($this); + $classname = strtolower(get_class($this)); if ($this->_debug) { print "PEAR constructor called, class=$classname\n"; } if ($error_class !== null) { $this->_error_class = $error_class; } - while ($classname) { + while ($classname && strcasecmp($classname, "pear")) { $destructor = "_$classname"; if (method_exists($this, $destructor)) { global $_PEAR_destructor_object_list; $_PEAR_destructor_object_list[] = &$this; + if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { + register_shutdown_function("_PEAR_call_destructors"); + $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; + } break; } else { $classname = get_parent_class($classname); @@ -168,31 +191,81 @@ */ function _PEAR() { if ($this->_debug) { - printf("PEAR destructor called, class=%s\n", get_class($this)); + printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); } } // }}} + // {{{ getStaticProperty() + + /** + * If you have a class that's mostly/entirely static, and you need static + * properties, you can use this method to simulate them. Eg. in your method(s) + * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); + * You MUST use a reference, or they will not persist! + * + * @access public + * @param string $class The calling classname, to prevent clashes + * @param string $var The variable to retrieve. + * @return mixed A reference to the variable. If not set it will be + * auto initialised to NULL. + */ + function &getStaticProperty($class, $var) + { + static $properties; + return $properties[$class][$var]; + } + + // }}} + // {{{ registerShutdownFunc() + + /** + * Use this function to register a shutdown method for static + * classes. + * + * @access public + * @param mixed $func The function name (or array of class/method) to call + * @param mixed $args The arguments to pass to the function + * @return void + */ + function registerShutdownFunc($func, $args = array()) + { + $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); + } + + // }}} // {{{ isError() /** * Tell whether a value is a PEAR error. * - * @param mixed the value to test + * @param mixed $data the value to test + * @param int $code if $data is an error object, return true + * only if $code is a string and + * $obj->getMessage() == $code or + * $code is an integer and $obj->getCode() == $code * @access public * @return bool true if parameter is an error */ - function isError($data) { - return (bool)(is_object($data) && - (get_class($data) == 'pear_error' || - is_subclass_of($data, 'pear_error'))); + function isError($data, $code = null) + { + if (is_a($data, 'PEAR_Error')) { + if (is_null($code)) { + return true; + } elseif (is_string($code)) { + return $data->getMessage() == $code; + } else { + return $data->getCode() == $code; + } + } + return false; } // }}} // {{{ setErrorHandling() /** - * Sets how errors generated by this DB object should be handled. + * Sets how errors generated by this object should be handled. * Can be invoked both in objects and statically. If called * statically, setErrorHandling sets the default behaviour for all * PEAR objects. If called in an object, setErrorHandling sets @@ -200,8 +273,8 @@ * * @param int $mode * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, - * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE or - * PEAR_ERROR_CALLBACK. + * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, + * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION. * * @param mixed $options * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one @@ -225,23 +298,23 @@ * @see PEAR_ERROR_TRIGGER * @see PEAR_ERROR_DIE * @see PEAR_ERROR_CALLBACK + * @see PEAR_ERROR_EXCEPTION * * @since PHP 4.0.5 */ function setErrorHandling($mode = null, $options = null) { - if (isset($this)) { + if (isset($this) && is_a($this, 'PEAR')) { $setmode = &$this->_default_error_mode; $setoptions = &$this->_default_error_options; - //$setcallback = &$this->_default_error_callback; } else { $setmode = &$GLOBALS['_PEAR_default_error_mode']; $setoptions = &$GLOBALS['_PEAR_default_error_options']; - //$setcallback = &$GLOBALS['_PEAR_default_error_callback']; } switch ($mode) { + case PEAR_ERROR_EXCEPTION: case PEAR_ERROR_RETURN: case PEAR_ERROR_PRINT: case PEAR_ERROR_TRIGGER: @@ -253,9 +326,8 @@ case PEAR_ERROR_CALLBACK: $setmode = $mode; - if ((is_string($options) && function_exists($options)) || - (is_array($options) && method_exists(@$options[0], @$options[1]))) - { + // class/object method callback + if (is_callable($options)) { $setoptions = $options; } else { trigger_error("invalid error callback", E_USER_WARNING); @@ -279,12 +351,14 @@ * expected errors are in effect until they are popped off the * stack with the popExpect() method. * - * @param mixed a single error code or an array of error codes - * to expect + * Note that this method can not be called statically + * + * @param mixed $code a single error code or an array of error codes to expect * * @return int the new depth of the "expected errors" stack + * @access public */ - function expectError($code = "*") + function expectError($code = '*') { if (is_array($code)) { array_push($this->_expected_errors, $code); @@ -309,6 +383,76 @@ } // }}} + // {{{ _checkDelExpect() + + /** + * This method checks unsets an error code if available + * + * @param mixed error code + * @return bool true if the error code was unset, false otherwise + * @access private + * @since PHP 4.3.0 + */ + function _checkDelExpect($error_code) + { + $deleted = false; + + foreach ($this->_expected_errors AS $key => $error_array) { + if (in_array($error_code, $error_array)) { + unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); + $deleted = true; + } + + // clean up empty arrays + if (0 == count($this->_expected_errors[$key])) { + unset($this->_expected_errors[$key]); + } + } + return $deleted; + } + + // }}} + // {{{ delExpect() + + /** + * This method deletes all occurences of the specified element from + * the expected error codes stack. + * + * @param mixed $error_code error code that should be deleted + * @return mixed list of error codes that were deleted or error + * @access public + * @since PHP 4.3.0 + */ + function delExpect($error_code) + { + $deleted = false; + + if ((is_array($error_code) && (0 != count($error_code)))) { + // $error_code is a non-empty array here; + // we walk through it trying to unset all + // values + foreach($error_code as $key => $error) { + if ($this->_checkDelExpect($error)) { + $deleted = true; + } else { + $deleted = false; + } + } + return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME + } elseif (!empty($error_code)) { + // $error_code comes alone, trying to unset it + if ($this->_checkDelExpect($error_code)) { + return true; + } else { + return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME + } + } else { + // $error_code is empty + return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME + } + } + + // }}} // {{{ raiseError() /** @@ -317,16 +461,16 @@ * handling applied. If the $mode and $options parameters are not * specified, the object's defaults are used. * - * @param $message a text error message or a PEAR error object + * @param mixed $message a text error message or a PEAR error object * - * @param $code a numeric error code (it is up to your class + * @param int $code a numeric error code (it is up to your class * to define these if you want to use codes) * - * @param $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, - * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE or - * PEAR_ERROR_CALLBACK. + * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, + * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, + * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. * - * @param $options If $mode is PEAR_ERROR_TRIGGER, this parameter + * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter * specifies the PHP-internal error level (one of * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). * If $mode is PEAR_ERROR_CALLBACK, this @@ -334,13 +478,13 @@ * method. In other error modes this parameter * is ignored. * - * @param $userinfo If you need to pass along for example debug + * @param string $userinfo If you need to pass along for example debug * information, this parameter is meant for that. * - * @param $error_class The returned error object will be instantiated - * from this class, if specified. + * @param string $error_class The returned error object will be + * instantiated from this class, if specified. * - * @param $skipmsg If true, raiseError will only pass error codes, + * @param bool $skipmsg If true, raiseError will only pass error codes, * the error message parameter will be dropped. * * @access public @@ -348,7 +492,7 @@ * @see PEAR::setErrorHandling * @since PHP 4.0.5 */ - function &raiseError($message = null, + function raiseError($message = null, $code = null, $mode = null, $options = null, @@ -361,6 +505,7 @@ $code = $message->getCode(); $userinfo = $message->getUserInfo(); $error_class = $message->getType(); + $message->error_message_prefix = ''; $message = $message->getMessage(); } @@ -371,47 +516,19 @@ $mode = PEAR_ERROR_RETURN; } } - + // No mode given, try global ones if ($mode === null) { + // Class error handler if (isset($this) && isset($this->_default_error_mode)) { - $mode = $this->_default_error_mode; - } else { - $mode = $GLOBALS['_PEAR_default_error_mode']; - } - } - - if ($mode == PEAR_ERROR_TRIGGER && $options === null) { - if (isset($this)) { - if (isset($this->_default_error_options)) { - $options = $this->_default_error_options; - } - } else { + $mode = $this->_default_error_mode; + $options = $this->_default_error_options; + // Global error handler + } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { + $mode = $GLOBALS['_PEAR_default_error_mode']; $options = $GLOBALS['_PEAR_default_error_options']; } } - if ($mode == PEAR_ERROR_CALLBACK) { - if (!is_string($options) && - !(is_array($options) && sizeof($options) == 2 && - is_object($options[0]) && is_string($options[1]))) - { - if (isset($this) && isset($this->_default_error_options)) { - $options = $this->_default_error_options; - } else { - $options = $GLOBALS['_PEAR_default_error_options']; - } - } - } else { - if ($options === null) { - if (isset($this)) { - if (isset($this->_default_error_options)) { - $options = $this->_default_error_options; - } - } else { - $options = $GLOBALS['_PEAR_default_error_options']; - } - } - } if ($error_class !== null) { $ec = $error_class; } elseif (isset($this) && isset($this->_error_class)) { @@ -427,40 +544,125 @@ } // }}} + // {{{ throwError() + + /** + * Simpler form of raiseError with fewer options. In most cases + * message, code and userinfo are enough. + * + * @param string $message + * + */ + function throwError($message = null, + $code = null, + $userinfo = null) + { + if (isset($this) && is_a($this, 'PEAR')) { + return $this->raiseError($message, $code, null, null, $userinfo); + } else { + return PEAR::raiseError($message, $code, null, null, $userinfo); + } + } + + // }}} + function staticPushErrorHandling($mode, $options = null) + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + $def_mode = &$GLOBALS['_PEAR_default_error_mode']; + $def_options = &$GLOBALS['_PEAR_default_error_options']; + $stack[] = array($def_mode, $def_options); + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $def_mode = $mode; + $def_options = $options; + break; + + case PEAR_ERROR_CALLBACK: + $def_mode = $mode; + // class/object method callback + if (is_callable($options)) { + $def_options = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + $stack[] = array($mode, $options); + return true; + } + + function staticPopErrorHandling() + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + $setmode = &$GLOBALS['_PEAR_default_error_mode']; + $setoptions = &$GLOBALS['_PEAR_default_error_options']; + array_pop($stack); + list($mode, $options) = $stack[sizeof($stack) - 1]; + array_pop($stack); + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $setmode = $mode; + $setoptions = $options; + break; + + case PEAR_ERROR_CALLBACK: + $setmode = $mode; + // class/object method callback + if (is_callable($options)) { + $setoptions = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + return true; + } + // {{{ pushErrorHandling() /** - * Push a new error handler on top of the error handler options stack. With this - * you can easily override the actual error handler for some code and restore - * it later with popErrorHandling. - * - * @param $mode mixed (same as setErrorHandling) - * @param $options mixed (same as setErrorHandling) - * - * @return bool Always true - * - * @see PEAR::setErrorHandling - */ + * Push a new error handler on top of the error handler options stack. With this + * you can easily override the actual error handler for some code and restore + * it later with popErrorHandling. + * + * @param mixed $mode (same as setErrorHandling) + * @param mixed $options (same as setErrorHandling) + * + * @return bool Always true + * + * @see PEAR::setErrorHandling + */ function pushErrorHandling($mode, $options = null) { $stack = &$GLOBALS['_PEAR_error_handler_stack']; - if (!is_array($stack)) { - if (isset($this)) { - $def_mode = &$this->_default_error_mode; - $def_options = &$this->_default_error_options; - // XXX Used anywhere? - //$def_callback = &$this->_default_error_callback; - } else { - $def_mode = &$GLOBALS['_PEAR_default_error_mode']; - $def_options = &$GLOBALS['_PEAR_default_error_options']; - // XXX Used anywhere? - //$def_callback = &$GLOBALS['_PEAR_default_error_callback']; - } - $stack = array(); - $stack[] = array($def_mode, $def_options); + if (isset($this) && is_a($this, 'PEAR')) { + $def_mode = &$this->_default_error_mode; + $def_options = &$this->_default_error_options; + } else { + $def_mode = &$GLOBALS['_PEAR_default_error_mode']; + $def_options = &$GLOBALS['_PEAR_default_error_options']; } + $stack[] = array($def_mode, $def_options); - if (isset($this)) { + if (isset($this) && is_a($this, 'PEAR')) { $this->setErrorHandling($mode, $options); } else { PEAR::setErrorHandling($mode, $options); @@ -484,7 +686,8 @@ $stack = &$GLOBALS['_PEAR_error_handler_stack']; array_pop($stack); list($mode, $options) = $stack[sizeof($stack) - 1]; - if (isset($this)) { + array_pop($stack); + if (isset($this) && is_a($this, 'PEAR')) { $this->setErrorHandling($mode, $options); } else { PEAR::setErrorHandling($mode, $options); @@ -493,6 +696,39 @@ } // }}} + // {{{ loadExtension() + + /** + * OS independant PHP extension load. Remember to take care + * on the correct extension name for case sensitive OSes. + * + * @param string $ext The extension name + * @return bool Success or not on the dl() call + */ + function loadExtension($ext) + { + if (!extension_loaded($ext)) { + // if either returns true dl() will produce a FATAL error, stop that + if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) { + return false; + } + if (OS_WINDOWS) { + $suffix = '.dll'; + } elseif (PHP_OS == 'HP-UX') { + $suffix = '.sl'; + } elseif (PHP_OS == 'AIX') { + $suffix = '.a'; + } elseif (PHP_OS == 'OSX') { + $suffix = '.bundle'; + } else { + $suffix = '.so'; + } + return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); + } + return true; + } + + // }}} } // {{{ _PEAR_call_destructors() @@ -504,6 +740,9 @@ sizeof($_PEAR_destructor_object_list)) { reset($_PEAR_destructor_object_list); + if (@PEAR::getStaticProperty('PEAR', 'destructlifo')) { + $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); + } while (list($k, $objref) = each($_PEAR_destructor_object_list)) { $classname = get_class($objref); while ($classname) { @@ -520,6 +759,13 @@ // not called more than once. $_PEAR_destructor_object_list = array(); } + + // Now call the shutdown functions + if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) { + foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { + call_user_func_array($value[0], $value[1]); + } + } } // }}} @@ -534,11 +780,7 @@ var $code = -1; var $message = ''; var $userinfo = ''; - - // Wait until we have a stack-groping function in PHP. - //var $file = ''; - //var $line = 0; - + var $backtrace = null; // }}} // {{{ constructor @@ -546,18 +788,20 @@ /** * PEAR_Error constructor * - * @param $message error message + * @param string $message message * - * @param $code (optional) error code + * @param int $code (optional) error code * - * @param $mode (optional) error mode, one of: PEAR_ERROR_RETURN, - * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER or - * PEAR_ERROR_CALLBACK + * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, + * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER, + * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION * - * @param $level (optional) error level, _OR_ in the case of + * @param mixed $options (optional) error level, _OR_ in the case of * PEAR_ERROR_CALLBACK, the callback function or object/method * tuple. * + * @param string $userinfo (optional) additional user/debug info + * * @access public * */ @@ -571,6 +815,11 @@ $this->code = $code; $this->mode = $mode; $this->userinfo = $userinfo; + if (function_exists("debug_backtrace")) { + if (@!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) { + $this->backtrace = debug_backtrace(); + } + } if ($mode & PEAR_ERROR_CALLBACK) { $this->level = E_USER_NOTICE; $this->callback = $options; @@ -605,17 +854,14 @@ die(sprintf($format, $msg)); } if ($this->mode & PEAR_ERROR_CALLBACK) { - if (is_string($this->callback) && strlen($this->callback)) { + if (is_callable($this->callback)) { call_user_func($this->callback, $this); - } elseif (is_array($this->callback) && - sizeof($this->callback) == 2 && - is_object($this->callback[0]) && - is_string($this->callback[1]) && - strlen($this->callback[1])) { - @call_user_method($this->callback[1], $this->callback[0], - $this); } } + if ($this->mode & PEAR_ERROR_EXCEPTION) { + trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_ErrorStack for exceptions", E_USER_WARNING); + eval('$e = new Exception($this->message, $this->code);$e->PEAR_Error = $this;throw($e);'); + } } // }}} @@ -654,7 +900,7 @@ * @return string full error message * @access public */ - function getMessage () + function getMessage() { return ($this->error_message_prefix . $this->message); } @@ -683,7 +929,7 @@ * @return string error/exception name (type) * @access public */ - function getType () + function getType() { return get_class($this); } @@ -697,7 +943,7 @@ * @return string user-supplied information * @access public */ - function getUserInfo () + function getUserInfo() { return $this->userinfo; } @@ -711,12 +957,31 @@ * @return string debug information * @access public */ - function getDebugInfo () + function getDebugInfo() { return $this->getUserInfo(); } // }}} + // {{{ getBacktrace() + + /** + * Get the call backtrace from where the error was generated. + * Supported with PHP 4.3.0 or newer. + * + * @param int $frame (optional) what frame to fetch + * @return array Backtrace, or NULL if not available. + * @access public + */ + function getBacktrace($frame = null) + { + if ($frame === null) { + return $this->backtrace; + } + return $this->backtrace[$frame]; + } + + // }}} // {{{ addUserInfo() function addUserInfo($info) @@ -744,20 +1009,19 @@ E_USER_ERROR => 'error'); if ($this->mode & PEAR_ERROR_CALLBACK) { if (is_array($this->callback)) { - $callback = get_class($this->callback[0]) . '::' . + $callback = (is_object($this->callback[0]) ? + strtolower(get_class($this->callback[0])) : + $this->callback[0]) . '::' . $this->callback[1]; } else { $callback = $this->callback; } return sprintf('[%s: message="%s" code=%d mode=callback '. 'callback=%s prefix="%s" info="%s"]', - get_class($this), $this->message, $this->code, + strtolower(get_class($this)), $this->message, $this->code, $callback, $this->error_message_prefix, $this->userinfo); } - if ($this->mode & PEAR_ERROR_CALLBACK) { - $modes[] = 'callback'; - } if ($this->mode & PEAR_ERROR_PRINT) { $modes[] = 'print'; } @@ -772,7 +1036,7 @@ } return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. 'prefix="%s" info="%s"]', - get_class($this), $this->message, $this->code, + strtolower(get_class($this)), $this->message, $this->code, implode("|", $modes), $levels[$this->level], $this->error_message_prefix, $this->userinfo); @@ -781,8 +1045,6 @@ // }}} } -register_shutdown_function("_PEAR_call_destructors"); - /* * Local Variables: * mode: php |
|
From: Ulf E. <ulf...@fa...> - 2005-05-23 14:42:11
|
* Ben Curtis [2005-05-19 17:34]: > Any of the patches you already made that add pieces of functionality are > fine to add. I'd rather not put in patches that are for mysql only, > though. I can help with making them work with postgres, but I'm sorely > lacking in time lately. Great. I'll take a look at my old feature patches as well. By the end of the week, I hope. > > Do you have a list of blocking bugs for 1.0? Why was RC5 named RC5 and > > not 1.0? Are those issues addressed now? What is needed for RC6 and/or > > 1.0? How can I best help reach there? > > > > Actually, I don't have a list of blocking issues. I think the code is > basically ready to go for a 1.0 release. Of course, I could be > forgetting something. :) I'd rather do 1.0 than RC6. I think the only > thing holding me back is really someone (besides me) giving me the > thumbs up that the upgrade script works just fine for a 0.9.x database. Hmm.. There have actually been a number of tumbs down for installer and upgrade scripts lately.. I suspect that this partly could be due to newer versions of php and/or mysql. I'll try to come up with something there (including the error and warning log we talked about earlier). How about a wiki page to collect information about systems where install and upgrade work or fail (and error messages, in case of failure)? If you write a short description on how to test this anyone can fill in his system specifics and results. And, if you write the first entry everyone will include as much information. I wouldn't know what parameters are of importance ;-) /Ulf |
|
From: Ben C. <php...@be...> - 2005-05-20 00:34:45
|
Ulf Erikson wrote: > * Benjamin Curtis [2005-05-14 12:54]: > >>I think the only reason the patches haven't been applied is that the >>time just slipped by me. To correct that, I've added you as a developer >>to the project so you can add your patches yourself. :) Changes should >>be applied to the HEAD. > > > What a dirty trick! ;-) It is soo much easier to complain than to fix it > myself.. but I will try to look at it, next week or so. > > Could you at least give a hint on what patches are okay to add now and > what can better wait until after 1.0? > Heh, good working tossing it back. :) > >>I don't have a desire to add any more features before 1.0, I just want >>work out any remaining bugs left over from the RCs. > > > Sounds wise. I guess this means that it is too late for changes to > things such as the database structure, the main queries and the > translatable strings, etc.? That would disqualify most of my patches for > now.. Another thing, some of my changes are for MySQL only. Who can help > with similar changes for the other database types? (do you normally > commit changes for one type only and add the others later? or do you > wait until changes for all types can be done at once?) Any of the patches you already made that add pieces of functionality are fine to add. I'd rather not put in patches that are for mysql only, though. I can help with making them work with postgres, but I'm sorely lacking in time lately. > > Do you have a list of blocking bugs for 1.0? Why was RC5 named RC5 and > not 1.0? Are those issues addressed now? What is needed for RC6 and/or > 1.0? How can I best help reach there? > Actually, I don't have a list of blocking issues. I think the code is basically ready to go for a 1.0 release. Of course, I could be forgetting something. :) I'd rather do 1.0 than RC6. I think the only thing holding me back is really someone (besides me) giving me the thumbs up that the upgrade script works just fine for a 0.9.x database. |
|
From: Ulf E. <ulf...@fa...> - 2005-05-17 12:34:58
|
* Benjamin Curtis [2005-05-14 12:54]: > I think the only reason the patches haven't been applied is that the > time just slipped by me. To correct that, I've added you as a developer > to the project so you can add your patches yourself. :) Changes should > be applied to the HEAD. What a dirty trick! ;-) It is soo much easier to complain than to fix it myself.. but I will try to look at it, next week or so. Could you at least give a hint on what patches are okay to add now and what can better wait until after 1.0? > I don't have a desire to add any more features before 1.0, I just want > work out any remaining bugs left over from the RCs. Sounds wise. I guess this means that it is too late for changes to things such as the database structure, the main queries and the translatable strings, etc.? That would disqualify most of my patches for now.. Another thing, some of my changes are for MySQL only. Who can help with similar changes for the other database types? (do you normally commit changes for one type only and add the others later? or do you wait until changes for all types can be done at once?) Do you have a list of blocking bugs for 1.0? Why was RC5 named RC5 and not 1.0? Are those issues addressed now? What is needed for RC6 and/or 1.0? How can I best help reach there? -- Ulf |
|
From: Benjamin C. <php...@be...> - 2005-05-14 19:47:42
|
I think the only reason the patches haven't been applied is that the time just slipped by me. To correct that, I've added you as a developer to the project so you can add your patches yourself. :) Changes should be applied to the HEAD. I don't have a desire to add any more features before 1.0, I just want work out any remaining bugs left over from the RCs. Ulf Erikson wrote: > Benjamin, > > Could you please update the RoadMap to show what features actually went > into 0.9, what curently sit in 1.0rc and what you plan to include for > 1.0final? I'd try to help with a thing or two if I knew where you're > going.. til now I have not heard much about if/when (or why not) my > earlier set of patches will get included. The good thing with this slow > pace is that they probably still apply ;-) > > /Ulf > > * Benjamin Curtis [2005-05-12 15:26]: > >> The current goal is to get 1.0 released in July. >> >> Matthieu Pupat wrote: >> >>> Hello, >>> >>> What is the sate of PHPBT. It has been in rc5 for months and nothing >>> seems to change. Is a 1.0final planned ? >>> >>> Thanks, > > > > ------------------------------------------------------- > This SF.Net email is sponsored by Oracle Space Sweepstakes > Want to be the first software developer in space? > Enter now for the Oracle Space Sweepstakes! > http://ads.osdn.com/?ad_id=7393&alloc_id=16281&op=click > _______________________________________________ > phpbt-dev mailing list > php...@li... > https://lists.sourceforge.net/lists/listinfo/phpbt-dev |
|
From: Ulf E. <ulf...@fa...> - 2005-05-12 18:01:33
|
Benjamin, Could you please update the RoadMap to show what features actually went into 0.9, what curently sit in 1.0rc and what you plan to include for 1.0final? I'd try to help with a thing or two if I knew where you're going.. til now I have not heard much about if/when (or why not) my earlier set of patches will get included. The good thing with this slow pace is that they probably still apply ;-) /Ulf * Benjamin Curtis [2005-05-12 15:26]: > The current goal is to get 1.0 released in July. > > Matthieu Pupat wrote: > >> Hello, >> >>What is the sate of PHPBT. It has been in rc5 for months and nothing >>seems to change. Is a 1.0final planned ? >> >> Thanks, |
|
From: Benjamin C. <php...@be...> - 2005-05-12 13:20:24
|
The current goal is to get 1.0 released in July. Matthieu Pupat wrote: > Hello, > > What is the sate of PHPBT. It has been in rc5 for months and nothing > seems to change. Is a 1.0final planned ? > > Thanks, > |
|
From: Matthieu P. <mat...@dp...> - 2005-05-12 07:24:43
|
Hello, What is the sate of PHPBT. It has been in rc5 for months and nothing seems to change. Is a 1.0final planned ? Thanks, -- Matthieu PUPAT Digital Product Simulation Téléphone : +33 (0)5 62 12 03 87 (interne 7013) Fax : +33 (0)5 62 12 03 89 |
|
From: Michael C. Jr. <mi...@mi...> - 2005-03-23 23:39:02
|
After I complete an install and all goes well, I get this message when I hit the root install dir from IE Warning: session_start(): Cannot send session cookie - headers already sent by (output started at /home/.sites/45/site74/web/bt/config.php:74) in /home/.sites/45/site74/web/bt/include.php on line 153 Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at /home/.sites/45/site74/web/bt/config.php:74) in /home/.sites/45/site74/web/bt/include.php on line 153 Then I get what appears the normal BT login - the PHPBUGTRACKER banner page, asking for email and password, then it lists 5 most recent bugs no bugs found, etc. Please help -- Michael Cupp, Jr. mi...@mi... |
|
From: Benjamin C. <php...@be...> - 2005-03-10 13:31:34
|
A popup or an iframe could be used to log the queries, to keep it separate from the main output. Ulf Erikson wrote: > Hoi, > > There are two fairly new threads about failures with upgrading: > http://sourceforge.net/forum/message.php?msg_id=2664123 > http://sourceforge.net/forum/message.php?msg_id=3000998 > > Both reports indicate that upgrade.php doesn't change the database as > intended, and one of them that the problem is that v0.9 doesn't have a > DB_VERSION field. > > My first attempt would be to count the number of fields before querying > for the DB_VERSION. (just in case it is possible to have a setup that > throws an error or returns a big positive "value" when the field doesn't > exists) > > My next suggestion would be to log all queries and replies. That would > make it quite simple to spot any issues of this kind. You probably want > something similar for install.php. > > The alternative upgrade.php attached implements these two ideas. > Unfortunately is a full log a bit too much text.. Your comment about > manually changes needed for closed states gets a bit lost. Somewhat > better might be to show the log in a textarea but only if there has been > an error? Still I think a log would greatly help debugging this issue. > > Thoughts? Comments? > > > ------------------------------------------------------------------------ > > "; echo htmlentities($obj->message).' > '.htmlentities($obj->userinfo); echo "\n"; } function log_query($str) { > global $db; echo "\t\t\tSQL: " . $str . " > \n"; $result = $db->query($str); if (DB::isError($result)) { echo > "\t\t\t" . DB::errorMessage($result) . " > \n"; } echo "\t\t\t > \n"; } function upgrade() { global $db; echo "\n"; echo "\t\n"; echo > "\t\t\n"; echo "\t\t\n"; echo "\t\n"; echo "\t\n"; echo "\t\t > \n"; echo "\t\t\t > \n"; echo "\t\t\t".translate("Your database is being updated.")."\n"; > echo "\t\t\t > \n"; echo "\t\t\t > \n"; $db->setErrorHandling(PEAR_ERROR_CALLBACK, "handle_upgrade_error"); > $thisvers = 0; echo "\t\t\tSQL: select count(*) from ".TBL_CONFIGURATION." > \n"; $count = $db->getOne('select count(*) from '.TBL_CONFIGURATION); > echo "\t\t\tcount = $count > > \n"; if ($count > 30) { echo "\t\t\tSQL: select varvalue from > ".TBL_CONFIGURATION." where varname = 'DB_VERSION' > \n"; $thisvers = $db->getOne('select varvalue from '.TBL_CONFIGURATION.' > where varname = \'DB_VERSION\''); if (DB::isError($thisvers)) { echo > DB::errorMessage($thisvers) . " > "; $thisvers = 0; } } echo "\t\t\tCurrent DB version = $thisvers > \n"; echo "\t\t\tUpgrading to version = ".CUR_DB_VERSION." > \n"; echo "\t\t\t > \n"; if ($thisvers == CUR_DB_VERSION) $upgraded = 1; if (!$upgraded) { > switch(DB_TYPE) { case 'pgsql' : log_query("create table > ".TBL_PROJECT_PERM." ( project_id INT4 NOT NULL DEFAULT '0', user_id > INT4 NOT NULL DEFAULT '0' )"); if ($thisvers < 2) { log_query("alter > table ".TBL_AUTH_GROUP." ADD assignable INT2"); log_query("alter table > ".TBL_AUTH_GROUP." alter assignable set DEFAULT 0"); log_query("update > ".TBL_AUTH_GROUP." set assignable = 0"); log_query("alter table > ".TBL_AUTH_GROUP." alter assignable set NOT NULL"); } if ($thisvers < 3) > { log_query("ALTER TABLE ".TBL_USER_PREF." ADD def_results INT4"); > log_query("ALTER TABLE ".TBL_USER_PREF." alter def_results set DEFAULT > 20"); log_query("update ".TBL_USER_PREF." set def_results = 20"); > log_query("ALTER TABLE ".TBL_USER_PREF." alter def_results set NOT > NULL"); } if ($thisvers < 4) { log_query('ALTER TABLE '.TBL_STATUS.' ADD > bug_open INT2'); log_query("ALTER TABLE ".TBL_STATUS." alter bug_open > set DEFAULT 1"); log_query("update ".TBL_STATUS." set bug_open = 1"); > log_query("ALTER TABLE ".TBL_STATUS." alter bug_open set NOT NULL"); } > break; case 'mysql' : log_query("create table if not exists > ".TBL_PROJECT_PERM." ( project_id int(11) NOT NULL default '0', user_id > int(11) NOT NULL default '0' )"); if ($thisvers < 2) { log_query("alter > table ".TBL_AUTH_GROUP." ADD assignable TINYINT DEFAULT 0 NOT NULL AFTER > locked"); } if ($thisvers < 3) { log_query("ALTER TABLE > ".TBL_USER_PREF." ADD def_results INT DEFAULT '20' NOT NULL"); } if > ($thisvers < 4) { log_query('ALTER TABLE '.TBL_STATUS.' ADD bug_open > TINYINT DEFAULT \'1\' NOT NULL'); } break; case 'oci8' : echo "Oracle is > not supported in version 1.0"; exit; log_query("create table > ".TBL_PROJECT_PERM." ( project_id number(10) default '0' NOT NULL, > user_id number(10) default '0' NOT NULL )"); //! TBL_AUTH_GROUP //! > TBL_USER_PERM.def_results (see mysql) break; } /** Database-independent > changes */ if ($thisvers < 2) { log_query("DELETE FROM > ".TBL_CONFIGURATION." WHERE varname = 'GROUP_ASSIGN_TO'"); > log_query("UPDATE ".TBL_AUTH_GROUP." SET assignable = 1 WHERE group_id = > 3"); log_query("INSERT INTO ".TBL_CONFIGURATION." VALUES > ('EMAIL_DISABLED', '0', 'Whether to disable all mail sent from the > system', 'bool');"); /* add db-version attribute */ log_query("INSERT > INTO ".TBL_CONFIGURATION." VALUES ('DB_VERSION', > '".(int)CUR_DB_VERSION."', 'Database Version *Warning:* Changing this > might make things go horribly wrong.', 'string')"); } if ($thisvers < 4) > { log_query('DELETE FROM '.TBL_CONFIGURATION.' WHERE varname = > \'BUG_CLOSED\''); echo "\t\t\tYou must set your Statuses to either open > or closed. Default settings should be modified so that \"resolved\", > \"closed\", and \"verified\" are shown as being closed, and all other > statuses are set to open. > > \n"; log_query("INSERT INTO ".TBL_AUTH_PERM." (perm_id, perm_name) > VALUES (3, 'EditAssignment')"); } /* update to current DB_VERSION */ > log_query("UPDATE ".TBL_CONFIGURATION." SET varvalue = > '".CUR_DB_VERSION."' WHERE varname = 'DB_VERSION'"); echo "\t\t\t > \n"; echo "\t\t\t".translate("Done!")."\n"; echo "\t\t\t > \n"; } else { echo "\t\t\t > \n"; echo "\t\t\t".translate("Nothing to do.")."\n"; echo "\t\t\t > \n"; } echo "\t\t > \n"; echo "\t\t".translate("phpBugTracker home")." <\"index.php\">\n"; > echo "\t\t > \n"; echo "\t\n"; echo "\n"; } if (isset($_GET['doit'])) { upgrade(); } > else { include 'templates/default/upgrade.html'; } ?> |
|
From: Ulf E. <ulf...@fa...> - 2005-03-08 21:19:17
|
Hoi, There are two fairly new threads about failures with upgrading: http://sourceforge.net/forum/message.php?msg_id=2664123 http://sourceforge.net/forum/message.php?msg_id=3000998 Both reports indicate that upgrade.php doesn't change the database as intended, and one of them that the problem is that v0.9 doesn't have a DB_VERSION field. My first attempt would be to count the number of fields before querying for the DB_VERSION. (just in case it is possible to have a setup that throws an error or returns a big positive "value" when the field doesn't exists) My next suggestion would be to log all queries and replies. That would make it quite simple to spot any issues of this kind. You probably want something similar for install.php. The alternative upgrade.php attached implements these two ideas. Unfortunately is a full log a bit too much text.. Your comment about manually changes needed for closed states gets a bit lost. Somewhat better might be to show the log in a textarea but only if there has been an error? Still I think a log would greatly help debugging this issue. Thoughts? Comments? -- Ulf |