Parcourir la source

Initial import of version 0.2

spficklin il y a 15 ans
Parent
commit
2cec0df360

+ 111 - 0
tripal_core/cvterms.php

@@ -0,0 +1,111 @@
+<?php
+//
+// Copyright 2009 Clemson University
+//
+
+/************************************************************************
+*
+*/
+function tripal_add_cvterms ($name,$definition,$cv_name = 'tripal',$db_name='tripal'){
+   
+   
+   $previous_db = db_set_active('chado');  // use chado database
+   $cv = db_fetch_object(db_query("SELECT * FROM {cv} WHERE name = '$cv_name'"));
+   if (!$cv->cv_id) {
+      db_set_active($previous_db);
+      tripal_add_cv('tripal', 'Terms used by Tripal for modules to manage data such as that stored in property tables like featureprop, analysisprop, etc');
+      db_set_active('chado');
+      $cv = db_fetch_object(db_query("SELECT * FROM {cv} WHERE name = '$cv_name'"));
+   }
+   $db = db_fetch_object(db_query("SELECT * FROM {db} WHERE name = '$db_name'"));
+	if (!$db->db_id) {
+	   db_set_active($previous_db);
+	   tripal_add_db('tripal', 'Used as a database placeholder for tripal defined objects such as tripal cvterms', '', '');
+	   db_set_active('chado');
+	   $db = db_fetch_object(db_query("SELECT * FROM {db} WHERE name = '$db_name'"));
+	}
+	// check to see if the dbxref already exists if not then add it
+	$sql = "SELECT * FROM {dbxref} WHERE db_id = $db->db_id and accession = '$name'";
+	$dbxref = db_fetch_object(db_query($sql));
+	if(!$dbxref){
+	   db_query("INSERT INTO {dbxref} (db_id,accession) VALUES ($db->db_id,'$name')");
+		$dbxref = db_fetch_object(db_query($sql));
+	}
+
+   
+   // now add the cvterm only if it doesn't already exist
+	$sql = "SELECT * FROM {cvterm} ".
+	       "WHERE cv_id = $cv->cv_id and dbxref_id = $dbxref->dbxref_id and name = '$name'";
+	$cvterm = db_fetch_object(db_query($sql));
+	if(!$cvterm){
+      $result = db_query("INSERT INTO {cvterm} (cv_id,name,definition,dbxref_id) ".
+                         "VALUES ($cv->cv_id,'$name','$definition',$dbxref->dbxref_id)");
+	}
+   db_set_active($previous_db);  // now use drupal database	
+	
+   if(!$result){
+     // TODO -- ERROR HANDLING
+   }
+}
+/************************************************************************
+*
+*/
+function tripal_add_db($db_name,$description,$urlprefix,$url){
+   $previous_db = db_set_active('chado');  // use chado database
+
+   // use this SQL statement to get the db_id for the database name
+   $id_sql = "SELECT db_id FROM {db} WHERE name = '%s'";
+
+   $db = db_fetch_object(db_query($id_sql,$db_name));
+
+   // if the database doesn't exist then let's add it.
+   if(!$db->db_id){
+      $sql = "
+         INSERT INTO {db} (name,description,urlprefix,url) VALUES 
+         ('%s','%s','%s','%s');
+      ";
+      db_query($sql,$db_name,$description,$urlprefix,$url);
+    
+      # now get the id for this new db entry
+      $db = db_fetch_object(db_query($id_sql,$db_name));
+   }
+   db_set_active($previous_db);  // now use drupal database	
+   return $db->db_id;
+}
+
+/************************************************************************
+*
+*/
+function tripal_delete_db($db_name){
+   $previous_db = db_set_active('chado');  // use chado database
+   $sql = "DELETE FROM {db} WHERE name ='%s'";
+   db_query($sql,$db_name);
+   db_set_active($previous_db);  // now use drupal database 
+   
+}
+
+/************************************************************************
+*
+*/
+function tripal_add_cv($cv_name,$definition){
+   $previous_db = db_set_active('chado');  // use chado database
+
+   // use this SQL statement to get the db_id for the database name
+   $id_sql = "SELECT cv_id FROM {cv} WHERE name = '%s'";
+
+   $cv = db_fetch_object(db_query($sql,$cv_name));
+
+   // if the database doesn't exist then let's add it.
+   if(!$cv){
+      $sql = "
+         INSERT INTO {cv} (name,definition) VALUES 
+         ('%s','%s');
+      ";
+      db_query($sql,$cv_name,$definition);
+    
+      # now get the id for this new db entry
+      $cv = db_fetch_object(db_query($sql,$cv_name));
+   }
+   db_set_active($previous_db);  // now use drupal database	
+   return $cv->cv_id;
+}

+ 181 - 0
tripal_core/jobs.php

