/*
* Publication Harvester
* Copyright (c) 2003-2006 Stellman & Greene Consulting
* Developed for Joshua Zivin and Pierre Azoulay, Columbia University
* http://www.stellman-greene.com/PublicationHarvester
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program (GPL.txt); if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.OleDb;
using System.Data.Odbc;
using System.Collections;
namespace Com.StellmanGreene.PubMed
{
public class Database
{
OdbcConnection Connection;
public string DSN;
///
/// Establish a connection with an ODBC data source
///
/// HandGeneratedData source to connect to
public Database(string DSN)
{
Connection = new OdbcConnection("DSN=" + DSN + ";");
Connection.Open();
this.DSN = DSN;
}
///
/// Retrieve the status of the data in the database
///
/// True if the Harvested.CreateTables() has been called
/// Number of people that have been added to the database
/// Number of the people whose publications have been harvested
/// Number of publications in the database
public void GetStatus(out bool TablesCreated, out int numPeople,
out int numHarvestedPeople, out int numPublications, out int numErrors)
{
// Determine whether all seven of the tables have been created
DataTable Results = ExecuteQuery("SHOW TABLES");
if (Results.Rows.Count < 7)
{
TablesCreated = false;
numPeople = 0;
numHarvestedPeople = 0;
numPublications = 0;
numErrors = 0;
return;
}
ArrayList Tables = new ArrayList();
foreach (DataRow Row in Results.Rows)
{
Tables.Add(Row[0].ToString().ToLower());
}
foreach (string Table in new string[] {
"meshheadings", "people", "peoplepublications", "publicationauthors",
"publicationmeshheadings", "publications", "pubtypecategories", "publicationgrants"
}) {
if (Tables.Contains(Table) == false)
{
TablesCreated = false;
numPeople = 0;
numHarvestedPeople = 0;
numPublications = 0;
numErrors = 0;
return;
}
}
TablesCreated = true;
// Get the other values
numPeople = GetIntValue("SELECT Count(*) FROM People");
numHarvestedPeople = GetIntValue("SELECT Count(*) FROM People WHERE Harvested = 1");
numPublications = GetIntValue("SELECT Count(*) FROM Publications");
numErrors = GetIntValue("SELECT Count(*) FROM People WHERE Error = 1");
}
///
/// Execute a query that does not return a table
///
/// SQL query to execute
/// Number of rows affected
public virtual int ExecuteNonQuery(string SQL)
{
int results;
OdbcCommand Command;
using (Command = new OdbcCommand(SQL, Connection))
{
results = Command.ExecuteNonQuery();
}
return results;
}
///
/// Execute a query that does not return a table
///
/// SQL query to execute
/// ArrayList of OdbcParameter objects
/// Number of rows affected
public virtual int ExecuteNonQuery(string SQL, ArrayList Parameters)
{
int results;
OdbcCommand Command;
using (Command = new OdbcCommand(SQL, Connection))
{
for (int i = 0; i < Parameters.Count; i++)
Command.Parameters.Add(Parameters[i]);
results = Command.ExecuteNonQuery();
}
return results;
}
///
/// Execute a query that returns a table
///
/// SQL query to execute
/// Returns a DataTable containing the results of the query
public virtual DataTable ExecuteQuery(string SQL)
{
DataTable Table = new DataTable();
using (OdbcDataAdapter Query = new OdbcDataAdapter(SQL, Connection))
{
Query.Fill(Table);
}
return Table;
}
///
/// Execute a query that returns a table
///
/// SQL query to execute
/// ArrayList of OdbcParameter objects
/// Returns a DataTable containing the results of the query
public virtual DataTable ExecuteQuery(string SQL, ArrayList Parameters)
{
using (OdbcCommand Command = new OdbcCommand(SQL, Connection))
{
for (int i = 0; i < Parameters.Count; i++)
Command.Parameters.Add(Parameters[i]);
OdbcDataAdapter Query = new OdbcDataAdapter(Command);
DataTable Table = new DataTable();
Query.Fill(Table);
return Table;
}
}
///
/// Execute a query that returns a scalar
///
/// SQL query to execute
/// Returns an object containing the results of the query
public virtual object ExecuteScalar(string SQL)
{
object result;
using (OdbcCommand Command = new OdbcCommand(SQL, Connection))
{
result = Command.ExecuteScalar();
}
return result;
}
///
/// Get a string from the database
///
/// SQL query to execute
/// Returns a string containing the results of the query
public virtual string GetStringValue(string SQL)
{
string result;
using (OdbcCommand Command = new OdbcCommand(SQL, Connection))
{
result = Command.ExecuteScalar().ToString();
}
return result;
}
///
/// Get an int from the database
///
/// SQL query to execute
/// Returns an int containing the results of the query
public virtual int GetIntValue(string SQL)
{
int result;
using (OdbcCommand Command = new OdbcCommand(SQL, Connection)) {
result = Convert.ToInt32(Command.ExecuteScalar().ToString());
}
return result;
}
///
/// Get an int from the database
///
/// SQL query to execute
/// ArrayList of OdbcParameter objects
/// Returns an int containing the results of the query
public virtual int GetIntValue(string SQL, ArrayList Parameters)
{
int result;
OdbcCommand Command;
using (Command = new OdbcCommand(SQL, Connection))
{
for (int i = 0; i < Parameters.Count; i++)
Command.Parameters.Add(Parameters[i]);
result = Convert.ToInt32(Command.ExecuteScalar().ToString());
}
return result;
}
///
/// Create an OdbcParameter
///
/// Object to pass to a query
/// An OdbcParameter object that has the value Objct
public static OdbcParameter Parameter(object Object) {
if (Object == null)
return new OdbcParameter("", DBNull.Value);
else
return new OdbcParameter("", Object);
}
///
/// Trim a string to a given length, but only if it's greater than that length
///
/// String to trim
/// Maximum length of the string
/// Trimmed string
public static string Left(string Input, int Length)
{
if (Input == null)
return null;
else if (Input.Length > Length)
return Input.Substring(0, Length);
else
return Input;
}
///
/// The columns from the People table for use in a SQL query
///
public const string PEOPLE_COLUMNS = " Setnb, First, Middle, Last, Name1, Name2, Name3, Name4, MedlineSearch, CAST(Harvested AS unsigned integer) AS Harvested, CAST(Error AS unsigned integer) AS Error, ErrorMessage ";
///
/// Get a boolean value from an object
///
/// Value to parse
/// Output of value if one is found
/// True if a boolean value is found, false otherwise
public static bool GetBoolValue(object value, out bool result)
{
/*
* Note: This is needed as part of a workaround for a bug in MySQL 5.1 and
* MySQL ODBC Connector 5.1.5, where bit(1) columns always read as true
* no matter what their actual contents are. If we cast the column as an
* unsigned integer, it does return the actual value as 1 or 0:
*
* SELECT CAST(Harvested AS unsigned integer) AS Harvested
* FROM Colleagues
*
* This method is used to parse the results, in as flexible a manner as possible.
*/
if (value.Equals(1) || value.Equals(true))
{
result = true;
return true;
}
if (value.Equals(0) || value.Equals(false))
{
result = false;
return true;
}
if (value.Equals(System.DBNull.Value))
{
result = false;
return true;
}
int intValue;
bool boolValue;
if (int.TryParse(value.ToString(), out intValue))
{
if (intValue == 1)
result = true;
else
result = false;
return true;
}
else if (bool.TryParse(value.ToString(), out boolValue))
{
result = boolValue;
return true;
}
result = true;
return false;
}
}
}