csv_from_result() move robust against data with "," in it.
diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php
index d48425d..8ce19b1 100644
--- a/system/database/DB_utility.php
+++ b/system/database/DB_utility.php
@@ -236,35 +236,51 @@
 	 * @param	string	The newline character - \n by default

 	 * @return	string

 	 */

-	function csv_from_result($query, $delim = "\t", $newline = "\n")

+	function csv_from_result($query, $delim = ',', $newline = '', $enclosure = '"')

 	{

-		if ( ! is_object($query) OR ! method_exists($query, 'field_names'))

-		{

-			show_error('You must submit a valid result object');

-		}	

+		if (!is_a($query, 'CI_DB_result')) {

+			show_error('CI_DB_utility::csv_from_result - You must submit a valid result object');

+		}    

+		

+		if ($delim === '') {

+			show_error('CI_DB_utility::csv_from_result - Empty delimiters are not permitted');

+		}

+		

+		if ($newline === '') {

+			$newline = (stripos(getenv('HTTP_USER_AGENT'), 'win') !== false) ? "\r\n" : "\n";

+		}

 	

+		if ((strpos($enclosure, $newline) !== false) or (($enclosure !== '') and (strpos($newline, $enclosure) !== false))) {

+			show_error('CI_DB_utility::csv_from_result - Field enclosure must not be contained within delimiter (or vice versa)');

+		}

+			

 		$out = '';

 		

 		// First generate the headings from the table column names

-		foreach ($query->list_fields() as $name)

-		{

-			$out .= $name.$delim;

-		}

-		

-		$out = rtrim($out);

-		$out .= $newline;

-		

-		// Next blast through the result array and build out the rows

-		foreach ($query->result_array() as $row)

-		{

-			foreach ($row as $item)

-			{

-				$out .= $item.$delim;			

+		foreach ($query->list_fields() as $name) {

+			// there's no point enclosing strings that do not require it

+			if (strpos($name, $delim) !== false) {

+				$out .= $enclosure . $name . $enclosure  . $delim;

+			} else {

+				$out .= $name . $delim;

 			}

-			$out = rtrim($out);

-			$out .= $newline;

 		}

-

+		

+		$out = rtrim($out, $delim) . $newline;

+				

+		// Next blast through the result array and build out the rows

+		foreach ($query->result_array() as $row) {

+			foreach ($row as $item)    {

+				// there's no point enclosing strings that do not require it

+				if (strpos($item, $delim) !== false) {

+					$out .= $enclosure . $item . $enclosure . $delim;

+				} else {

+					$out .= $item . $delim;

+				}

+			}

+			$out = rtrim($out, $delim) . $newline;

+		}

+	

 		return $out;

 	}

 	

diff --git a/user_guide/changelog.html b/user_guide/changelog.html
index 0456be3..e598e7c 100644
--- a/user_guide/changelog.html
+++ b/user_guide/changelog.html
@@ -71,6 +71,7 @@
 	<li>Added some additional mime types in application/config/mimes.php.</li>

 	<li>Added filename_security() method to <a href="./libraries/input.html">Input library</a>.</li>

 	<li>Added some additional arguments to the <a href="./helpers/inflector_helper.html">Inflection helper</a> singular() to compensate for words ending in "s".  Also added a force parameter to pluralize().</li>

+	<li>Fiixed a bug in csv_from_result() function that resulted in inproper output. </li>

 	<li>Fixed MSSQL insert_id().</li>

 	<li>Fixed a logic error in the DB trans_status() function.  It was incorrectly returning TRUE on failure and FALSE on success.</li>

 	<li>Fixed a bug that was allowing multiple load attempts on extended classes.</li>