Autarchy of the Private Cave

Science, Society, Programming and Hobbies

  • Exits

  • Categories

  • Archives

  • Visitors' track

    Locations of visitors to this page
  • Tags list

    • Web Hosting

    • Blog sponsors

    • Earn and spend


    • Exits

    • Ratings

      Science Blogs - Blog Top Sites website monitoring service

    dotProject 2.0.4 on GoDaddy.com shared hosting

    22nd January 2007

    In one of my recent posts about project management software I stated the desire to extensively test dotProject 2.0.4. However, GoDaddy.com shared hosting appears incompatible with dotProject: the right to CREATE TEMPORARY TABLES in MySQL is not granted, but is needed by dotProject.

    Here's sample error:

    query failed(CREATE TEMPORARY TABLE tasks_sum SELECT task_project, COUNT(distinct task_id) AS total_tasks,
    SUM(task_duration * task_percent_complete * IF(task_duration_type = 24, 8.0, task_duration_type))/
    SUM(task_duration * IF(task_duration_type = 24, 8.0, task_duration_type)) AS project_percent_complete FROM `tasks` GROUP BY task_project)

    I tried looking for solutions, and here's what I found...

    First of all, I tried issuing the "grant" command to try enabling temporary tables:

    GRANT CREATE TEMPORARY TABLES ON dot_projects.* to dot_projects@mysql123.secureserver.net;

    Expectedly, this didn't work: "access denied for user ....".

    Then I tried looking for a ready-to-apply solution. Here are the links relevant to the topic, if you happen to prefer "the source", and not the retelling: link 1, link 2, link 3, link 4, link 5.

    What should have helped, according to all that reading:

    1. download this file
    2. replace your /modules/project/index.php with the downloaded file, and
    3. you're done!it didn't work, read below

    What we need to do: instead of creating temporary tables each time they are needed (what is impossible on GoDaddy shared hosting), we need to create the necessary tables once. Then, instead of dropping temporary tables, we just truncate our "static" tables.

    Here's how we proceed.

    1. Issue once the following MySQL statements (using, e.g., phpMyAdmin):
    (click the "PLAIN TEXT" box headers for the "copy-paste"-able plain text versions)

    SQL:
    1. CREATE TABLE IF NOT EXISTS `tasks_problems` (
    2. `task_project` INT( 11 ) DEFAULT NULL ,
    3. `task_log_problem` TINYINT(1) DEFAULT NULL
    4. ) TYPE=MyISAM;
    5.  
    6. CREATE TABLE IF NOT EXISTS `tasks_critical` (
    7. `task_project` INT( 11 ) DEFAULT NULL ,
    8. `critical_task` INT( 11 ) DEFAULT NULL ,
    9. `project_actual_end_date` DATETIME DEFAULT NULL
    10. ) TYPE=MyISAM;
    11.  
    12.  
    13. CREATE TABLE IF NOT EXISTS `tasks_sum` (
    14. `task_project` INT( 11 ) DEFAULT NULL ,
    15. `total_tasks` INT( 6 ) DEFAULT NULL ,
    16. `project_percent_complete` VARCHAR( 11 ) DEFAULT NULL,
    17. `project_duration` VARCHAR( 11 ) DEFAULT NULL
    18. ) TYPE=MyISAM;
    19.  
    20. CREATE TABLE IF NOT EXISTS `tasks_summy` (
    21. `task_project` INT(11) DEFAULT NULL,
    22. `my_tasks` varchar(10) DEFAULT NULL
    23. ) TYPE=MyISAM;
    24.  
    25. CREATE TABLE IF NOT EXISTS `tasks_users` (
    26. `task_project` INT(11) DEFAULT NULL,
    27. `user_id` INT(11) DEFAULT NULL
    28. ) TYPE=MyISAM;

    This creates all the necessary tables.

    Now,
    in classes/query.class.php at line 393 (dotProject 2.0.4, or search for the matching line)
    comment out this line:

    PHP:
    1. $q = 'CREATE TEMPORARY TABLE ' . $this->_table_prefix . $this->create_table;

    so it reads:

    PHP:
    1. //$q = 'CREATE TEMPORARY TABLE ' . $this->_table_prefix . $this->create_table;

    Now we won't get any errors about the tables which fail to be created.

    Next... I noticed that despite replacing the index.php file (with the one from the "should have worked" list), which replaces "dropTable" with truncate requests, tables still disappear.

    I found that most of the functions from index.php in 2.0.4 are taken out to projects.class.php, and that is where the tables are deleted. Thus, index.php file with fixes is no longer a valid solution :(

    I restored original index.php, and replaced the following text in projects.class.php (lines 388-392):

    PHP:
    1. // Let's delete temproary tables
    2.     $q  = new DBQuery;
    3.     $q->dropTemp('tasks_sum, tasks_summy, tasks_critical, tasks_problems, tasks_users');
    4.     $q->exec();
    5.     $q->clear();

    with this:

    PHP:
    1. // Let's delete temporary tables
    2.     $sql = "TRUNCATE TABLE tasks_sum";
    3.     db_exec($sql);
    4.     $sql = "TRUNCATE TABLE tasks_summy";
    5.     db_exec($sql);
    6.     $sql = "TRUNCATE TABLE tasks_critical";
    7.     db_exec($sql);
    8.     $sql = "TRUNCATE TABLE tasks_problems";
    9.     db_exec($sql);
    10.     $sql = "TRUNCATE TABLE tasks_users";
    11.     db_exec($sql);
    12.  
    13.     $q  = new DBQuery;

    At this point, I no longer received error messages while on the "projects" tab. However, I'm still unsure how this code in projects.class.php on lines 409-471 works with the createTemp commented out in query.php:

    PHP:
    1. // GJB: Note that we have to special case duration type 24 and this refers to the hours in a day, NOT 24 hours
    2.     $q->createTemp('tasks_sum');
    3.     $q->addTable('tasks');
    4.     $q->addQuery("task_project, COUNT(distinct tasks.task_id) AS total_tasks,
    5.             SUM(task_duration * task_percent_complete * IF(task_duration_type = 24, ".$working_hours.", task_duration_type))/
    6.             SUM(task_duration * IF(task_duration_type = 24, ".$working_hours.", task_duration_type)) AS project_percent_complete, SUM(task_duration * IF(task_duration_type = 24, ".$working_hours.", task_duration_type)) AS project_duration");
    7.     if ($user_id) {
    8.         $q->addJoin('user_tasks', 'ut', 'ut.task_id = tasks.task_id');
    9.         $q->addWhere('ut.user_id = '.$user_id);
    10.     }
    11.     $q->addGroup('task_project');
    12.     $tasks_sum = $q->exec();
    13.     $q->clear();
    14.  
    15.     // temporary My Tasks
    16.     // by Pablo Roca (pabloroca@mvps.org)
    17.     // 16 August 2003
    18.     $q->createTemp('tasks_summy');
    19.     $q->addTable('tasks');
    20.     $q->addQuery('task_project, COUNT(distinct task_id) AS my_tasks');
    21.     if ($user_id) {
    22.         $q->addWhere('task_owner = '.$user_id);
    23.     } else {
    24.         $q->addWhere('task_owner = '.$AppUI->user_id);
    25.     }
    26.     $q->addGroup('task_project');
    27.     $tasks_summy = $q->exec();
    28.     $q->clear();
    29.  
    30.     // temporary critical tasks
    31.     $q->createTemp('tasks_critical');
    32.     $q->addTable('tasks');
    33.     $q->addQuery('task_project, task_id AS critical_task, MAX(task_end_date) AS project_actual_end_date');
    34.     $q->addJoin('projects', 'p', 'p.project_id = task_project');
    35.     $q->addOrder("task_end_date DESC");
    36.     $q->addGroup('task_project');
    37.     $tasks_critical = $q->exec();
    38.     $q->clear();
    39.  
    40.     // temporary task problem logs
    41.     $q->createTemp('tasks_problems');
    42.     $q->addTable('tasks');
    43.     $q->addQuery('task_project, task_log_problem');
    44.     $q->addJoin('task_log', 'tl', 'tl.task_log_task = task_id');
    45.     $q->addWhere("task_log_problem> '0'");
    46.     $q->addGroup('task_project');
    47.     $tasks_problems = $q->exec();
    48.     $q->clear();
    49.  
    50.     if ($addProjectsWithAssignedTasks) {
    51.     // temporary users tasks
    52.     $q->createTemp('tasks_users');
    53.     $q->addTable('tasks');
    54.     $q->addQuery('task_project');
    55.     $q->addQuery('ut.user_id');
    56.     $q->addJoin('user_tasks', 'ut', 'ut.task_id = tasks.task_id');
    57.     if ($user_id) {
    58.         $q->addWhere('ut.user_id = '.$user_id);
    59.     }
    60.     $q->addOrder("task_end_date DESC");
    61.     $q->addGroup('task_project');
    62.     $tasks_users = $q->exec();
    63.     $q->clear();

    UPDATE: I decided to slightly improve the performance of dotProject specifically in this case. So I changed the 'engine' for the above-mentioned tables to 'memory'. If you followed this post, you now may want to issue the following SQL statements:

    SQL:
    1. ALTER TABLE tasks_problems engine=memory;
    2. ALTER TABLE tasks_critical engine=memory;
    3. ALTER TABLE tasks_sum engine=memory;
    4. ALTER TABLE tasks_summy engine=memory;
    5. ALTER TABLE tasks_users engine=memory;

    This change will make MySQL keep those tables in RAM. As they are used as temporary tables, this decreases disk I/O a lot while working with dotProject. Of course, YMMV - to apply this change or not depends on where is your bottleneck.

    If you didn't yet do anything from the start of the post but intend to apply the above-described changes, then just change "type=MyISAM" to "type=memory" in the SQL box in the beginning.

    I hope it works fine, if not - will have to update this post.

    Here are the links to the two modified files, rename them as necessary and replace original files:

    modules/projects/projects.class.php

    classes/query.class.php

    Comments and improvements are welcome.

    Share This

    3 Responses to “dotProject 2.0.4 on GoDaddy.com shared hosting”

    1. vilvendhan Says:

      Thanks for your help.
      It is working now.

    2. chronos Says:

      I'm glad it helped!
      Since I applied the described solution, there were no other related error messages or problems, so it should work just fine.

    3. Syed Says:

      Thanks for this info. It really helped and saved me a lot of time.

    Leave a Reply

    XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

     
    Close
    E-mail It