@@ -0,0 +1,181 @@
+<?php
+//
+// Copyright 2009 Clemson University
+//
+
+/************************************************************************
+*
+*/
+function tripal_add_job ($job_name,$modulename,$callback,$arguments,$uid,
+   $priority = 10){
+
+   # convert the arguments into a string for storage in the database
+   $args = implode("::",$arguments);
+
+   $record = new stdClass();
+   $record->job_name = $job_name;
+   $record->modulename = $modulename;
+   $record->callback = $callback;
+   $record->status = 'Waiting';
+   $record->submit_date = time();
+   $record->uid = $uid;
+   $record->priority = $priority;  # the lower the number the higher the priority
+   if($args){
+      $record->arguments = $args;
+   }
+   drupal_write_record('tripal_jobs',$record);
+   $jobs_url = url("admin/tripal/tripal_jobs");
+   drupal_set_message(t("Job '$job_name' submitted.  Check the <a href='$jobs_url'>jobs page</a> for status"));
+
+   return 1;
+}
+/************************************************************************
+*   
+*/
+function tripal_job_set_progress($job_id,$percentage){
+
+   if(preg_match("/^(\d\d|100)$/",$percentage)){
+      $record = new stdClass();
+      $record->job_id = $job_id; 
+      $record->progress = $percentage;
+	  if(drupal_write_record('tripal_jobs',$record,'job_id')){
+	     return 1;
+	  }
+   }
+   return 0;
+}
+/************************************************************************
+*   Returns a list of jobs associated with the given module
+*/
+function tripal_get_module_active_jobs ($modulename){
+   $sql =  "SELECT * FROM {tripal_jobs} TJ ".
+           "WHERE TJ.end_time IS NULL and TJ.modulename = '%s' ";
+  return db_fetch_object(db_query($sql,$modulename));
+
+}
+/************************************************************************
+*
+*/
+function tripal_jobs_report () {
+   //$jobs = db_query("SELECT * FROM {tripal_jobs} ORDER BY job_id DESC");
+   $jobs = pager_query("SELECT * FROM {tripal_jobs} ORDER BY job_id DESC",10,0,"SELECT count(*) FROM {tripal_jobs}");
+	
+   // create a table with each row containig stats for 
+   // an individual job in the results set.
+   $output .= "Waiting jobs are executed first by priority level (the lower the ".
+              "number the higher the priority) and second by the order they ".
+              "were entered";
+   $output .= "<table class=\"border-table\">". 
+              "  <tr>".
+              "    <th>Job ID</th>".
+              "    <th>Job Name</th>".
+              "    <th nowrap>Dates</th>".             
+			     "    <th>Priority</th>".
+			     "    <th>Progress</th>".
+              "    <th>Status</th>".
+              "  </tr>";
+   
+   while($job = db_fetch_object($jobs)){
+      $submit = format_date($job->submit_date);
+      if($job->start_time > 0){
+         $start = format_date($job->start_time);
+      } else {
+         $start = 'Not Yet Started';
+      }
+      if($job->end_time > 0){
+         $end = format_date($job->end_time);
+      } else {
+         $end = '';
+      }
+      $output .= "  <tr>";
+      $output .= "    <td>$job->job_id</td>".
+                 "    <td>$job->job_name</td>".
+                 "    <td nowrap>Submit Date: $submit".
+                 "    <br>Start Time: $start".
+                 "    <br>End Time: $end</td>".
+                 "    <td>$job->priority</td>".
+				     "    <td>$job->progress%</td>".
+                 "    <td>$job->status</td>".
+                 "  </tr>";
+   }
+   $output .= "</table>";
+	$output .= theme_pager();
+   return $output;
+}
+/************************************************************************
+*
+*/
+function tripal_jobs_launch (){
+   
+   // first check if any jobs are currently running
+   // if they are, don't continue, we don't want to have
+   // more than one job script running at a time
+   if(tripal_jobs_check_running()){
+      return;
+   }
+   
+   // get all jobs that have not started and order them such that
+   // they are processed in a FIFO manner. 
+   $sql =  "SELECT * FROM {tripal_jobs} TJ ".
+           "WHERE TJ.start_time IS NULL ".
+           "ORDER BY priority ASC,job_id ASC";
+   $job_res = db_query($sql);
+   while($job = db_fetch_object($job_res)){
+
+		// set the start time for this job
+		$record = new stdClass();
+		$record->job_id = $job->job_id;
+		$record->start_time = time();
+		$record->status = 'Running';
+		$record->pid = getmypid();
+		drupal_write_record('tripal_jobs',$record,'job_id');
+
+		// call the function provided in the callback column.
+		// Add the job_id as the last item in the list of arguments. All
+		// callback functions should support this argument.
+		$callback = $job->callback;
+		$args = split("::",$job->arguments);
+		$args[] = $job->job_id;
+		print "Calling: $callback(" . implode(", ",$args) . ")\n";   
+		call_user_func_array($callback,$args);
+		
+		// set the end time for this job
+		$record->end_time = time();
+		$record->status = 'Completed';
+		$record->progress = '100';
+		drupal_write_record('tripal_jobs',$record,'job_id');
+		
+		// send an email to the user advising that the job has finished
+   }
+}
+/************************************************************************
+*
+*/
+function tripal_jobs_check_running () {
+   // iterate through each job that has not ended
+   // and see if it is still running. If it is not
+   // running but does not have an end_time then
+   // set the end time and set the status to 'Error'
+   $sql =  "SELECT * FROM {tripal_jobs} TJ ".
+           "WHERE TJ.end_time IS NULL and NOT TJ.start_time IS NULL ";
+   $jobs = db_query($sql);
+   while($job = db_fetch_object($jobs)){
+      if($job->pid and posix_kill($job->pid, 0)) {
+         // the job is still running so let it go
+		   // we return 1 to indicate that a job is running
+		   print "Job is still running (pid $job->pid)\n";
+		   return 1;
+      } else {
+	      // the job is not running so terminate it
+	      $record = new stdClass();
+         $record->job_id = $job->job_id;
+	      $record->end_time = time();
+         $record->status = 'Error';
+	      $record->error_msg = 'Job has terminated unexpectedly.';
+         drupal_write_record('tripal_jobs',$record,'job_id');
+	   }
+   }
+   // return 1 to indicate that no jobs are currently running.
+   return 0;
+}
+?>

