diff --git a/src/admin/sources.php b/src/admin/sources.php
index 4e45586..3b16669 100644
--- a/src/admin/sources.php
+++ b/src/admin/sources.php
@@ -346,7 +346,9 @@ if ( isset($_GET['op']) )
$content['SourceTypeName'] = $content['SOURCETYPES'][ $content['SourceType'] ]['DisplayName'];
// Fix Filename manually for FILE LOGSTREAM!
- if ( $content['SourceType'] == SOURCE_DB || $content['SourceType'] == SOURCE_PDO )
+ if ( $content['SourceType'] == SOURCE_DB ||
+ $content['SourceType'] == SOURCE_PDO ||
+ $content['SourceType'] == SOURCE_MONGODB )
{
// Create LogStream Object
$stream = $tmpSource['ObjRef']->LogStreamFactory($tmpSource['ObjRef']);
@@ -545,7 +547,10 @@ if ( isset($_POST['op']) )
if ( isset($_POST['SourceDiskFile']) ) { $content['SourceDiskFile'] = DB_RemoveBadChars($_POST['SourceDiskFile']); }
}
// DB Params
- else if ( $content['SourceType'] == SOURCE_DB || $content['SourceType'] == SOURCE_PDO )
+ else if ( $content['SourceType'] == SOURCE_DB ||
+ $content['SourceType'] == SOURCE_PDO ||
+ $content['SourceType'] == SOURCE_MONGODB
+ )
{
if ( isset($_POST['SourceDBType']) ) { $content['SourceDBType'] = DB_RemoveBadChars($_POST['SourceDBType']); }
if ( isset($_POST['SourceDBName']) ) { $content['SourceDBName'] = DB_RemoveBadChars($_POST['SourceDBName']); }
@@ -640,7 +645,10 @@ if ( isset($_POST['op']) )
}
}
// DB Params
- else if ( $content['SourceType'] == SOURCE_DB || $content['SourceType'] == SOURCE_PDO )
+ else if ( $content['SourceType'] == SOURCE_DB ||
+ $content['SourceType'] == SOURCE_PDO ||
+ $content['SourceType'] == SOURCE_MONGODB
+ )
{
if ( !isset($content['SourceDBType']) )
{
@@ -705,7 +713,10 @@ if ( isset($_POST['op']) )
$tmpSource['DiskFile'] = $content['SourceDiskFileTesting']; // use SourceDiskFileTesting rather then SourceDiskFile as it is corrected
}
// DB Params
- else if ( $tmpSource['SourceType'] == SOURCE_DB || $tmpSource['SourceType'] == SOURCE_PDO )
+ else if ( $tmpSource['SourceType'] == SOURCE_DB ||
+ $tmpSource['SourceType'] == SOURCE_PDO ||
+ $tmpSource['SourceType'] == SOURCE_MONGODB
+ )
{
$tmpSource['DBType'] = DB_StripSlahes($content['SourceDBType']);
$tmpSource['DBName'] = DB_StripSlahes($content['SourceDBName']);
@@ -761,7 +772,10 @@ if ( isset($_POST['op']) )
" . $content['groupid'] . "
)";
}
- else if ( $content['SourceType'] == SOURCE_DB || $content['SourceType'] == SOURCE_PDO )
+ else if ( $content['SourceType'] == SOURCE_DB ||
+ $content['SourceType'] == SOURCE_PDO ||
+ $content['SourceType'] == SOURCE_MONGODB
+ )
{
$sqlquery = "INSERT INTO " . DB_SOURCES . " (Name, Description, SourceType, MsgParserList, MsgNormalize, MsgSkipUnparseable, defaultfilter, ViewID, DBTableType, DBType, DBServer, DBName, DBUser, DBPassword, DBTableName, DBEnableRowCounting, DBRecordsPerQuery, userid, groupid)
VALUES ('" . $content['Name'] . "',
@@ -821,7 +835,10 @@ if ( isset($_POST['op']) )
groupid = " . $content['groupid'] . "
WHERE ID = " . $content['SOURCEID'];
}
- else if ( $content['SourceType'] == SOURCE_DB || $content['SourceType'] == SOURCE_PDO )
+ else if ( $content['SourceType'] == SOURCE_DB ||
+ $content['SourceType'] == SOURCE_PDO ||
+ $content['SourceType'] == SOURCE_MONGODB
+ )
{
$sqlquery = "UPDATE " . DB_SOURCES . " SET
Name = '" . $content['Name'] . "',
@@ -931,6 +948,15 @@ if ( !isset($_POST['op']) && !isset($_GET['op']) )
// Enabled Database Maintenance functions
$mySource['IsDatabaseSource'] = true;
}
+ else if ( $mySource['SourceType'] == SOURCE_MONGODB )
+ {
+ $mySource['SourcesTypeImage'] = $content["MENU_SOURCE_MONGODB"];
+ $mySource['SourcesTypeText'] = $content["LN_SOURCES_MONGODB"];
+
+ // Enabled Database Maintenance functions
+ $mySource['IsDatabaseSource'] = true;
+ }
+
// ---
// --- Set CSS Class
diff --git a/src/classes/logstreamconfigmongodb.class.php b/src/classes/logstreamconfigmongodb.class.php
new file mode 100644
index 0000000..a7a8ca8
--- /dev/null
+++ b/src/classes/logstreamconfigmongodb.class.php
@@ -0,0 +1,70 @@
+.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this
+ * distribution.
+ *********************************************************************
+*/
+
+// --- Avoid directly accessing this file!
+if ( !defined('IN_PHPLOGCON') )
+{
+ die('Hacking attempt');
+ exit;
+}
+// ---
+
+class LogStreamConfigMongoDB extends LogStreamConfig {
+ public $DBServer = '127.0.0.1';
+ public $DBPort = 27017;
+ public $DBName = 'syslog';
+// public $DBUser = '';
+// public $DBPassword = '';
+ public $DBTableType = 'mongodb'; // Default = Use mongodb layout!
+ public $DBCollection = 'rsyslog'; // Default Tabelname from RSYSLOG
+// public $DBEnableRowCounting = true; // Default RowCounting is enabled!
+
+ // Runtime configuration variables
+ public $RecordsPerQuery = 100; // This will determine how to limit sql statements
+ public $IDsPerQuery = 5000; // When we query ID's, we read a lot more the datarecords at once!
+ public $SortColumn = SYSLOG_UID; // Default sorting column
+
+// public $FileName = '';
+// public $LineParserType = "syslog"; // Default = Syslog!
+// public $_lineParser = null;
+
+ public function LogStreamFactory($o)
+ {
+ // An instance is created, then include the logstreamdisk class as well!
+ global $gl_root_path;
+ require_once($gl_root_path . 'classes/logstreammongodb.class.php');
+
+ // return LogStreamDisk instance
+ return new LogStreamMongoDB($o);
+ }
+}
+?>
\ No newline at end of file
diff --git a/src/classes/logstreammongodb.class.php b/src/classes/logstreammongodb.class.php
new file mode 100644
index 0000000..5c580a4
--- /dev/null
+++ b/src/classes/logstreammongodb.class.php
@@ -0,0 +1,2128 @@
+.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this
+ * distribution.
+ *********************************************************************
+*/
+
+// --- Avoid directly accessing this file!
+if ( !defined('IN_PHPLOGCON') )
+{
+ die('Hacking attempt');
+ exit;
+}
+// ---
+
+// --- Required Includes!
+require_once($gl_root_path . 'include/constants_errors.php');
+// ---
+
+class LogStreamMongoDB extends LogStream {
+ private $_dbhandle = null;
+
+ // Helper to store the database records
+ private $bufferedRecords = null;
+ private $_currentRecordStart = 0;
+ private $_currentRecordNum = 0;
+ private $_totalRecordCount = -1;
+ private $_previousPageUID = -1;
+ private $_lastPageUID = -1;
+ private $_firstPageUID = -1;
+ private $_currentPageNumber = 0;
+
+ private $_SQLwhereClause = "";
+ private $_myDBQuery = null;
+
+ private $_myMongoCon = null;
+ private $_myMongoDB = null;
+ private $_myMongoCollection = null;
+
+ // Constructor
+ public function LogStreamMongoDB($streamConfigObj) {
+ $this->_logStreamConfigObj = $streamConfigObj;
+
+ // Probe if a function exists!
+ if ( !function_exists("bson_encode") )
+ DieWithFriendlyErrorMsg("Error, MongoDB PHP Driver Extensions is not installed! Please see http://www.php.net/manual/en/mongo.installation.php for installation details.");
+ }
+
+ /**
+ * Open and verifies the database conncetion
+ *
+ * @param arrProperties array in: Properties wish list.
+ * @return integer Error stat
+ */
+ public function Open($arrProperties)
+ {
+ global $dbmapping;
+
+ // Initialise Basic stuff within the Classs
+ $this->RunBasicInits();
+
+ // Verify database connection (This also opens the database!)
+ $res = $this->Verify();
+ if ( $res != SUCCESS )
+ return $res;
+
+ // Copy the Property Array
+ $this->_arrProperties = $arrProperties;
+
+ // Check if DB Mapping exists
+ if ( !isset($dbmapping[ $this->_logStreamConfigObj->DBTableType ]) )
+ return ERROR_DB_INVALIDDBMAPPING;
+
+ // Create SQL Where Clause first!
+ $res = $this->CreateSQLWhereClause();
+ if ( $res != SUCCESS )
+ return $res;
+
+ // Success, this means we init the Pagenumber to ONE!
+ $this->_currentPageNumber = 1;
+
+ // reached this point means success!
+ return SUCCESS;
+ }
+
+ /*
+ * Helper function to clear the current querystring!
+ */
+ public function ResetFilters()
+ {
+ // Clear _SQLwhereClause variable!
+ $this->_SQLwhereClause = "";
+ }
+
+ /**
+ * Close the database connection.
+ *
+ * @return integer Error state
+ */
+ public function Close()
+ {
+ $bReturn = SUCCESS;
+ if ($this->_myMongoCon)
+ {
+ if (!$this->_myMongoCon->close())
+ $bReturn = false; // return fail
+ }
+
+ // Reset variables
+ $this->_myMongoCon = null;
+ $this->_myMongoDB = null;
+ $this->_myMongoCollection = null;
+
+ return $bReturn;
+ }
+
+ /**
+ * Verify if the database connection exists!
+ *
+ * @return integer Error state
+ */
+ public function Verify() {
+ // Try to connect to the database
+ if ( $this->_myMongoCon == null )
+ {
+ try
+ {
+// TODO: USername and Password support!
+ // Forces to open a new Connection
+ $this->_myMongoCon = new Mongo("mongodb://" . $this->_logStreamConfigObj->DBServer . ":" . $this->_logStreamConfigObj->DBPort ); // Connect to Mongo Server
+ }
+ catch ( MongoConnectionException $e )
+ {
+ global $extraErrorDescription;
+ $extraErrorDescription = $e->getMessage;
+
+ // Return error code
+ return ERROR_DB_CONNECTFAILED;
+ }
+ }
+
+ try
+ {
+ $this->_myMongoDB = $this->_myMongoCon->selectDB( $this->_logStreamConfigObj->DBName ); // Connect to Database
+ }
+ catch ( MongoException $e )
+ {
+ global $extraErrorDescription;
+ $extraErrorDescription = $e->getMessage;
+
+ // Return error code
+ return ERROR_DB_CANNOTSELECTDB;
+ }
+
+ // Check if the table exists!
+ try
+ {
+ $this->_myMongoCollection = $this->_myMongoDB->selectCollection ( $this->_logStreamConfigObj->DBCollection );
+ }
+ catch ( MongoException $e )
+ {
+ global $extraErrorDescription;
+ $extraErrorDescription = $e->getMessage;
+
+ // Return error code
+ return ERROR_DB_TABLENOTFOUND;
+ }
+
+ // reached this point means success ;)!
+ return SUCCESS;
+ }
+
+
+ /*
+ * Implementation of VerifyFields: Checks if fields exist in table
+ */
+ public function VerifyFields( $arrProperitesIn )
+ {
+/*
+TODO!!!
+ global $dbmapping, $fields;
+
+ // Get List of Indexes as Array
+ $arrFieldKeys = $this->GetFieldsAsArray();
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // Loop through all fields to see which one is missing!
+ foreach ( $arrProperitesIn as $myproperty )
+ {
+// echo $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "
";
+ if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) && in_array($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrFieldKeys) )
+ {
+ OutputDebugMessage("LogStreamDB|VerifyFields: Found Field for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "'", DEBUG_ULTRADEBUG);
+ continue;
+ }
+ else
+ {
+ // Index is missing for this field!
+ OutputDebugMessage("LogStreamDB|VerifyFields: Missing Field for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "'", DEBUG_WARN);
+ return ERROR_DB_DBFIELDNOTFOUND;
+ }
+ }
+*/
+
+ // Successfull
+ return SUCCESS;
+ }
+
+
+ /*
+ * Implementation of VerifyIndexes: Checks if indexes exist for desired fields
+ */
+ public function VerifyIndexes( $arrProperitesIn )
+ {
+/*
+TODO!!!
+ global $dbmapping, $fields;
+
+ // Get List of Indexes as Array
+ $arrIndexKeys = $this->GetIndexesAsArray();
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // Loop through all fields to see which one is missing!
+ foreach ( $arrProperitesIn as $myproperty )
+ {
+// echo $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "
";
+ if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) && in_array($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrIndexKeys) )
+ {
+ OutputDebugMessage("LogStreamDB|VerifyIndexes: Found INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "'", DEBUG_ULTRADEBUG);
+ continue;
+ }
+ else
+ {
+ // Index is missing for this field!
+ OutputDebugMessage("LogStreamDB|VerifyIndexes: Missing INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "'", DEBUG_WARN);
+ return ERROR_DB_INDEXESMISSING;
+ }
+ }
+*/
+ // Successfull
+ return SUCCESS;
+ }
+
+
+ /*
+ * Implementation of VerifyChecksumTrigger: Checks if checksum trigger exists
+ */
+ public function VerifyChecksumTrigger( $myTriggerProperty )
+ {
+/*
+TODO
+ global $dbmapping, $fields;
+
+ // Get List of Triggers as Array
+ $arrIndexTriggers = $this->GetTriggersAsArray();
+
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+ $szDBName = $this->_logStreamConfigObj->DBName;
+ $szTableName = $this->_logStreamConfigObj->DBTableName;
+ $szDBTriggerField = $dbmapping[$szTableType]['DBMAPPINGS'][$myTriggerProperty];
+
+ // Create Triggername | lowercase!
+ $szTriggerName = strtolower( $szDBName . "_" . $szTableName . "_" . $szDBTriggerField );
+
+ // Try to find logstream trigger
+ if ( count($arrIndexTriggers) > 0 )
+ {
+ if ( in_array($szTriggerName, $arrIndexTriggers) )
+ return SUCCESS;
+ else
+ {
+ // Index is missing for this field!
+ OutputDebugMessage("LogStreamDB|VerifyChecksumTrigger: Missing TRIGGER '" . $szTriggerName . "' for Table '" . $szTableName . "'", DEBUG_WARN);
+ return ERROR_DB_TRIGGERMISSING;
+ }
+ }
+ else
+ {
+ // Index is missing for this field!
+ OutputDebugMessage("LogStreamDB|VerifyChecksumTrigger: No TRIGGERS found in your database", DEBUG_WARN);
+ return ERROR_DB_TRIGGERMISSING;
+ }
+*/
+
+ // Successfull
+ return SUCCESS;
+ }
+
+
+ /*
+ * Implementation of CreateMissingIndexes: Checks if indexes exist for desired fields
+ */
+ public function CreateMissingIndexes( $arrProperitesIn )
+ {
+/*
+TODO
+ global $dbmapping, $fields, $querycount;
+
+ // Get List of Indexes as Array
+ $arrIndexKeys = $this->GetIndexesAsArray();
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // Loop through all fields to see which one is missing!
+ foreach ( $arrProperitesIn as $myproperty )
+ {
+ if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) && in_array($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrIndexKeys) )
+ continue;
+ else
+ {
+ // Update Table schema now!
+ $szSql = "ALTER TABLE " . $this->_logStreamConfigObj->DBTableName . " ADD INDEX ( " . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . " )";
+
+ // Index is missing for this field!
+ OutputDebugMessage("LogStreamDB|CreateMissingIndexes: Createing missing INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' - " . $szSql, DEBUG_INFO);
+
+ // Add missing INDEX now!
+ $myQuery = mysql_query($szSql, $this->_dbhandle);
+ if (!$myQuery)
+ {
+ // Return failure!
+ $this->PrintDebugError("Dynamically Adding INDEX for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' failed with Statement: '" . $szSql . "'");
+ return ERROR_DB_INDEXFAILED;
+ }
+ }
+ }
+*/
+
+ // Successfull
+ return SUCCESS;
+ }
+
+
+ /*
+ * Implementation of CreateMissingFields: Checks if indexes exist for desired fields
+ */
+ public function CreateMissingFields( $arrProperitesIn )
+ {
+/*
+TODO
+
+ global $dbmapping, $fields, $querycount;
+
+ // Get List of Indexes as Array
+ $arrFieldKeys = $this->GetFieldsAsArray();
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // Loop through all fields to see which one is missing!
+ foreach ( $arrProperitesIn as $myproperty )
+ {
+ if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) && in_array($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrFieldKeys) )
+ continue;
+ else
+ {
+ if ( $this->HandleMissingField( $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], $arrProperitesIn ) == SUCCESS )
+ {
+ // Index is missing for this field!
+ OutputDebugMessage("LogStreamDB|CreateMissingFields: Createing missing FIELD for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty], DEBUG_INFO);
+ }
+ else
+ {
+ // Return failure!
+ $this->PrintDebugError("Dynamically Adding FIELD for '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' failed!");
+ return ERROR_DB_ADDDBFIELDFAILED;
+ }
+ }
+ }
+*/
+
+ // Successfull
+ return SUCCESS;
+ }
+
+
+ /*
+ * Implementation of GetCreateMissingTriggerSQL: Creates SQL needed to create a TRIGGER
+ */
+ public function GetCreateMissingTriggerSQL( $myDBTriggerField, $myDBTriggerCheckSumField )
+ {
+/*
+ global $dbmapping, $fields, $querycount;
+
+ // Get List of Triggers as Array
+ $szDBName = $this->_logStreamConfigObj->DBName;
+ $szTableName = $this->_logStreamConfigObj->DBTableName;
+
+ // Create Triggername
+ $szTriggerName = $szDBName . "_" . $szTableName . "_" . $myDBTriggerField;
+
+ // Create TRIGGER SQL!
+ $szSql = "CREATE TRIGGER " . $szTriggerName . " BEFORE INSERT ON `" . $szTableName . "`
+ FOR EACH ROW
+ BEGIN
+ SET NEW." . $myDBTriggerCheckSumField . " = crc32(NEW." . $myDBTriggerField . ");
+ END
+ ;";
+
+ return $szSql;
+*/
+ return "";
+ }
+
+
+ /*
+ * Implementation of CreateMissingTrigger: Creates missing triggers !
+ */
+ public function CreateMissingTrigger( $myTriggerProperty, $myCheckSumProperty )
+ {
+/*
+TODO
+ global $dbmapping, $fields, $querycount;
+
+ // Get List of Triggers as Array
+ $szTableName = $this->_logStreamConfigObj->DBTableName;
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+ $szDBTriggerField = $dbmapping[$szTableType]['DBMAPPINGS'][$myTriggerProperty];
+ $szDBTriggerCheckSumField = $dbmapping[$szTableType]['DBMAPPINGS'][$myCheckSumProperty];
+
+ // Get SQL Code to create the trigger!
+ $szSql = $this->GetCreateMissingTriggerSQL( $szDBTriggerField, $szDBTriggerCheckSumField );
+
+ // Index is missing for this field!
+ OutputDebugMessage("LogStreamDB|CreateMissingTrigger: Creating missing TRIGGER for '" . $szTableName . "' - $szDBTriggerCheckSumField = crc32(NEW.$szDBTriggerField)" . $szSql, DEBUG_INFO);
+
+ // Add missing INDEX now!
+ $myQuery = mysql_query($szSql, $this->_dbhandle);
+ if (!$myQuery)
+ {
+ // Return failure!
+ $this->PrintDebugError("Dynamically Adding TRIGGER for '" . $szTableName . "' failed!
If you want to manually add the TRIGGER, use the following SQL Command:
" . str_replace("\n", "
", $szSql) . "
");
+
+ return ERROR_DB_TRIGGERFAILED;
+ }
+*/
+
+ // Successfull
+ return SUCCESS;
+ }
+
+
+ /*
+ * Implementation of ChangeChecksumFieldUnsigned: Changes the Checkusm field to unsigned!
+ */
+ public function ChangeChecksumFieldUnsigned()
+ {
+/*
+TODO!!!
+ global $dbmapping, $fields, $querycount;
+
+ // Get variables
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // Change Checksumfield to use UNSIGNED!
+ $szUpdateSql = "ALTER TABLE `" . $this->_logStreamConfigObj->DBTableName . "` CHANGE `" .
+ $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . "` `" .
+ $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . "` INT(11) UNSIGNED NOT NULL DEFAULT '0'";
+
+ // Update Table schema now!
+ $myQuery = mysql_query($szUpdateSql, $this->_dbhandle);
+ if (!$myQuery)
+ {
+ // Return failure!
+ $this->PrintDebugError("ER_BAD_FIELD_ERROR - Failed to Change field '" . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . "' from signed to unsigned with sql statement: '" . $szUpdateSql . "'");
+ return ERROR_DB_CHECKSUMCHANGEFAILED;
+ }
+*/
+
+ // return results
+ return SUCCESS;
+ }
+
+
+ /*
+ * Implementation of VerifyChecksumField: Verifies if the checkusm field is signed or unsigned!
+ */
+ public function VerifyChecksumField()
+ {
+/*
+TODO
+ global $dbmapping, $fields, $querycount;
+
+ // Get variables
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // Create SQL and Get INDEXES for table!
+ $szSql = "SHOW COLUMNS FROM " . $this->_logStreamConfigObj->DBTableName . " WHERE Field = '" . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . "'";
+ $myQuery = mysql_query($szSql, $this->_dbhandle);
+ if ($myQuery)
+ {
+ // Get result!
+ $myRow = mysql_fetch_array($myQuery, MYSQL_ASSOC);
+ if (strpos( strtolower($myRow['Type']), "unsigned") === false )
+ {
+ // return error code!
+ return ERROR_DB_CHECKSUMERROR;
+ }
+
+ // Free query now
+ mysql_free_result ($myQuery);
+
+ // Increment for the Footer Stats
+ $querycount++;
+ }
+*/
+
+ // return results
+ return SUCCESS;
+ }
+
+
+ /**
+ * Read the data from a specific uID which means in this
+ * case beginning with from the Database ID
+ *
+ * @param uID integer in/out: unique id of the data row
+ * @param arrProperitesOut array out: array filled with properties
+ * @return integer Error state
+ * @see ReadNext()
+ */
+ public function Read($uID, &$arrProperitesOut)
+ {
+ // Seek the first uID!
+ if ( $this->Sseek($uID, EnumSeek::UID, 0) == SUCCESS)
+ {
+ // Read the next record!
+ $ret = $this->ReadNext($uID, $arrProperitesOut);
+ }
+ else
+ $ret = ERROR_NOMORERECORDS;
+
+ // return result!
+ return $ret;
+ }
+
+ /**
+ * Read the next line from the file depending on the current
+ * read direction.
+ *
+ * Hint: If the current stream becomes unavailable an error
+ * stated is retuned. A typical case is if a log rotation
+ * changed the original data source.
+ *
+ * @param uID integer out: uID is the offset of data row
+ * @param arrProperitesOut array out: properties
+ * @return integer Error state
+ * @see ReadNext
+ */
+ public function ReadNext(&$uID, &$arrProperitesOut, $bParseMessage = true)
+ {
+ // Helpers needed for DB Mapping
+ global $content, $gl_starttime;
+ global $dbmapping, $fields;
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // define $ret
+ $ret = SUCCESS;
+
+ do
+ {
+ // No buffer? then read from DB!
+ if ( $this->bufferedRecords == null )
+ $ret = $this->ReadNextRecordsFromDB($uID);
+ else
+ {
+ if ( !isset($this->bufferedRecords[$this->_currentRecordNum] ) )
+ {
+ // We need to load new records, so clear the old ones first!
+ $this->ResetBufferedRecords();
+
+ // Set new Record start, will be used in the SQL Statement!
+ $this->_currentRecordStart = $this->_currentRecordNum; // + 1;
+
+ // Now read new ones
+ $ret = $this->ReadNextRecordsFromDB($uID);
+
+ // Check if we found more records
+ if ( !isset($this->bufferedRecords[$this->_currentRecordNum] ) )
+ $ret = ERROR_NOMORERECORDS;
+ }
+ }
+
+ if ( $ret == SUCCESS && $this->_arrProperties != null )
+ {
+ // Init and set variables
+ foreach ( $this->_arrProperties as $property )
+ {
+ // Check if mapping exists
+ if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$property]) )
+ {
+ // Copy property if available!
+ $dbfieldname = $dbmapping[$szTableType]['DBMAPPINGS'][$property];
+ if ( isset($this->bufferedRecords[$this->_currentRecordNum][$dbfieldname]) )
+ {
+ if ( isset($fields[$property]['FieldType']) && $fields[$property]['FieldType'] == FILTER_TYPE_DATE ) // Handle as date!
+ $arrProperitesOut[$property] = GetEventTime( $this->bufferedRecords[$this->_currentRecordNum][$dbfieldname] );
+ else
+ $arrProperitesOut[$property] = $this->bufferedRecords[$this->_currentRecordNum][$dbfieldname];
+ }
+ else
+ $arrProperitesOut[$property] = '';
+ }
+ else
+ $arrProperitesOut[$property] = '';
+ }
+
+ // Run optional Message Parsers now
+ if ( isset($arrProperitesOut[SYSLOG_MESSAGE]) )
+ {
+ $retParser = $this->_logStreamConfigObj->ProcessMsgParsers($arrProperitesOut[SYSLOG_MESSAGE], $arrProperitesOut);
+
+ // Check if we have to skip the message!
+ if ( $retParser == ERROR_MSG_SKIPMESSAGE )
+ $ret = $retParser;
+ }
+
+ // Set uID to the PropertiesOut! //DEBUG -> $this->_currentRecordNum;
+ $uID = $arrProperitesOut[SYSLOG_UID] = $this->bufferedRecords[$this->_currentRecordNum][$dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID]];
+
+ // Increment $_currentRecordNum
+ $this->_currentRecordNum++;
+ }
+
+ // Check how long we are running. If only two seconds of execution time are left, we abort further reading!
+ $scriptruntime = intval(microtime_float() - $gl_starttime);
+ if ( $content['MaxExecutionTime'] > 0 && $scriptruntime > ($content['MaxExecutionTime']-2) )
+ {
+ // This may display a warning message, so the user knows we stopped reading records because of the script timeout.
+ $content['logstream_warning'] = "false";
+ $content['logstream_warning_details'] = $content['LN_WARNING_LOGSTREAMDISK_TIMEOUT'];
+ $content['logstream_warning_code'] = ERROR_FILE_NOMORETIME;
+
+ // Return error code
+ return ERROR_FILE_NOMORETIME;
+ }
+
+ // This additional filter check will take care on dynamic fields from the message parser!
+ } while ( $this->ApplyFilters($ret, $arrProperitesOut) != SUCCESS && $ret == SUCCESS );
+
+ // reached here means return result!
+ return $ret;
+ }
+
+ /**
+ * Implementation of Seek
+ */
+ public function Sseek(&$uID, $mode, $numrecs)
+ {
+ // predefine return value
+ $ret = SUCCESS;
+
+ switch ($mode)
+ {
+ case EnumSeek::UID:
+// if ( $uID == UID_UNKNOWN ) // set uID to first ID!
+ {
+ // No buffer? then read from DB!
+ if ( $this->bufferedRecords == null )
+ $ret = $this->ReadNextRecordsFromDB($uID);
+
+ if ( $ret == SUCCESS )
+ {
+ $this->_currentRecordNum = 0;
+ $uID = $this->bufferedRecords[ $this->_currentRecordNum ];
+ }
+ }
+ break;
+ }
+
+ // Return result!
+ return $ret;
+ }
+
+ /**
+ * GetMessageCount will return the count of Message.
+ * If this count is not available, the function will
+ * return the default -1
+ */
+ public function GetMessageCount()
+ {
+ return $this->_totalRecordCount;
+ }
+
+ /**
+ * This function returns the first UID for previous PAGE, if availbale!
+ * Otherwise will return -1!
+ */
+ public function GetPreviousPageUID()
+ {
+ return $this->_previousPageUID;
+ }
+
+ /**
+ * This function returns the FIRST UID for the FIRST PAGE!
+ * Will be done by a seperated SQL Statement.
+ */
+ public function GetFirstPageUID()
+ {
+/* TODO
+ global $querycount, $dbmapping;
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // Only perform query if row counting is enabled!
+ if ( strlen($this->_SQLwhereClause) > 0 && !$this->_logStreamConfigObj->DBEnableRowCounting )
+ return $this->_firstPageUID;
+
+ $szSql = "SELECT MAX(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . ") FROM " . $this->_logStreamConfigObj->DBTableName . $this->_SQLwhereClause;
+ $myQuery = mysql_query($szSql, $this->_dbhandle);
+ if ($myQuery)
+ {
+ // obtain first and only row
+ $myRow = mysql_fetch_row($myQuery);
+ $this->_firstPageUID = $myRow[0];
+
+ // Free query now
+ mysql_free_result ($myQuery);
+
+ // Increment for the Footer Stats
+ $querycount++;
+ }
+
+ // Return result!
+ return $this->_firstPageUID;
+*/
+
+ return -1;
+ }
+
+ /**
+ * This function returns the first UID for the last PAGE!
+ * Will be done by a seperated SQL Statement.
+ */
+ public function GetLastPageUID()
+ {
+/*
+TODO
+ global $querycount, $dbmapping;
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // Only perform query if row counting is enabled!
+ if ( strlen($this->_SQLwhereClause) > 0 && !$this->_logStreamConfigObj->DBEnableRowCounting )
+ return $this->_lastPageUID;
+
+ $szSql = "SELECT MIN(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . ") FROM " . $this->_logStreamConfigObj->DBTableName . $this->_SQLwhereClause;
+ $myQuery = mysql_query($szSql, $this->_dbhandle);
+ if ($myQuery)
+ {
+ // obtain first and only row
+ $myRow = mysql_fetch_row($myQuery);
+ $this->_lastPageUID = $myRow[0];
+
+ // Free query now
+ mysql_free_result ($myQuery);
+
+ // Increment for the Footer Stats
+ $querycount++;
+ }
+
+ // Return result!
+ return $this->_lastPageUID;
+*/
+
+ return -1;
+ }
+
+ /**
+ * This function returns the current Page number, if availbale!
+ * Otherwise will return 0! We also assume that this function is
+ * only called once DB is open!
+ */
+ public function GetCurrentPageNumber()
+ {
+ return $this->_currentPageNumber;
+ }
+
+ /*
+ * Implementation of IsPropertySortable
+ *
+ * For now, sorting is only possible for the UID Property!
+ */
+ public function IsPropertySortable($myProperty)
+ {
+ global $fields;
+
+ // TODO: HARDCODED | FOR NOW only FALSE!
+ return false;
+ }
+
+ /**
+ * Implementation of GetLogStreamStats
+ *
+ * Returns an Array og logstream statsdata
+ * Count of Data Items
+ * Total Filesize
+ */
+ public function GetLogStreamStats()
+ {
+/*
+ global $querycount, $dbmapping;
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // Perform if Connection is true!
+ if ( $this->_dbhandle != null )
+ {
+ // Obtain Stats data for this table!
+ $szSql = "SHOW TABLE STATUS FROM " . $this->_logStreamConfigObj->DBName;
+ $myQuery = mysql_query($szSql, $this->_dbhandle);
+ if ($myQuery)
+ {
+ // Loop through results
+ while ($myRow = mysql_fetch_array($myQuery, MYSQL_ASSOC))
+ {
+ // Set tablename!
+ $tableName = $myRow['Name'];
+ $myStats = null;
+ $myStats[] = array( 'StatsDisplayName' => 'Table name', 'StatsValue' => $tableName );
+
+ // copy usefull statsdata
+ if ( isset($myRow['Engine']) )
+ $myStats[] = array( 'StatsDisplayName' => 'Table engine', 'StatsValue' => $myRow['Engine'] );
+ if ( isset($myRow['Rows']) )
+ $myStats[] = array( 'StatsDisplayName' => 'Rowcount', 'StatsValue' => $myRow['Rows'] );
+
+ if ( isset($myRow['Data_length']) )
+ $myStats[] = array( 'StatsDisplayName' => 'Table filesize (bytes)', 'StatsValue' => $myRow['Data_length'] );
+ if ( isset($myRow['Collation']) )
+ $myStats[] = array( 'StatsDisplayName' => 'Collation', 'StatsValue' => $myRow['Collation'] );
+ if ( isset($myRow['Comment']) )
+ $myStats[] = array( 'StatsDisplayName' => 'Comment', 'StatsValue' => $myRow['Comment'] );
+
+ $stats[]['STATSDATA'] = $myStats;
+ }
+
+ // Free query now
+ mysql_free_result ($myQuery);
+
+ // Increment for the Footer Stats
+ $querycount++;
+ }
+
+ // return results!
+ return $stats;
+ }
+ else
+ return null;
+*/
+
+ // NOT IMPLEMENTED YET!
+ return null;
+ }
+
+ /**
+ * Implementation of GetLogStreamTotalRowCount
+ *
+ * Returns the total amount of rows in the main datatable
+ */
+ public function GetLogStreamTotalRowCount()
+ {
+ global $querycount, $dbmapping;
+
+ // Set default rowcount
+ $rowcount = null;
+
+ // Perform if Connection is true!
+ if ( $this->_myMongoCollection != null )
+ {
+ $rowcount = $this->_myMongoCollection->count();
+ }
+
+ //return result
+ return $rowcount;
+ }
+
+ /**
+ * Implementation of the CleanupLogdataByDate function! Returns affected rows!
+ */
+ public function CleanupLogdataByDate( $nDateTimeStamp )
+ {
+/*
+TODO
+ global $querycount, $dbmapping;
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // Set default rowcount
+ $rowcount = null;
+
+ // Perform if Connection is true!
+ if ( $this->_dbhandle != null )
+ {
+ // --- Init Filters if necessary!
+ if ( $this->_filters == null )
+ $this->SetFilter( "" ); // This will init filters!
+
+ // Create SQL Where Clause!
+ $this->CreateSQLWhereClause();
+ // ---
+
+ // --- Add default WHERE clause
+ if ( strlen($this->_SQLwhereClause) > 0 )
+ $szWhere = $this->_SQLwhereClause;
+ else
+ $szWhere = "";
+
+ // Add Datefilter if necessary!
+ if ( $nDateTimeStamp > 0 )
+ {
+ if ( strlen($szWhere) > 0 )
+ $szWhere .= " AND ";
+ else
+ $szWhere = " WHERE ";
+
+ // Append Date Filter!
+ $szWhere .= " UNIX_TIMESTAMP(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_DATE] . ") < " . $nDateTimeStamp;
+ }
+ // ---
+
+ // DELETE DATA NOW!
+ $szSql = "DELETE FROM " . $this->_logStreamConfigObj->DBTableName . $szWhere;
+ OutputDebugMessage("LogStreamDB|CleanupLogdataByDate: Created SQL Query:
" . $szSql, DEBUG_DEBUG);
+ $myQuery = mysql_query($szSql, $this->_dbhandle);
+ if ($myQuery)
+ {
+ // Get affected rows and return!
+ $rowcount = mysql_affected_rows();
+
+ // Reset AUTO_INCREMENT if all records were deleted!
+ if ( $nDateTimeStamp == 0 )
+ {
+ $szSql = "ALTER TABLE " . $this->_logStreamConfigObj->DBTableName . " AUTO_INCREMENT=0";
+ $myQuery = mysql_query($szSql, $this->_dbhandle);
+ // error occured, output DEBUG message
+ if (!$myQuery)
+ $this->PrintDebugError("CleanupLogdataByDate failed to reset AUTO_INCREMENT for '" . $this->_logStreamConfigObj->DBTableName . "' table. ");
+ }
+
+ // Free result not needed here!
+ //mysql_free_result ($myQuery);
+ }
+ else
+ {
+ // error occured, output DEBUG message
+ $this->PrintDebugError("CleanupLogdataByDate failed with SQL Statement ' " . $szSql . " '");
+ }
+ }
+
+ //return affected rows
+ return $rowcount;
+*/
+
+ //not implemented
+ return null;
+ }
+
+
+ /*
+ * Implementation of the UpdateAllMessageChecksum
+ *
+ * Update all missing checksum properties in the current database
+ */
+ public function UpdateAllMessageChecksum( )
+ {
+/*
+ global $querycount, $dbmapping;
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // UPDATE DATA NOW!
+ $szSql = "UPDATE " . $this->_logStreamConfigObj->DBTableName .
+ " SET " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " = crc32(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_MESSAGE] . ") " .
+ " WHERE " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " IS NULL OR " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " = 0";
+
+ // Output Debug Informations
+ OutputDebugMessage("LogStreamDB|UpdateAllMessageChecksum: Running Created SQL Query:
" . $szSql, DEBUG_ULTRADEBUG);
+
+ // Running SQL Query
+ $myQuery = mysql_query($szSql, $this->_dbhandle);
+ if ($myQuery)
+ {
+ // Debug Output
+ OutputDebugMessage("LogStreamDB|UpdateAllMessageChecksum: Successfully updated Checksum of '" . mysql_affected_rows($this->_dbhandle) . "' datarecords", DEBUG_INFO);
+
+ // Return success
+ return SUCCESS;
+ }
+ else
+ {
+ // error occured, output DEBUG message
+ $this->PrintDebugError("SaveMessageChecksum failed with SQL Statement ' " . $szSql . " '");
+
+ // Failed
+ return ERROR;
+ }
+*/
+
+ return SUCCESS;
+ }
+
+
+ /*
+ * Implementation of the SaveMessageChecksum
+ *
+ * Creates an database UPDATE Statement and performs it!
+ */
+ public function SaveMessageChecksum( $arrProperitesIn )
+ {
+/*
+ global $querycount, $dbmapping;
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ if ( isset($arrProperitesIn[SYSLOG_UID]) && isset($arrProperitesIn[MISC_CHECKSUM]) && isset($dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM]) )
+ {
+ // UPDATE DATA NOW!
+ $szSql = "UPDATE " . $this->_logStreamConfigObj->DBTableName .
+ " SET " . $dbmapping[$szTableType]['DBMAPPINGS'][MISC_CHECKSUM] . " = " . $arrProperitesIn[MISC_CHECKSUM] .
+ " WHERE " . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . " = " . $arrProperitesIn[SYSLOG_UID];
+ $myQuery = mysql_query($szSql, $this->_dbhandle);
+ if ($myQuery)
+ {
+ // Return success
+ return SUCCESS;
+ }
+ else
+ {
+ // error occured, output DEBUG message
+ $this->PrintDebugError("SaveMessageChecksum failed with SQL Statement ' " . $szSql . " '");
+
+ // Failed
+ return ERROR;
+ }
+ }
+ else
+ // Missing important properties
+ return ERROR;
+*/
+
+ return SUCCESS;
+ }
+
+
+ /**
+ * Implementation of ConsolidateItemListByField
+ *
+ * In the native MYSQL Logstream, the database will do most of the work
+ *
+ * @return integer Error stat
+ */
+ public function ConsolidateItemListByField($szConsFieldId, $nRecordLimit, $szSortFieldId, $nSortingOrder)
+ {
+/*
+TODO!!!
+ global $content, $dbmapping, $fields;
+
+ // Copy helper variables, this is just for better readability
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // Check if fields are available
+ if ( !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId]) || !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szSortFieldId]) )
+ return ERROR_DB_DBFIELDNOTFOUND;
+
+ // --- Set Options
+ $nConsFieldType = $fields[$szConsFieldId]['FieldType'];
+
+ if ( $nSortingOrder == SORTING_ORDER_DESC )
+ $szSortingOrder = "DESC";
+ else
+ $szSortingOrder = "ASC";
+ // ---
+
+ // --- Set DB Field names
+ $myDBConsFieldName = $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId];
+ $myDBGroupByFieldName = $myDBConsFieldName;
+ $myDBQueryFields = $myDBConsFieldName . ", ";
+
+ // Set Sorted Field
+ if ( $szConsFieldId == $szSortFieldId )
+ $myDBSortedFieldName = "itemcount";
+ else
+ $myDBSortedFieldName = $szSortFieldId;
+ // ---
+
+ // Special handling for date fields
+ if ( $nConsFieldType == FILTER_TYPE_DATE )
+ {
+ // Helper variable for the select statement
+ $mySelectFieldName = $myDBGroupByFieldName . "Grouped";
+ $myDBQueryFieldName = "DATE( " . $myDBConsFieldName . ") AS " . $myDBGroupByFieldName ;
+ }
+
+ // Set Limit String
+ if ( $nRecordLimit > 0 )
+ $szLimitSql = " LIMIT " . $nRecordLimit;
+ else
+ $szLimitSql = "";
+
+ // Create SQL Where Clause!
+ if ( $this->_SQLwhereClause == "" )
+ {
+ $res = $this->CreateSQLWhereClause();
+ if ( $res != SUCCESS )
+ return $res;
+ }
+
+ // Create SQL String now!
+ $szSql = "SELECT " .
+ $myDBQueryFields .
+ "count(" . $myDBConsFieldName . ") as itemcount " .
+ " FROM " . $this->_logStreamConfigObj->DBTableName .
+ $this->_SQLwhereClause .
+ " GROUP BY " . $myDBGroupByFieldName .
+ " ORDER BY " . $myDBSortedFieldName . " " . $szSortingOrder .
+ $szLimitSql ;
+
+ // Output Debug Informations
+ OutputDebugMessage("LogStreamDB|ConsolidateItemListByField: Running Created SQL Query:
" . $szSql, DEBUG_ULTRADEBUG);
+
+ // Perform Database Query
+ $myquery = mysql_query($szSql, $this->_dbhandle);
+ if ( !$myquery )
+ return ERROR_DB_QUERYFAILED;
+
+ // Initialize Array variable
+ $aResult = array();
+
+ // read data records
+ while ($myRow = mysql_fetch_array($myquery, MYSQL_ASSOC))
+ {
+ // Create new row
+ $aNewRow = array();
+
+ foreach ( $myRow as $myFieldName => $myFieldValue )
+ {
+ if ( $myFieldName == $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId] )
+ $aNewRow[$szConsFieldId] = $myFieldValue;
+ else
+ $aNewRow[$myFieldName] = $myFieldValue;
+ }
+
+ // Add new row to result
+ $aResult[] = $aNewRow;
+ }
+
+ // return finished array
+ if ( count($aResult) > 0 )
+ return $aResult;
+ else
+ return ERROR_NOMORERECORDS;
+
+*/
+
+ // NOT IMPLEMENTED
+ return ERROR_NOMORERECORDS;
+ }
+
+
+ /**
+ * Implementation of ConsolidateDataByField
+ *
+ * In the native MYSQL Logstream, the database will do most of the work
+ *
+ * @return integer Error stat
+ */
+ public function ConsolidateDataByField($szConsFieldId, $nRecordLimit, $szSortFieldId, $nSortingOrder, $aIncludeCustomFields = null, $bIncludeLogStreamFields = false, $bIncludeMinMaxDateFields = false)
+ {
+/*
+TODO!!!
+
+ global $content, $dbmapping, $fields;
+
+ // Copy helper variables, this is just for better readability
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // Check if fields are available
+ if ( !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId]) || !isset($dbmapping[$szTableType]['DBMAPPINGS'][$szSortFieldId]) )
+ return ERROR_DB_DBFIELDNOTFOUND;
+
+ // --- Set Options
+ $nConsFieldType = $fields[$szConsFieldId]['FieldType'];
+
+ if ( $nSortingOrder == SORTING_ORDER_DESC )
+ $szSortingOrder = "DESC";
+ else
+ $szSortingOrder = "ASC";
+ // ---
+
+ // --- Set DB Field names
+ $myDBConsFieldName = $dbmapping[$szTableType]['DBMAPPINGS'][$szConsFieldId];
+ $myDBGroupByFieldName = $myDBConsFieldName;
+
+ // Check which fields to include
+ if ( $aIncludeCustomFields != null )
+ {
+ $myDBQueryFields = "";
+ foreach ( $aIncludeCustomFields as $myFieldName )
+ {
+ if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName]) )
+ $myDBQueryFields .= $dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName] . ", ";
+ }
+
+ // Append Sortingfield
+ if ( !in_array($szConsFieldId, $aIncludeCustomFields) )
+ $myDBQueryFields .= $myDBConsFieldName . ", ";
+ }
+ else if ( $bIncludeLogStreamFields )
+ {
+ $myDBQueryFields = "";
+ foreach ( $this->_arrProperties as $myFieldName )
+ {
+ if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName]) )
+ $myDBQueryFields .= $dbmapping[$szTableType]['DBMAPPINGS'][$myFieldName] . ", ";
+ }
+ }
+ else // Only Include ConsolidateField
+ $myDBQueryFields = $myDBConsFieldName . ", ";
+
+ // Add Min and Max fields for DATE if desired
+ if ( $bIncludeMinMaxDateFields )
+ {
+ $myDBQueryFields .= "Min(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_DATE] . ") as firstoccurrence_date, ";
+ $myDBQueryFields .= "Max(" . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_DATE] . ") as lastoccurrence_date, ";
+ }
+
+ if ( $szConsFieldId == $szSortFieldId )
+ $myDBSortedFieldName = "itemcount";
+ else
+ $myDBSortedFieldName = $szSortFieldId;
+ // ---
+
+ // Special handling for date fields
+ if ( $nConsFieldType == FILTER_TYPE_DATE )
+ {
+ // Helper variable for the select statement
+ $mySelectFieldName = $myDBGroupByFieldName . "Grouped";
+ $myDBQueryFieldName = "DATE( " . $myDBConsFieldName . ") AS " . $myDBGroupByFieldName ;
+ }
+
+ // Set Limit String
+ if ( $nRecordLimit > 0 )
+ $szLimitSql = " LIMIT " . $nRecordLimit;
+ else
+ $szLimitSql = "";
+
+ // Create SQL Where Clause!
+ if ( strlen($this->_SQLwhereClause) <= 0 )
+ {
+ $res = $this->CreateSQLWhereClause();
+ if ( $res != SUCCESS )
+ return $res;
+ }
+
+ // Create SQL String now!
+ $szSql = "SELECT " .
+ $myDBQueryFields .
+ "count(" . $myDBConsFieldName . ") as itemcount " .
+ " FROM " . $this->_logStreamConfigObj->DBTableName .
+ $this->_SQLwhereClause .
+ " GROUP BY " . $myDBGroupByFieldName .
+ " ORDER BY " . $myDBSortedFieldName . " " . $szSortingOrder .
+ $szLimitSql ;
+
+ // Output Debug Informations
+ OutputDebugMessage("LogStreamDB|ConsolidateDataByField: Running Created SQL Query:
" . $szSql, DEBUG_ULTRADEBUG);
+
+ // Perform Database Query
+ $myquery = mysql_query($szSql, $this->_dbhandle);
+ if ( !$myquery )
+ return ERROR_DB_QUERYFAILED;
+
+ // Initialize Array variable
+ $aResult = array();
+
+ // read data records
+ while ($myRow = mysql_fetch_array($myquery, MYSQL_ASSOC))
+ {
+ // Create new row
+ $aNewRow = array();
+
+ foreach ( $myRow as $myFieldName => $myFieldValue )
+ {
+ $myFieldID = $this->GetFieldIDbyDatabaseMapping($szTableType, $myFieldName);
+ $aNewRow[ $myFieldID ] = $myFieldValue;
+
+// }
+ }
+ // Add new row to result
+ $aResult[] = $aNewRow;
+ }
+
+ // return finished array
+ if ( count($aResult) > 0 )
+ return $aResult;
+ else
+ return ERROR_NOMORERECORDS;
+*/
+
+ // NOT IMPLEMENTED
+ return ERROR_NOMORERECORDS;
+ }
+
+ /**
+ * Implementation of GetCountSortedByField
+ *
+ * In the native MYSQL Logstream, the database will do most of the work
+ *
+ * @return integer Error stat
+ */
+ public function GetCountSortedByField($szFieldId, $nFieldType, $nRecordLimit)
+ {
+/*
+TODO!!!
+ global $content, $dbmapping;
+
+ // Copy helper variables, this is just for better readability
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$szFieldId]) )
+ {
+ // Set DB Field name first!
+ $myDBFieldName = $dbmapping[$szTableType]['DBMAPPINGS'][$szFieldId];
+ $myDBQueryFieldName = $myDBFieldName;
+ $mySelectFieldName = $myDBFieldName;
+
+ // Special handling for date fields
+ if ( $nFieldType == FILTER_TYPE_DATE )
+ {
+ // Helper variable for the select statement
+ $mySelectFieldName = $mySelectFieldName . "Grouped";
+ $myDBQueryFieldName = "DATE( " . $myDBFieldName . ") AS " . $mySelectFieldName ;
+ }
+
+ // Create SQL Where Clause!
+ if ( $this->_SQLwhereClause == "" )
+ {
+ $res = $this->CreateSQLWhereClause();
+ if ( $res != SUCCESS )
+ return $res;
+ }
+
+ // Create SQL String now!
+ $szSql = "SELECT " .
+ $myDBQueryFieldName . ", " .
+ "count(" . $myDBFieldName . ") as TotalCount " .
+ " FROM " . $this->_logStreamConfigObj->DBTableName .
+ $this->_SQLwhereClause .
+ " GROUP BY " . $mySelectFieldName .
+ " ORDER BY TotalCount DESC" .
+ " LIMIT " . $nRecordLimit;
+
+ // Perform Database Query
+ $myquery = mysql_query($szSql, $this->_dbhandle);
+ if ( !$myquery )
+ return ERROR_DB_QUERYFAILED;
+
+ // Initialize Array variable
+ $aResult = array();
+
+ // read data records
+ while ($myRow = mysql_fetch_array($myquery, MYSQL_ASSOC))
+ $aResult[ $myRow[$mySelectFieldName] ] = $myRow['TotalCount'];
+
+ // return finished array
+ if ( count($aResult) > 0 )
+ return $aResult;
+ else
+ return ERROR_NOMORERECORDS;
+ }
+ else
+ {
+ // return error code, field mapping not found
+ return ERROR_DB_DBFIELDNOTFOUND;
+ }
+*/
+
+ // NOT IMPLEMENTED
+ return ERROR_NOMORERECORDS;
+ }
+
+
+
+ /*
+ * ============= Beginn of private functions =============
+ */
+
+ /*
+ * This function expects the filters to already being set earlier.
+ * Otherwise no usual WHERE Clause can be created!
+ */
+ private function CreateSQLWhereClause()
+ {
+ // DEBUG FOF NOW
+ return SUCCESS;
+
+ if ( $this->_filters != null )
+ {
+ global $dbmapping;
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // Reset WhereClause
+ $this->_SQLwhereClause = "";
+
+ // --- Build Query Array
+ $arrayQueryProperties = $this->_arrProperties;
+ if ( isset($this->_arrFilterProperties) && $this->_arrFilterProperties != null)
+ {
+ foreach ( $this->_arrFilterProperties as $filterproperty )
+ {
+ if ( $this->_arrProperties == null || !in_array($filterproperty, $this->_arrProperties) )
+ $arrayQueryProperties[] = $filterproperty;
+ }
+ }
+ // ---
+
+ // Loop through all available properties
+ foreach( $arrayQueryProperties as $propertyname )
+ {
+ // If the property exists in the filter array, we have something to filter for ^^!
+ if ( array_key_exists($propertyname, $this->_filters) )
+ {
+ // Process all filters
+ foreach( $this->_filters[$propertyname] as $myfilter )
+ {
+ // Only perform if database mapping is available for this filter!
+ if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$propertyname]) )
+ {
+ switch( $myfilter[FILTER_TYPE] )
+ {
+ case FILTER_TYPE_STRING:
+ // --- Either make a LIKE or a equal query!
+ if ( $myfilter[FILTER_MODE] & FILTER_MODE_SEARCHFULL )
+ {
+ // Set addnot to nothing
+ $addnod = "";
+
+ // --- Check if user wants to include or exclude!
+ if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE)
+ {
+ $szSearchBegin = " = '";
+ $szSearchEnd = "' ";
+ }
+ else
+ {
+ $szSearchBegin = " <> '";
+ $szSearchEnd = "' ";
+ }
+ // ---
+ }
+ else if ( $myfilter[FILTER_MODE] & FILTER_MODE_SEARCHREGEX )
+ {
+ // --- Check if user wants to include or exclude!
+ if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE)
+ $addnod = "";
+ else
+ $addnod = " NOT";
+ // ---
+
+ $szSearchBegin = " REGEXP '";
+ $szSearchEnd = "' ";
+ }
+ else
+ {
+ // --- Check if user wants to include or exclude!
+ if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE)
+ $addnod = "";
+ else
+ $addnod = " NOT";
+ // ---
+
+ $szSearchBegin = " LIKE '%";
+ $szSearchEnd = "%' ";
+ }
+ // ---
+
+ // --- If Syslog message, we have AND handling, otherwise OR!
+ if ( $propertyname == SYSLOG_MESSAGE )
+ $addor = " AND ";
+ else
+ {
+ // If we exclude filters, we need to combine with AND
+ if ( $myfilter[FILTER_MODE] & FILTER_MODE_INCLUDE)
+ $addor = " OR ";
+ else
+ $addor = " AND ";
+ }
+ // ---
+
+ // Now Create LIKE Filters
+ if ( isset($tmpfilters[$propertyname]) )
+ $tmpfilters[$propertyname][FILTER_VALUE] .= $addor . $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . $addnod . $szSearchBegin . DB_RemoveBadChars($myfilter[FILTER_VALUE]) . $szSearchEnd;
+ else
+ {
+ $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_STRING;
+ $tmpfilters[$propertyname][FILTER_VALUE] = $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . $addnod . $szSearchBegin . DB_RemoveBadChars($myfilter[FILTER_VALUE]) . $szSearchEnd;
+ }
+ break;
+ case FILTER_TYPE_NUMBER:
+ // --- Check if user wants to include or exclude!
+ if ( $myfilter[FILTER_MODE] & FILTER_MODE_EXCLUDE )
+ {
+ // Add to filterset
+ $szArrayKey = $propertyname . "-NOT";
+ if ( isset($tmpfilters[$szArrayKey]) )
+ $tmpfilters[$szArrayKey][FILTER_VALUE] .= ", " . $myfilter[FILTER_VALUE];
+ else
+ {
+ $tmpfilters[$szArrayKey][FILTER_TYPE] = FILTER_TYPE_NUMBER;
+ $tmpfilters[$szArrayKey][FILTER_VALUE] = $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " NOT IN (" . DB_RemoveBadChars($myfilter[FILTER_VALUE]);
+ }
+ }
+ else
+ {
+ // Add to filterset
+ if ( isset($tmpfilters[$propertyname]) )
+ $tmpfilters[$propertyname][FILTER_VALUE] .= ", " . $myfilter[FILTER_VALUE];
+ else
+ {
+ $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_NUMBER;
+ $tmpfilters[$propertyname][FILTER_VALUE] = $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " IN (" . DB_RemoveBadChars($myfilter[FILTER_VALUE]);
+ }
+ }
+ // ---
+ break;
+ case FILTER_TYPE_DATE:
+ if ( isset($tmpfilters[$propertyname]) )
+ $tmpfilters[$propertyname][FILTER_VALUE] .= " AND ";
+ else
+ {
+ $tmpfilters[$propertyname][FILTER_VALUE] = "";
+ $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_DATE;
+ }
+
+ if ( $myfilter[FILTER_DATEMODE] == DATEMODE_LASTX )
+ {
+ // Get current timestamp
+ $nNowTimeStamp = time();
+
+ if ( $myfilter[FILTER_VALUE] == DATE_LASTX_HOUR )
+ $nNowTimeStamp -= 60 * 60; // One Hour!
+ else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_12HOURS )
+ $nNowTimeStamp -= 60 * 60 * 12; // 12 Hours!
+ else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_24HOURS )
+ $nNowTimeStamp -= 60 * 60 * 24; // 24 Hours!
+ else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_7DAYS )
+ $nNowTimeStamp -= 60 * 60 * 24 * 7; // 7 days
+ else if ( $myfilter[FILTER_VALUE] == DATE_LASTX_31DAYS )
+ $nNowTimeStamp -= 60 * 60 * 24 * 31; // 31 days
+ else
+ {
+ // Set filter to unknown and Abort in this case!
+ $tmpfilters[$propertyname][FILTER_TYPE] = FILTER_TYPE_UNKNOWN;
+ break;
+ }
+
+ // Append filter
+ $tmpfilters[$propertyname][FILTER_VALUE] .= $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " > '" . date("Y-m-d H:i:s", $nNowTimeStamp) . "'";
+ }
+ else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_RANGE_FROM )
+ {
+ // Obtain Event struct for the time!
+ $myeventtime = GetEventTime($myfilter[FILTER_VALUE]);
+ $tmpfilters[$propertyname][FILTER_VALUE] .= $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " > '" . date("Y-m-d H:i:s", $myeventtime[EVTIME_TIMESTAMP]) . "'";
+ }
+ else if ( $myfilter[FILTER_DATEMODE] == DATEMODE_RANGE_TO )
+ {
+ // Obtain Event struct for the time!
+ $myeventtime = GetEventTime($myfilter[FILTER_VALUE]);
+ $tmpfilters[$propertyname][FILTER_VALUE] .= $dbmapping[$szTableType]['DBMAPPINGS'][$propertyname] . " < '" . date("Y-m-d H:i:s", $myeventtime[EVTIME_TIMESTAMP]) . "'";
+ }
+
+ break;
+ default:
+ // Nothing to do!
+ break;
+ }
+ }
+ else
+ {
+ // Check how to treat not found db mappings / filters
+ if ( GetConfigSetting("TreatNotFoundFiltersAsTrue", 0, CFGLEVEL_USER) == 0 )
+ return ERROR_DB_DBFIELDNOTFOUND;
+ }
+ }
+ }
+ }
+
+ // Check and combine all filters now!
+ if ( isset($tmpfilters) )
+ {
+ // Append filters
+ foreach( $tmpfilters as $tmpfilter )
+ {
+ // Init WHERE or Append AND
+ if ( strlen($this->_SQLwhereClause) > 0 )
+ $this->_SQLwhereClause .= " AND ";
+ else
+ $this->_SQLwhereClause = " WHERE ";
+
+ switch( $tmpfilter[FILTER_TYPE] )
+ {
+ case FILTER_TYPE_STRING:
+ $this->_SQLwhereClause .= "( " . $tmpfilter[FILTER_VALUE] . ") ";
+ break;
+ case FILTER_TYPE_NUMBER:
+ $this->_SQLwhereClause .= $tmpfilter[FILTER_VALUE] . ") ";
+ break;
+ case FILTER_TYPE_DATE:
+ $this->_SQLwhereClause .= $tmpfilter[FILTER_VALUE];
+ break;
+ default:
+ // Should not happen, wrong filters!
+ // We add a dummy into the where clause, just as a place holder
+ $this->_SQLwhereClause .= " 1=1 ";
+ break;
+ }
+ }
+ }
+
+// echo $this->_SQLwhereClause;
+ //$dbmapping[$szTableType][SYSLOG_UID]
+ }
+ else // No filters means nothing to do!
+ return SUCCESS;
+ }
+
+ /*
+ * This helper function will read the next records into the buffer.
+ */
+ private function ReadNextRecordsFromDB($uID)
+ {
+ global $querycount, $dbmapping;
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // return error if there was one!
+ if ( ($res = $this->CreateMainSQLQuery($uID)) != SUCCESS )
+ return $res;
+
+ // Append LIMIT clause
+// $szSql .= " LIMIT " . $this->_currentRecordStart . ", " . $this->_logStreamConfigObj->RecordsPerQuery;
+
+ $myCursor = $this->_myMongoCollection->find(); // ->limit(10); // $collection->find();
+ $myCursor = $myCursor->sort(array("_id" => -1));
+
+ // Copy rows into the buffer!
+ $iBegin = $this->_currentRecordNum;
+
+ while ($myRow = $myCursor->getNext())
+ {
+ // Check if result was successfull!
+ if ( $myRow === FALSE || !$myRow )
+ break;
+
+ $myRow[ "_id" ] = $myRow["_id"]->{'$id'};
+
+ // Keys will be converted into lowercase!
+ $this->bufferedRecords[$iBegin] = array_change_key_case( $myRow, CASE_LOWER);
+ $iBegin++;
+ }
+
+ // --- Check if results were found
+ if ( $iBegin == $this->_currentRecordNum )
+ return ERROR_NOMORERECORDS;
+ // ---
+/*
+ // Only obtain count if enabled and not done before
+ if ( $this->_logStreamConfigObj->DBEnableRowCounting && $this->_totalRecordCount == -1 )
+ {
+ $this->_totalRecordCount = $this->GetRowCountFromTable();
+
+ if ( $this->_totalRecordCount <= 0 )
+ return ERROR_NOMORERECORDS;
+ }
+*/
+ // Increment for the Footer Stats
+ $querycount++;
+
+ // return success state if reached this point!
+ return SUCCESS;
+ }
+
+ /*
+ * Create the SQL QUery!
+ */
+ private function CreateMainSQLQuery($uID)
+ {
+/*
+ global $querycount;
+
+ // Get SQL Statement
+ $szSql = $this->CreateSQLStatement($uID);
+
+ // --- Append LIMIT
+ $szSql .= " LIMIT " . $this->_logStreamConfigObj->RecordsPerQuery;
+ // ---
+
+ // Perform Database Query
+ $this->_myDBQuery = mysql_query($szSql, $this->_dbhandle);
+ if ( !$this->_myDBQuery )
+ {
+ // Check if a field is missing!
+ if ( mysql_errno() == 1054 )
+ {
+ // Handle missing field and try again!
+ if ( $this->HandleMissingField() == SUCCESS )
+ {
+ $this->_myDBQuery = mysql_query($szSql, $this->_dbhandle);
+ if ( !$this->_myDBQuery )
+ {
+ $this->PrintDebugError("Invalid SQL: ".$szSql);
+ return ERROR_DB_QUERYFAILED;
+ }
+ }
+ else // Failed to add field dynamically
+ return ERROR_DB_QUERYFAILED;
+ }
+ else
+ {
+ $this->PrintDebugError("Invalid SQL: ".$szSql);
+ return ERROR_DB_QUERYFAILED;
+ }
+ }
+ else
+ {
+ // Skip one entry in this case
+ if ( $this->_currentRecordStart > 0 )
+ {
+ // Throw away
+ $myRow = mysql_fetch_array($this->_myDBQuery, MYSQL_ASSOC);
+ }
+ }
+
+ // Increment for the Footer Stats
+ $querycount++;
+
+ // Output Debug Informations
+ OutputDebugMessage("LogStreamDB|CreateMainSQLQuery: Created SQL Query:
" . $szSql, DEBUG_DEBUG);
+
+ // return success state if reached this point!
+ return SUCCESS;
+*/
+
+ return SUCCESS;
+ }
+
+ /*
+ * Creates the SQL Statement we are going to use!
+ */
+ private function CreateSQLStatement($uID, $includeFields = true)
+ {
+/*
+ global $dbmapping;
+
+ // Copy helper variables, this is just for better readability
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+ $szSortColumn = $this->_logStreamConfigObj->SortColumn;
+
+ // Create Basic SQL String
+ if ( $this->_logStreamConfigObj->DBEnableRowCounting ) // with SQL_CALC_FOUND_ROWS
+ $sqlString = "SELECT SQL_CALC_FOUND_ROWS " . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID];
+ else // without row calc
+ $sqlString = "SELECT " . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID];
+
+ // Append fields if needed
+ if ( $includeFields && $this->_arrProperties != null )
+ {
+ // Loop through all requested fields
+ foreach ( $this->_arrProperties as $myproperty )
+ {
+ // SYSLOG_UID already added!
+ if ( $myproperty != SYSLOG_UID && isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) )
+ {
+ // Append field!
+ $sqlString .= ", " . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty];
+ }
+ }
+ }
+
+ // Append FROM 'table'!
+ $sqlString .= " FROM " . $this->_logStreamConfigObj->DBTableName;
+
+ // Append precreated where clause
+ $sqlString .= $this->_SQLwhereClause;
+
+ // Append UID QUERY!
+ if ( $uID != -1 )
+ {
+ if ( $this->_readDirection == EnumReadDirection::Forward )
+ $myOperator = ">=";
+ else
+ $myOperator = "<=";
+
+ if ( strlen($this->_SQLwhereClause) > 0 )
+ $sqlString .= " AND " . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . " $myOperator $uID";
+ else
+ $sqlString .= " WHERE " . $dbmapping[$szTableType]['DBMAPPINGS'][SYSLOG_UID] . " $myOperator $uID";
+ }
+
+ // Append ORDER clause
+ if ( $this->_readDirection == EnumReadDirection::Forward )
+ $sqlString .= " ORDER BY " . $dbmapping[$szTableType]['DBMAPPINGS'][$szSortColumn];
+ else if ( $this->_readDirection == EnumReadDirection::Backward )
+ $sqlString .= " ORDER BY " . $dbmapping[$szTableType]['DBMAPPINGS'][$szSortColumn] . " DESC";
+
+ // return SQL result string:
+ return $sqlString;
+
+*/
+ return "";
+ }
+
+ /*
+ * Reset record buffer in this function!
+ */
+ private function ResetBufferedRecords()
+ {
+ if ( isset($this->bufferedRecords) )
+ {
+ // Loop through all subrecords first!
+ foreach ($this->bufferedRecords as $mykey => $myrecord)
+ unset( $this->bufferedRecords[$mykey] );
+
+ // Set buffered records to NULL!
+ $this->bufferedRecords = null;
+ }
+ }
+
+ /*
+ * Helper function to display SQL Errors for now!
+ */
+ private function PrintDebugError($szErrorMsg)
+ {
+ global $extraErrorDescription;
+
+ $errdesc = mysql_error();
+ $errno = mysql_errno();
+
+ $errormsg="$szErrorMsg
";
+ $errormsg.="Detail error: $errdesc
";
+ $errormsg.="Error Code: $errno
";
+
+ // Add to additional error output
+ $extraErrorDescription = $errormsg;
+
+ //Output!
+ OutputDebugMessage("LogStreamDB|PrintDebugError: $errormsg", DEBUG_ERROR);
+ }
+
+ /*
+ * Returns the number of possible records by using a query
+ */
+ private function GetRowCountByString($szQuery)
+ {
+ if ($myQuery = mysql_query($szQuery))
+ {
+ $num_rows = mysql_num_rows($myQuery);
+ mysql_free_result ($myQuery);
+ }
+ return $num_rows;
+ }
+
+ /*
+ * Returns the number of possible records by using an existing queryid
+ */
+ private function GetRowCountByQueryID($myQuery)
+ {
+ $num_rows = mysql_num_rows($myQuery);
+ return $num_rows;
+ }
+
+ /*
+ * Returns the number of possible records by using a select count statement!
+ */
+ private function GetRowCountFromTable()
+ {
+ if ( $myquery = mysql_query("Select FOUND_ROWS();", $this->_dbhandle) )
+ {
+ // Get first and only row!
+ $myRow = mysql_fetch_array($myquery);
+
+ // copy row count
+ $numRows = $myRow[0];
+ }
+ else
+ $numRows = -1;
+
+ // return result!
+ return $numRows;
+
+ /* OLD slow code!
+ global $dbmapping,$querycount;
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // Create Statement and perform query!
+ $szSql = "SELECT count(" . $dbmapping[$szTableType][SYSLOG_UID] . ") FROM " . $this->_logStreamConfigObj->DBTableName . $this->_SQLwhereClause;
+ if ($myQuery = mysql_query($szSql, $this->_dbhandle))
+ {
+ // obtain first and only row
+ $myRow = mysql_fetch_row($myQuery);
+ $numRows = $myRow[0];
+
+ // Increment for the Footer Stats
+ $querycount++;
+
+ // Free query now
+ mysql_free_result ($myQuery);
+ }
+ else
+ $numRows = -1;
+ */
+ }
+
+ /*
+ * Function handles missing database fields automatically!
+ */
+ private function HandleMissingField( $szMissingField = null, $arrProperties = null )
+ {
+ global $dbmapping, $fields;
+
+ // Get Err description
+ $errdesc = mysql_error();
+
+ // Try to get missing field from SQL Error of not specified as argument
+ if ( $szMissingField == null )
+ {
+ if ( preg_match("/Unknown column '(.*?)' in '(.*?)'$/", $errdesc, $errOutArr ) )
+ $szMissingField = $errOutArr[1];
+ else
+ {
+ $this->PrintDebugError("ER_BAD_FIELD_ERROR - SQL Statement: ". $errdesc);
+ return ERROR_DB_DBFIELDNOTFOUND;
+ }
+ }
+
+ // Set Properties to default if NULL
+ if ( $arrProperties == null )
+ $arrProperties = $this->_arrProperties;
+
+ // Get Tabletype
+ $szTableType = $this->_logStreamConfigObj->DBTableType;
+
+ // Loop through all fields to see which one is missing!
+ foreach ( $arrProperties as $myproperty )
+ {
+ if ( isset($dbmapping[$szTableType]['DBMAPPINGS'][$myproperty]) && $szMissingField == $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] )
+ {
+ // Create SQL Numeric field
+ $szUpdateSql = ""; $szUnsigned = "";
+ if ( $fields[$myproperty]['FieldType'] == FILTER_TYPE_NUMBER )
+ {
+ // This will add the checksum field as unsigned automatically!
+ if ( $myproperty == MISC_CHECKSUM )
+ $szUnsigned = "UNSIGNED";
+ $szUpdateSql = "ALTER TABLE `" . $this->_logStreamConfigObj->DBTableName . "` ADD `" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "` int(11) " . $szUnsigned . " NOT NULL DEFAULT '0'";
+ }
+ if ( $fields[$myproperty]['FieldType'] == FILTER_TYPE_STRING )
+ $szUpdateSql = "ALTER TABLE `" . $this->_logStreamConfigObj->DBTableName . "` ADD `" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "` varchar(60) NOT NULL DEFAULT ''";
+ if ( $fields[$myproperty]['FieldType'] == FILTER_TYPE_DATE )
+ $szUpdateSql = "ALTER TABLE `" . $this->_logStreamConfigObj->DBTableName . "` ADD `" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "` datetime NOT NULL DEFAULT '0000-00-00 00:00:00'";
+
+ if ( strlen($szUpdateSql) > 0 )
+ {
+ // Update Table schema now!
+ $myQuery = mysql_query($szUpdateSql, $this->_dbhandle);
+ if (!$myQuery)
+ {
+ // Return failure!
+ $this->PrintDebugError("ER_BAD_FIELD_ERROR - Dynamically Adding field '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' with Statement failed: '" . $szUpdateSql . "'");
+ return ERROR_DB_ADDDBFIELDFAILED;
+ }
+ }
+ else
+ {
+ // Return failure!
+ $this->PrintDebugError("ER_BAD_FIELD_ERROR - Field '" . $dbmapping[$szTableType]['DBMAPPINGS'][$myproperty] . "' is missing has to be added manually to the database layout!'");
+ return ERROR_DB_ADDDBFIELDFAILED;
+ }
+ }
+ }
+
+ // Reached this point means success!
+ return SUCCESS;
+ }
+
+ /*
+ * Helper function to return a list of Indexes for the logstream table
+ */
+ private function GetIndexesAsArray()
+ {
+ global $querycount;
+
+ // Verify database connection (This also opens the database!)
+ $res = $this->Verify();
+ if ( $res != SUCCESS )
+ return $res;
+
+ // Init Array
+ $arrIndexKeys = array();
+
+ // Create SQL and Get INDEXES for table!
+ $szSql = "SHOW INDEX FROM " . $this->_logStreamConfigObj->DBTableName;
+ $myQuery = mysql_query($szSql, $this->_dbhandle);
+ if ($myQuery)
+ {
+ // Loop through results
+ while ($myRow = mysql_fetch_array($myQuery, MYSQL_ASSOC))
+ {
+ // Add to index keys
+ $arrIndexKeys[] = strtolower($myRow['Key_name']);
+ }
+
+ // Free query now
+ mysql_free_result ($myQuery);
+
+ // Increment for the Footer Stats
+ $querycount++;
+ }
+
+ // return Array
+ return $arrIndexKeys;
+ }
+
+
+ /*
+ * Helper function to return a list of Fields from the logstream table
+ */
+ private function GetFieldsAsArray()
+ {
+ global $querycount;
+
+ // Verify database connection (This also opens the database!)
+ $res = $this->Verify();
+ if ( $res != SUCCESS )
+ return $res;
+
+ // Init Array
+ $arrFieldKeys = array();
+
+ // Create SQL and Get INDEXES for table!
+ $szSql = "SHOW FIELDS FROM " . $this->_logStreamConfigObj->DBTableName;
+ $myQuery = mysql_query($szSql, $this->_dbhandle);
+ if ($myQuery)
+ {
+ // Loop through results
+ while ($myRow = mysql_fetch_array($myQuery, MYSQL_ASSOC))
+ {
+ // Add to index keys
+ $arrFieldKeys[] = strtolower($myRow['Field']);
+ }
+
+ // Free query now
+ mysql_free_result ($myQuery);
+
+ // Increment for the Footer Stats
+ $querycount++;
+ }
+
+ // return Array
+ return $arrFieldKeys;
+ }
+
+
+ /*
+ * Helper function to return a list of Indexes for the logstream table
+ */
+ private function GetTriggersAsArray()
+ {
+ global $querycount;
+
+ // Verify database connection (This also opens the database!)
+ $res = $this->Verify();
+ if ( $res != SUCCESS )
+ return $res;
+
+ // Init Array
+ $arrIndexTriggers = array();
+
+ // Create SQL and Get INDEXES for table!
+ $szSql = "SHOW TRIGGERS";
+ $myQuery = mysql_query($szSql, $this->_dbhandle);
+ if ($myQuery)
+ {
+ // Loop through results
+ while ($myRow = mysql_fetch_array($myQuery, MYSQL_ASSOC))
+ {
+// print_r ( $myRow );
+ // Add to index keys
+ $arrIndexTriggers[] = strtolower($myRow['Trigger']);
+ }
+
+ // Free query now
+ mysql_free_result ($myQuery);
+
+ // Increment for the Footer Stats
+ $querycount++;
+ }
+
+ // return Array
+ return $arrIndexTriggers;
+ }
+
+// --- End of Class!
+}
+
+?>
\ No newline at end of file
diff --git a/src/images/icons/mongodb.png b/src/images/icons/mongodb.png
new file mode 100644
index 0000000..58e844a
Binary files /dev/null and b/src/images/icons/mongodb.png differ
diff --git a/src/include/constants_general.php b/src/include/constants_general.php
index 055ada0..04e3369 100644
--- a/src/include/constants_general.php
+++ b/src/include/constants_general.php
@@ -71,6 +71,7 @@ define('CFGLEVEL_USER', 2);
define('SOURCE_DISK', '1');
define('SOURCE_DB', '2');
define('SOURCE_PDO', '3');
+define('SOURCE_MONGODB', '4');
// ---
// --- Exportformat defines
diff --git a/src/include/constants_logstream.php b/src/include/constants_logstream.php
index f7e920b..68c9525 100644
--- a/src/include/constants_logstream.php
+++ b/src/include/constants_logstream.php
@@ -376,6 +376,18 @@ $dbmapping['syslogng']['DBMAPPINGS'][SYSLOG_MESSAGE] = "msg";
$dbmapping['syslogng']['DBMAPPINGS'][SYSLOG_SYSLOGTAG] = "tag";
$dbmapping['syslogng']['DBMAPPINGS'][SYSLOG_PROCESSID] = "program";
+$dbmapping['mongodb']['ID'] = "mongodb";
+$dbmapping['mongodb']['DisplayName'] = "MongoDB";
+$dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_UID] = "_id";
+$dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_DATE] = "time";
+$dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_HOST] = "sys";
+$dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_MESSAGE] = "msg";
+// $dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_FACILITY] = "Facility";
+$dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_SEVERITY] = "level";
+$dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_SYSLOGTAG] = "procid";
+//$dbmapping['mongodb']['DBMAPPINGS'][SYSLOG_PROCESSID] = "ProcessID";
+$dbmapping['mongodb']['DBMAPPINGS'][MISC_CHECKSUM] = "Checksum";
+
// Convert all fieldnames to lowercase to avoid problems with case sensitive array keys later
foreach( $dbmapping as &$myMapping )
{
diff --git a/src/include/functions_common.php b/src/include/functions_common.php
index bbc57c1..47b07b0 100644
--- a/src/include/functions_common.php
+++ b/src/include/functions_common.php
@@ -251,6 +251,11 @@ function CreateSourceTypesList( $selectedSource )
$content['SOURCETYPES'][SOURCE_PDO]['type'] = SOURCE_PDO;
$content['SOURCETYPES'][SOURCE_PDO]['DisplayName'] = $content['LN_GEN_SOURCE_PDO'];
if ( $selectedSource == $content['SOURCETYPES'][SOURCE_PDO]['type'] ) { $content['SOURCETYPES'][SOURCE_PDO]['selected'] = "selected"; } else { $content['SOURCETYPES'][SOURCE_PDO]['selected'] = ""; }
+
+ // SOURCE_MONGODB ( MONGODB Wrapper)
+ $content['SOURCETYPES'][SOURCE_MONGODB]['type'] = SOURCE_MONGODB;
+ $content['SOURCETYPES'][SOURCE_MONGODB]['DisplayName'] = $content['LN_GEN_SOURCE_MONGODB'];
+ if ( $selectedSource == $content['SOURCETYPES'][SOURCE_MONGODB]['type'] ) { $content['SOURCETYPES'][SOURCE_MONGODB]['selected'] = "selected"; } else { $content['SOURCETYPES'][SOURCE_MONGODB]['selected'] = ""; }
}
function CreateAuthTypesList( $selectedAuth )
@@ -728,6 +733,7 @@ function InitFrontEndVariables()
$content['MENU_SOURCE_DISK'] = $content['BASEPATH'] . "images/icons/document_text.png";
$content['MENU_SOURCE_DB'] = $content['BASEPATH'] . "images/icons/data_table.png";
$content['MENU_SOURCE_PDO'] = $content['BASEPATH'] . "images/icons/data_gear.png";
+ $content['MENU_SOURCE_MONGODB'] = $content['BASEPATH'] . "images/icons/mongodb.png";
$content['MENU_MAXIMIZE'] = $content['BASEPATH'] . "images/icons/table_selection_all.png";
$content['MENU_NORMAL'] = $content['BASEPATH'] . "images/icons/table_selection_block.png";
$content['MENU_USEROPTIONS'] = $content['BASEPATH'] . "images/icons/businessman_preferences.png";
diff --git a/src/include/functions_config.php b/src/include/functions_config.php
index a555eb0..0a50b7d 100644
--- a/src/include/functions_config.php
+++ b/src/include/functions_config.php
@@ -189,6 +189,23 @@ function InitSource(&$mysource)
if ( isset($mysource['DBPassword']) ) { $mysource['ObjRef']->DBPassword = $mysource['DBPassword']; }
if ( isset($mysource['DBEnableRowCounting']) ) { $mysource['ObjRef']->DBEnableRowCounting = $mysource['DBEnableRowCounting']; }
}
+ else if ( $mysource['SourceType'] == SOURCE_MONGODB)
+ {
+ // Perform necessary include
+ require_once($gl_root_path . 'classes/logstreamconfigmongodb.class.php');
+
+ $mysource['ObjRef'] = new LogStreamConfigMongoDB();
+ $mysource['ObjRef']->DBServer = $mysource['DBServer'];
+ $mysource['ObjRef']->DBName = $mysource['DBName'];
+ $mysource['ObjRef']->DBCollection = $mysource['DBTableName'];
+ $mysource['ObjRef']->DBTableType = strtolower($mysource['DBTableType']);
+
+ // Optional parameters!
+ if ( isset($mysource['DBPort']) ) { $mysource['ObjRef']->DBPort = $mysource['DBPort']; }
+ if ( isset($mysource['DBUser']) ) { $mysource['ObjRef']->DBUser = $mysource['DBUser']; }
+ if ( isset($mysource['DBPassword']) ) { $mysource['ObjRef']->DBPassword = $mysource['DBPassword']; }
+// if ( isset($mysource['DBEnableRowCounting']) ) { $mysource['ObjRef']->DBEnableRowCounting = $mysource['DBEnableRowCounting']; }
+ }
else
{
// UNKNOWN, remove config entry!
diff --git a/src/lang/en/admin.php b/src/lang/en/admin.php
index 63933d1..c0376f9 100644
--- a/src/lang/en/admin.php
+++ b/src/lang/en/admin.php
@@ -256,6 +256,7 @@ $content['LN_SOURCES_ASSIGNTO'] = "Assigned To";
$content['LN_SOURCES_DISK'] = "Diskfile";
$content['LN_SOURCES_DB'] = "MySQL Database";
$content['LN_SOURCES_PDO'] = "PDO Datasource";
+$content['LN_SOURCES_MONGODB'] = "MongoDB Datasource";
$content['LN_SOURCES_ADD'] = "Add new Source";
$content['LN_SOURCES_ADDEDIT'] = "Add / Edit a Source";
$content['LN_SOURCES_TYPE'] = "Source Type";
diff --git a/src/lang/en/main.php b/src/lang/en/main.php
index 3cf65ab..5bb205e 100644
--- a/src/lang/en/main.php
+++ b/src/lang/en/main.php
@@ -44,6 +44,7 @@ $content['LN_GEN_PREDEFINEDSEARCHES'] = "Predefined Searches";
$content['LN_GEN_SOURCE_DISK'] = "Diskfile";
$content['LN_GEN_SOURCE_DB'] = "MYSQL Native";
$content['LN_GEN_SOURCE_PDO'] = "Database (PDO)";
+$content['LN_GEN_SOURCE_MONGODB'] = "MongoDB Native";
$content['LN_GEN_RECORDSPERPAGE'] = "records per page";
$content['LN_GEN_PRECONFIGURED'] = "Preconfigured";
$content['LN_GEN_AVAILABLESEARCHES'] = "Available searches";
diff --git a/src/templates/admin/admin_sources.html b/src/templates/admin/admin_sources.html
index 2288165..f1aadbe 100644
--- a/src/templates/admin/admin_sources.html
+++ b/src/templates/admin/admin_sources.html
@@ -25,6 +25,14 @@
showvisibility("HiddenDatabaseTypeOptions");
hidevisibility("HiddenDiskTypeOptions");
+ showvisibility("HiddenPDOSourceOptions");
+ hidevisibility("HiddenMYSQLSourceOptions");
+ }
+ else if (myfield.value == 4)
+ {
+ showvisibility("HiddenDatabaseTypeOptions");
+ hidevisibility("HiddenDiskTypeOptions");
+
showvisibility("HiddenPDOSourceOptions");
hidevisibility("HiddenMYSQLSourceOptions");
}