+ 413 - 0
tripal_core/mviews.php

@@ -0,0 +1,413 @@
+<?php
+//
+// Copyright 2009 Clemson University
+//
+
+/************************************************************************
+ * Add a materialized view to the chado database to help speed data access.
+ * @param name The name of the materialized view.
+ * @param modulename The name of the module submitting the materialized view (e.g. 'tripal_library')
+ * @param mv_table The name of the table to add to chado. This is the table that can be queried.
+ * @param mv_specs The table definition 
+ * @param indexed The columns that are to be indexed
+ * @param query The SQL query that loads the materialized view with data
+ * @param special_index  
+ * function
+ * @return nothing
+ */
+function tripal_add_mview ($name,$modulename,$mv_table,$mv_specs,$indexed,$query,$special_index){
+
+   $record = new stdClass();
+   $record->name = $name;
+   $record->modulename = $modulename;
+   $record->mv_schema = 'DUMMY';
+   $record->mv_table = $mv_table;
+   $record->mv_specs = $mv_specs;
+   $record->indexed = $indexed;
+   $record->query = $query;
+   $record->special_index = $special_index;
+
+   // add the record to the tripal_mviews table and if successful
+   // create the new materialized view in the chado schema
+   if(drupal_write_record('tripal_mviews',$record)){
+
+      // drop the table from chado if it exists
+      $previous_db = db_set_active('chado');  // use chado database
+      if (db_table_exists($mv_table)) {
+         $sql = "DROP TABLE $mv_table";
+         db_query($sql);
+      }
+      db_set_active($previous_db);  // now use drupal database
+      
+      // now add the table for this view
+      $index = '';
+      if($indexed){
+         $index = ", CONSTRAINT ". $mv_table . "_index UNIQUE ($indexed) ";
+      }
+      $sql = "CREATE TABLE {$mv_table} ($mv_specs $index)"; 
+      $previous_db = db_set_active('chado');  // use chado database
+      $results = db_query($sql);
+      db_set_active($previous_db);  // now use drupal database
+      if($results){
+         drupal_set_message(t("View '$name' created"));
+      } else {
+         // if we failed to create the view in chado then
+         // remove the record from the tripal_jobs table
+         $sql = "DELETE FROM {tripal_mviews} ".
+                "WHERE mview_id = $record->mview_id";
+         db_query($sql);
+      }
+   }
+}
+/************************************************************************
+*
+*/
+function tripal_mviews_get_mview_id ($view_name){
+
+   $sql = "SELECT * FROM {tripal_mviews} ".
+          "WHERE name = '%s'";
+   if(db_table_exists('tripal_mviews')){
+      $mview = db_fetch_object(db_query($sql,$view_name));
+	   if($mview){
+	      return $mview->mview_id;
+	   }
+   }
+   return 0;
+}
+/************************************************************************
+*
+*/
+function tripal_mviews_action ($op,$mview_id){
+   global $user;
+   $args = array("$mview_id");
+   
+   if(!$mview_id){
+      return '';
+   }
+
+   // get this mview details
+   $sql = "SELECT * FROM {tripal_mviews} WHERE mview_id = $mview_id ";
+   $mview = db_fetch_object(db_query($sql));
+   
+   // add a job or perform the action based on the given operation
+   if($op == 'update'){
+      tripal_add_job("Update materialized view '$mview->name'",'tripal_core',
+         'tripal_update_mview',$args,$user->uid);
+	}
+   if($op == 'delete'){
+	   // remove the mview from the tripal_mviews table
+	   $sql = "DELETE FROM {tripal_mviews} ".
+             "WHERE mview_id = $mview_id";
+      db_query($sql);
+		
+	   // drop the table from chado if it exists
+      $previous_db = db_set_active('chado');  // use chado database
+      if (db_table_exists($mview->mv_table)) {
+         $sql = "DROP TABLE $mview->mv_table";
+         db_query($sql);
+      }
+      db_set_active($previous_db);  // now use drupal database
+   }
+   return '';
+}
+/************************************************************************
+*
+*/
+function tripal_update_mview ($mview_id){
+   $sql = "SELECT * FROM {tripal_mviews} WHERE mview_id = %d ";
+   $mview = db_fetch_object(db_query($sql,$mview_id));
+   if($mview){
+      $previous_db = db_set_active('chado');  // use chado database
+	   $results = db_query("DELETE FROM {$mview->mv_table}");
+      $results = db_query("INSERT INTO $mview->mv_table ($mview->query)");
+      db_set_active($previous_db);  // now use drupal database
+      if($results){
+	      $record = new stdClass();
+         $record->mview_id = $mview_id;
+         $record->last_update = time();
+		   drupal_write_record('tripal_mviews',$record,'mview_id');
+		   return 1;
+      } else {
+	     // TODO -- error handling
+	     return 0;
+	  }
+   }
+}
+/************************************************************************
+*
+*/
+function tripal_mview_report ($mview_id) {
+   // get this mview details
+   $sql = "SELECT * FROM {tripal_mviews} WHERE mview_id = $mview_id ";
+   $mview = db_fetch_object(db_query($sql));
+
+   // create a table with each row containig stats for
+   // an individual job in the results set.
+
+   $return_url = url("admin/tripal/tripal_mviews/");
+
+   $output .= "<p><a href=\"$return_url\">Return to table of materialized views.</a></p>";
+   $output .= "<br />";
+   $output .= "<p>Details for <b>$mview->name</b>:</p>";
+   $output .= "<br />";
+   $output .= "<table class=\"border-table\">";
+   if($mview->name){
+      $output .= "  <tr>".
+      "    <th>View Name</th>".
+      "    <td>$mview->name</td>".
+      "  </tr>";
+   }   
+   if($mview->modulename){
+      $output .= "  <tr>".
+      "    <th>Module Name</th>".
+      "    <td>$mview->modulename</td>".
+      "  </tr>";
+   }
+   if($mview->mv_table){
+      $output .= "  <tr>".
+      "    <th>Table Name</th>".
+      "    <td>$mview->mv_table</td>".
+      "  </tr>";
+   }   
+   if($mview->mv_specs){
+      $output .= "  <tr>".
+      "    <th>Table Field Definitions</th>".
+      "    <td>$mview->mv_specs</td>".
+      "  </tr>";
+   }   
+   if($mview->query){
+      $output .= "  <tr>".
+      "    <th>Query</th>".
+      "    <td><pre>$mview->query</pre></td>".
+      "  </tr>";
+   }   
+   if($mview->indexed){
+      $output .= "  <tr>".
+      "    <th>Indexed Fields</th>".
+      "    <td>$mview->indexed</td>".
+      "  </tr>";
+   }   
+   if($mview->special_index){
+      $output .= "  <tr>".
+      "    <th>Special Indexed Fields</th>".
+      "    <td>$mview->speical_index</td>".
+      "  </tr>";
+   }   
+   if($mview->last_update > 0){
+      $update = format_date($mview->last_update);
+   } else {
+      $update = 'Not yet populated';
+   }
+   $output .= "  <tr>".
+      "    <th>Last Update</th>".
+      "    <td>$update</td>".
+      "  </tr>";
+
+   // build the URLs using the url function so we can handle installations where
+   // clean URLs are or are not used
+   $update_url = url("admin/tripal/tripal_mviews/action/update/$mview->mview_id");
+   $delete_url = url("admin/tripal/tripal_mviews/action/delete/$mview->mview_id");
+   $edit_url = url("admin/tripal/tripal_mviews/edit/$mview->mview_id");
+
+   $output .= "<tr><th>Actions</th>".
+              "<td> <a href='$update_url'>Update</a>, ".
+              "     <a href='$edit_url'>Edit</a>, ".
+              "     <a href='$delete_url'>Delete</a></td></tr>";
+
+   $output .= "</table>";
+
+   return $output;
+}
+/************************************************************************
+*
+*/
+function tripal_mviews_report () {
+   $mviews = db_query("SELECT * FROM {tripal_mviews} ORDER BY name");
+
+   // create a table with each row containig stats for
+   // an individual job in the results set.
+   $output .= "<table class=\"border-table\">". 
+              "  <tr>".
+              "    <th nowrap></th>".
+              "    <th>Name</th>".
+              "    <th>Last_Update</th>".
+              "    <th nowrap></th>".
+              "  </tr>";
+   
+   while($mview = db_fetch_object($mviews)){
+      if($mview->last_update > 0){
+         $update = format_date($mview->last_update);
+      } else {
+         $update = 'Not yet populated';
+      }
+	  // build the URLs using the url function so we can handle installations where
+	  // clean URLs are or are not used
+	  $view_url = url("admin/tripal/tripal_mview/$mview->mview_id");
+	  $update_url = url("admin/tripal/tripal_mviews/action/update/$mview->mview_id");
+	  $delete_url = url("admin/tripal/tripal_mviews/action/delete/$mview->mview_id");
+	  // create the row for the table
+      $output .= "  <tr>";
+      $output .= "    <td><a href='$view_url'>View</a>&nbsp".
+                 "        <a href='$update_url'>Update</a></td>".
+	             "    <td>$mview->name</td>".
+                 "    <td>$update</td>".
+                 "    <td><a href='$delete_url'>Delete</a></td>".
+                 "  </tr>";
+   }
+   $new_url = url("admin/tripal/tripal_mviews/new");
+   $output .= "</table>";
+   $output .= "<br />";
+   $output .= "<p><a href=\"$new_url\">Create a new materialized view.</a></p>";
+   return $output;
+}
+/************************************************************************
+*
+*/
+function tripal_mviews_form(&$form_state = NULL,$mview_id = NULL){
+
+   if(!$mview_id){
+      $action = 'Add';
+   } else {
+      $action = 'Update';
+   }
+
+   // get this requested view
+   if(strcmp($action,'Update')==0){
+      $sql = "SELECT * FROM {tripal_mviews} WHERE mview_id = $mview_id ";
+      $mview = db_fetch_object(db_query($sql));
+
+
+      # set the default values.  If there is a value set in the 
+      # form_state then let's use that, otherwise, we'll pull 
+      # the values from the database 
+      $default_name = $form_state['values']['name'];
+      $default_mv_table = $form_state['values']['mv_table'];
+      $default_mv_specs = $form_state['values']['mv_specs'];
+      $default_indexed = $form_state['values']['indexed'];
+      $default_mvquery = $form_state['values']['mvquery'];
+      $default_special_index = $form_state['values']['special_index'];
+      if(!$default_name){
+         $default_name = $mview->name;
+      }
+      if(!$default_mv_table){
+         $default_mv_table = $mview->mv_table;
+      }
+      if(!$default_mv_specs){
+         $default_mv_specs = $mview->mv_specs;
+      }
+      if(!$default_indexed){
+         $default_indexed = $mview->indexed;
+      }
+      if(!$default_mvquery){
+         $default_mvquery = $mview->query;
+      }
+      if(!$default_special_index){
+         $default_special_index = $mview->special_index;
+      }
+   }
+   // Build the form
+   $form['action'] = array(
+      '#type' => 'value',
+      '#value' => $action
+   );
+   $form['mview_id'] = array(
+      '#type' => 'value',
+      '#value' => $mview_id
+   );
+   $form['name']= array(
+      '#type'          => 'textfield',
+      '#title'         => t('View Name'),
+      '#description'   => t('Please enter the name for this materialized view.'),
+      '#required'      => TRUE,
+      '#default_value' => $default_name,
+      '#weight'        => 1
+   );
+
+   $form['mv_table']= array(
+      '#type'          => 'textfield',
+      '#title'         => t('Table Name'),
+      '#description'   => t('Please enter the Postgres table name that this view will generate in the database.  You can use the schema and table name for querying the view'),
+      '#required'      => TRUE,
+      '#default_value' => $default_mv_table,
+      '#weight'        => 3
+   );
+   $form['mv_specs']= array(
+      '#type'          => 'textarea',
+      '#title'         => t('Table Definition'),
+      '#description'   => t('Please enter the field definitions for this view. Each field should be separated by a comma or enter each field definition on each line.'),
+      '#required'      => TRUE,
+      '#default_value' => $default_mv_specs,
+      '#weight'        => 4
+   );
+   $form['indexed']= array(
+      '#type'          => 'textarea',
+      '#title'         => t('Indexed Fields'),
+      '#description'   => t('Please enter the field names (as provided in the table definition above) that will be indexed for this view.  Separate by a comma or enter each field on a new line.'),
+      '#required'      => FALSE,
+      '#default_value' => $default_indexed,
+      '#weight'        => 5
+   );
+   $form['mvquery']= array(
+      '#type'          => 'textarea',
+      '#title'         => t('Query'),
+      '#description'   => t('Please enter the SQL statement used to populate the table.'),
+      '#required'      => TRUE,
+      '#default_value' => $default_mvquery,
+      '#weight'        => 6
+   );
+/*
+   $form['special_index']= array(
+      '#type'          => 'textarea',
+      '#title'         => t('View Name'),
+      '#description'   => t('Please enter the name for this materialized view.'),
+      '#required'      => TRUE,
+      '#default_value' => $default_special_index,
+      '#weight'        => 7
+   );
+*/
+   $form['submit'] = array (
+     '#type'         => 'submit',
+     '#value'        => t($action),
+     '#weight'       => 8,
+     '#executes_submit_callback' => TRUE,
+   );
+
+   $form['#redirect'] = 'admin/tripal/tripal_mviews';
+   return $form;
+}
+/************************************************************************
+*
+*/
+function tripal_mviews_form_submit($form, &$form_state){
+   
+   $action = $form_state['values']['action'];
+
+   if(strcmp($action,'Update')==0){
+      $record = new stdClass();
+      $record->mview_id = $form_state['values']['mview_id'];
+      $record->name = $form_state['values']['name'];
+      $record->mv_table = $form_state['values']['mv_table'];
+      $record->mv_specs = $form_state['values']['mv_specs'];
+      $record->indexed = $form_state['values']['indexed'];
+      $record->query = $form_state['values']['mvquery'];
+      $record->special_index = $form_state['values']['special_index'];
+
+      // add the record to the tripal_mviews table and if successful
+      // create the new materialized view in the chado schema
+      if(drupal_write_record('tripal_mviews',$record,'mview_id')){
+         drupal_set_message('View updated successfullly');
+      } else {
+         drupal_set_message('View update failed');
+      }
+   }
+   else if(strcmp($action,'Add')==0){
+      tripal_add_mview ($form_state['values']['name'], 'tripal_core',
+         $form_state['values']['mv_table'], $form_state['values']['mv_specs'],
+         $form_state['values']['indexed'], $form_state['values']['mvquery'],
+         $form_state['values']['special_index']);
+   }
+   else {
+        drupal_set_message("No action performed.");
+   }
+   return '';
+}

+ 7 - 0
tripal_core/tripal_core.info

@@ -0,0 +1,7 @@
+; $Id: tripal_core.info,v 1.3 2009/10/23 02:12:34 ccheng Exp $
+name = Tripal Core
+description = The core module for the Tripal package that integrates Drupal and GMOD chado. This module provides common support for all Tripal modules.
+core = 6.x
+project = tripal_core
+package = Tripal
+version = "6.x-0.2b-m0.2"

+ 110 - 0
tripal_core/tripal_core.install

@@ -0,0 +1,110 @@
+<?php
+
+/************************************************************************
+*  Implementation of hook_install();
+*/
+function tripal_core_install(){
+
+   // make the data directory for this module
+   $data_dir = file_directory_path() . "/tripal";
+   if(!file_check_directory($data_dir,FILE_CREATE_DIRECTORY)){
+      $message = "Cannot create directory $data_dir. This module may not ".
+                 "behave correctly without this directory.  Please  create ".
+                 "the directory manually or fix the problem and reinstall.";
+      drupal_set_message($message,'error');      
+      watchdog('tripal_core',$message,array(),WATCHDOG_ERROR);
+   }
+
+
+  // create the 'tripal' controlled volcabulary in chado but only if it doesn't already exist
+  $previous_db = db_set_active('chado');  // use chado database
+  if(!db_fetch_object(db_query("SELECT * FROM {cv} WHERE name = 'tripal'"))){
+     $results = db_query("INSERT INTO {cv} (name,definition) ".
+	                     "VALUES ('tripal','Terms used by Tripal for modules to manage data such as that stored in property tables like featureprop, analysisprop, etc')");
+  } 
+  if(!db_fetch_object(db_query("SELECT * FROM {db} WHERE name = 'tripal'"))){
+     $results = db_query("INSERT INTO {db} (name,description) ".
+	                     "VALUES ('tripal','Used as a database placeholder for tripal defined objects such as tripal cvterms')");
+  }  
+  db_set_active($previous_db);  // now use drupal database
+
+  // create the tables that manage materialized views and jobs
+  drupal_install_schema('tripal_core');
+
+}
+
+/************************************************************************
+* Implementation of hook_schema().
+*/
+function tripal_core_schema() {
+   $schema = tripal_core_get_schemas();
+   return $schema;
+}
+/************************************************************************
+* Implementation of hook_uninstall()
+*/
+function tripal_core_uninstall(){
+   drupal_uninstall_schema('tripal_core');
+}
+
+/************************************************************************
+* This function simply defines all tables needed for the module to work
+* correctly.  By putting the table definitions in a separate function we
+* can easily provide the entire list for hook_install or individual
+* tables for an update.
+*/
+function tripal_core_get_schemas (){  
+  $schema = array();
+
+
+  $schema['tripal_jobs'] = array(
+      'fields' => array(
+         'job_id' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
+         'uid' => array ('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'description' => 'The Drupal userid of the submitee'),
+         'job_name' => array('type' => 'varchar','length' => 255, 'not null' => TRUE),
+         'modulename' => array('type' => 'varchar','length' => 50, 'not null' => TRUE, 'description' => 'The module name that provides the callback for this job'),
+         'callback' => array('type' => 'varchar','length' => 255, 'not null' => TRUE),
+         'arguments' => array('type' => 'text', 'size' => 'normal', 'not null' => FALSE),
+         'progress' => array('type' => 'int', 'unsigned' => TRUE, 'default' => 0, 'not null' => FALSE, 'description' => 'a value from 0 to 100 indicating percent complete'),
+         'status' => array('type' => 'varchar','length' => 50, 'not null' => TRUE),
+         'submit_date' => array ('type' => 'int', 'not null' => TRUE, 'description' => 'UNIX integer submit time'),
+         'start_time' => array ('type' => 'int', 'not null' => FALSE, 'description' => 'UNIX integer start time'),
+         'end_time' => array ('type' => 'int', 'not null' => FALSE, 'description' => 'UNIX integer end time'),
+         'error_msg' => array('type' => 'text','size' => 'normal', 'not null' => FALSE),
+         'pid' => array ('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'description' => 'The process id for the job'),
+         'priority' => array ('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => '0', 'description' => 'The job priority'),
+         'mlock' => array ('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'description' => 'If set to 1 then all jobs for the module are held until this one finishes'),
+         'lock' => array ('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'description' => 'If set to 1 then all jobs are held until this one finishes'),
+      ),
+      'indexes' => array(
+         'job_id' => array('job_id'),
+         'job_name' => array('job_name')
+      ),
+      'primary key' => array('job_id'),
+  );
+
+  $schema['tripal_mviews'] = array(
+      'fields' => array(
+         'mview_id' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
+         'name' => array('type' => 'varchar','length' => 255, 'not null' => TRUE),
+         'modulename' => array('type' => 'varchar','length' => 50, 'not null' => TRUE, 'description' => 'The module name that provides the callback for this job'),
+         'mv_table' => array('type' => 'varchar','length' => 128, 'not null' => TRUE),
+         'mv_specs' => array('type' => 'text', 'size' => 'normal', 'not null' => TRUE),
+         'indexed' => array('type' => 'text', 'size' => 'normal', 'not null' => TRUE),
+         'query' => array('type' => 'text', 'size' => 'normal', 'not null' => TRUE),
+         'special_index' => array('type' => 'text', 'size' => 'normal', 'not null' => FALSE),
+         'last_update' => array ('type' => 'int', 'not null' => FALSE, 'description' => 'UNIX integer time'),
+      ),
+      'indexes' => array(
+         'mview_id' => array('mview_id')
+      ),
+      'unique keys' => array(
+         'mv_table' => array('mv_table'),
+         'mv_name' => array('name'),
+      ),
+      'primary key' => array('mview_id'),
+  );
+
+  return $schema;
+}
+?>

+ 155 - 0
tripal_core/tripal_core.module

@@ -0,0 +1,155 @@
+<?php
+
+//
+// Copyright 2009 Clemson University
+//
+
+require_once "jobs.php";
+require_once "mviews.php";
+require_once "cvterms.php";
+/*************************************************************************
+*
+*/
+function tripal_core_init(){
+	
+}
+/*************************************************************************
+*
+*/
+function tripal_create_moddir($module_name){
+   // make the data directory for this module
+   $data_dir = file_directory_path() . "/tripal/$module_name";
+   if(!file_check_directory($data_dir,FILE_CREATE_DIRECTORY|FILE_MODIFY_PERMISSIONS)){
+      $message = "Cannot create directory $data_dir. This module may not ".
+                 "behave correctly without this directory.  Please  create ".
+                 "the directory manually or fix the problem and reinstall.";
+      drupal_set_message($message,'error');      
+      watchdog('tripal_core',$message,array(),WATCHDOG_ERROR);
+   }
+}
+/*************************************************************************
+*
+*/
+function tripal_get_moddir($module_name){
+   $data_dir = file_directory_path() . "/tripal/$module_name";
+   return $data_dir;
+}
+/*************************************************************************
+*
+*/
+function tripal_core_menu() {
+   $items = array();
+   
+   // Triapl setting groups
+   $items['admin/tripal'] = array(
+      'title' => 'Tripal Management',
+      'description' => "Manage the behavior or Tripal and its various modules.",
+      'position' => 'right',
+      'weight' => -5,
+      'page callback' => 'system_admin_menu_block_page',
+      'access arguments' => array('administer site configuration'),
+      'file' => 'system.admin.inc',
+      'file path' => drupal_get_path('module', 'system'),
+   );
+
+   // the administative settings menu
+/*   $items['admin/tripal/tripal_core'] = array(
+     'title' => 'Tripal core settings',
+     'description' => 'Tripal Settings',
+     'page callback' => 'drupal_get_form',
+     'page arguments' => array('tripal_core_admin'),
+     'access arguments' => array('access administration pages'),
+     'type' => MENU_NORMAL_ITEM,
+   );
+*/
+   $items['admin/tripal/tripal_jobs'] = array(
+     'title' => 'Jobs',
+     'description' => 'Jobs managed by Tripal',
+     'page callback' => 'tripal_jobs_report',
+     'access arguments' => array('access administration pages'),
+     'type' => MENU_NORMAL_ITEM,
+   );
+   $items['admin/tripal/tripal_mview/%'] = array(
+     'title' => 'Materialized View',
+     'description' => 'Materialized views are used to improve speed of large or complex queries.',
+     'page callback' => 'tripal_mview_report',
+     'page arguments' => array(3),
+     'access arguments' => array('access administration pages'),
+     'type' => MENU_NORMAL_ITEM,
+   );
+   $items['admin/tripal/tripal_mviews'] = array(
+     'title' => 'Materialized Views',
+     'description' => 'Materialized views are used to improve speed of large or complex queries.',
+     'page callback' => 'tripal_mviews_report',
+     'access arguments' => array('access administration pages'),
+     'type' => MENU_NORMAL_ITEM,
+   );
+   $items['admin/tripal/tripal_mviews/new'] = array(
+     'title' => 'Create View',
+     'description' => 'Materialized views are used to improve speed of large or complex queries.',
+     'page callback' => 'drupal_get_form',
+     'page arguments' => array('tripal_mviews_form'),
+     'access arguments' => array('access administration pages'),
+     'type' => MENU_NORMAL_ITEM,
+   );
+   $items['admin/tripal/tripal_mviews/edit/%'] = array(
+     'title' => 'Edit View',
+     'page callback' => 'drupal_get_form',
+     'page arguments' => array('tripal_mviews_form',4),
+     'access arguments' => array('access administration pages'),
+     'type' => MENU_NORMAL_ITEM,
+   );
+   $items['admin/tripal/tripal_mviews/action/%/%'] = array(
+     'title' => 'Create View',
+     'description' => 'Materialized views are used to improve speed of large or complex queries.',
+     'page callback' => 'tripal_mviews_action',
+     'page arguments' => array(4,5),
+     'access arguments' => array('access administration pages'),
+     'type' => MENU_CALLBACK,
+   );
+
+   $items['tripal_toggle_box_menu/%/%/%'] = array(
+     'title' => t('Libraries'),
+     'page callback' => 'tripal_toggle_box_menu',
+     'page arguments' => array(1,2,3),
+     'access arguments' => array('access administration pages'),
+     'type' => MENU_CALLBACK | MENU_LINKS_TO_PARENT 
+   );
+  return $items;
+}
+/************************************************************************
+*  The typical display for information on feature, organism, library, etc
+*  pages is to use the Tripal expandable boxes.  However, some sites may
+*  prefer to use a menu system to keep the pages less cluttered.  This
+*  function provides a common interface for setting a Drupal variable
+*  that indicates whether or not the content is displayed in a box or as
+*  a menu item.  This function just reverses the setting each time it is
+*  called
+*/
+function tripal_toggle_box_menu($module,$box_name,$nid){
+   // if the content is not in a menu then we wnat to turn on the
+   // menu. If the content is in a menu item then we want to turn
+   // on the box. 
+   if(strcmp(variable_get("$module-box-$box_name","menu_off"),"menu_off")==0){
+      variable_set("$module-box-$box_name","menu_on");
+   } else {
+      variable_set("$module-box-$box_name","menu_off");
+   }
+   drupal_goto("node/$nid");
+}
+/************************************************************************
+*
+*/
+function tripal_core_admin () {
+
+
+   $form['chado_feature_data_url'] = array (
+      '#title'       => t('URL for data files'),
+      '#type'        => t('textfield'),
+      '#description' => t("This is the base URL location (without a leading forward slash)  for where files (e.g. blast .xml files) related to each feature are stored. All files available for download or parsing that a feature needs for display should be located in this base directory."), 
+      '#required'    => TRUE,
+      '#default_value' => variable_get('chado_feature_data_url','sites/default/files/data'),
+   );
+   
+   return system_settings_form($form);
+}

+ 54 - 0
tripal_core/tripal_launch_jobs.php

@@ -0,0 +1,54 @@
+<?php
+//
+// Copyright 2009 Clemson University
+//
+
+/* 
+
+This script must be run at the base directory level of the drupal installation 
+in order to pick up all necessary dependencies 
+
+*/
+
+  $stdout = fopen('php://stdout', 'w');
+
+  // we require one command-line argument
+  if(sizeof($argv) < 2){
+     print_usage($stdout);
+     exit;
+  }
+
+  $drupal_base_url = parse_url('http://www.example.com');
+  $_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
+//  $_SERVER['PHP_SELF'] = $drupal_base_url['path'].'/index.php';
+  $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
+  $_SERVER['REMOTE_ADDR'] = NULL;
+  $_SERVER['REQUEST_METHOD'] = NULL;
+
+  require_once 'includes/bootstrap.inc';
+  drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
+
+  fwrite($stdout, "Tripal Job Launcher\n");
+  fwrite($stdout, "-------------------\n");
+
+  // check to make sure the username is valid
+  $username = $argv[1];
+  if(!db_fetch_object(db_query("SELECT * FROM {users} WHERE name = '$username'"))){
+     fwrite($stdout, "'$username' is not a valid Drupal username. exiting...\n");
+     exit;
+  }
+  global $user;
+  $user = user_load(array('name' => $username));
+
+  tripal_jobs_launch();
+
+/************************************************************************
+*
+*/
+function print_usage ($stdout){
+  fwrite($stdout,"Usage:\n");
+  fwrite($stdout,"  php ./sites/all/modules/tripal_core/tripal_launch_jobs <username> \n\n");
+  fwrite($stdout,"    where <username> is a Drupal user name\n\n");
+}
+
+?>