diff --git a/README.md b/README.md
index 8df4371..dd5bbe0 100755
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ Works with mobile versions too.
## Server requirements
* A reasonably fast web server with Apache 2 (nginx, IIS also supported)
* PHP 5.4 (other backends also available)
-* MySQL database to store test results (optional, PostgreSQL and SQLite also supported)
+* MySQL database to store test results (optional, Microsoft SQL Server, PostgreSQL and SQLite also supported)
* A fast! internet connection
## Installation videos
diff --git a/results/sanitycheck.php b/results/sanitycheck.php
new file mode 100644
index 0000000..133b683
--- /dev/null
+++ b/results/sanitycheck.php
@@ -0,0 +1,189 @@
+Pass";
+$failed="failed";
+$na="N/A";
+?>
+
+
+
+Speed Test installation sanity check
+
+
+
+Item | Status | Comment |
+PHP extensions |
+
+gd |
+
+ | Used to render result images. |
+
+openssl |
+
+ | |
+
+pdo_sqlsrv |
+
+ | Only required if using MS SQL. |
+
+pdo_mysql |
+
+ | Only required if using mysql. |
+
+pdo_sqlite |
+
+ | Only required if using sqlite. |
+
+
+pdo_pgsql |
+
+ | Only required if using sqlite. |
+
+
+Database check |
+Connecting to DB |
+ | | ";
+ } else {
+ echo $failed;
+ echo "". htmlspecialchars($pdo) . " | ";
+ }
+?>
+
+
+Insert into DB |
+ | ";
+ echo htmlspecialchars($insertResult->getMessage()) . " | ";
+ } else {
+ echo $pass;
+ echo " | ";
+ }
+?>
+
+
+Read from DB |
+ | ";
+ echo htmlspecialchars($insertResult->getMessage()) . " | ";
+ } elseif(!is_array($QueryResult)) {
+ echo $failed;
+ echo "Test result not retrieved from database. | ";
+ } else {
+ echo $pass;
+ echo " | ";
+ }
+ } else {
+ echo "Insert failed so can't test reading inserted data | ";
+ }
+?>
+
+
+
+
+
+
\ No newline at end of file
diff --git a/results/telemetry_db.php b/results/telemetry_db.php
index 6a1aee3..e516638 100755
--- a/results/telemetry_db.php
+++ b/results/telemetry_db.php
@@ -7,18 +7,24 @@ define('TELEMETRY_SETTINGS_FILE', 'telemetry_settings.php');
/**
* @return PDO|false
*/
-function getPdo()
+function getPdo($returnErrorMessage = false)
{
if (
!file_exists(TELEMETRY_SETTINGS_FILE)
|| !is_readable(TELEMETRY_SETTINGS_FILE)
) {
+ if($returnErrorMessage){
+ return 'missing TELEMETRY_SETTINGS_FILE';
+ }
return false;
}
require TELEMETRY_SETTINGS_FILE;
if (!isset($db_type)) {
+ if($returnErrorMessage){
+ return "db_type not set in '" . TELEMETRY_SETTINGS_FILE . "'";
+ }
return false;
}
@@ -27,6 +33,47 @@ function getPdo()
];
try {
+ if ('mssql' === $db_type) {
+ if (!isset(
+ $MsSql_server,
+ $MsSql_databasename,
+ $MsSql_WindowsAuthentication
+ )) {
+ if($returnErrorMessage){
+ return "Required MSSQL database settings missing in '" . TELEMETRY_SETTINGS_FILE . "'";
+ }
+ return false;
+ }
+
+ if (!$MsSql_WindowsAuthentication and
+ !isset(
+ $MsSql_username,
+ $MsSql_password,
+ )
+ ) {
+ if($returnErrorMessage){
+ return "Required MSSQL database settings missing in '" . TELEMETRY_SETTINGS_FILE . "'";
+ }
+ return false;
+ }
+ $dsn = 'sqlsrv:'
+ .'server='.$MsSql_server
+ .';Database='.$MsSql_databasename;
+
+ if($MsSql_TrustServerCertificate === true){
+ $dsn = $dsn . ';TrustServerCertificate=1';
+ }
+ if($MsSql_TrustServerCertificate === false){
+ $dsn = $dsn . ';TrustServerCertificate=0';
+ }
+
+ if($MsSql_WindowsAuthentication){
+ return new PDO($dsn, "", "", $pdoOptions);
+ } else {
+ return new PDO($dsn, $MySql_username, $MySql_password, $pdoOptions);
+ }
+ }
+
if ('mysql' === $db_type) {
if (!isset(
$MySql_hostname,
@@ -35,7 +82,10 @@ function getPdo()
$MySql_username,
$MySql_password
)) {
- return false;
+ if($returnErrorMessage){
+ return "Required mysql database settings missing in '" . TELEMETRY_SETTINGS_FILE . "'";
+ }
+ return false;
}
$dsn = 'mysql:'
@@ -48,6 +98,9 @@ function getPdo()
if ('sqlite' === $db_type) {
if (!isset($Sqlite_db_file)) {
+ if($returnErrorMessage){
+ return "Required sqlite database settings missing in '" . TELEMETRY_SETTINGS_FILE . "'";
+ }
return false;
}
@@ -80,7 +133,10 @@ function getPdo()
$PostgreSql_username,
$PostgreSql_password
)) {
- return false;
+ if($returnErrorMessage){
+ return "Required postgresql database settings missing in '" . TELEMETRY_SETTINGS_FILE . "'";
+ }
+ return false;
}
$dsn = 'pgsql:'
@@ -90,9 +146,15 @@ function getPdo()
return new PDO($dsn, $PostgreSql_username, $PostgreSql_password, $pdoOptions);
}
} catch (Exception $e) {
+ if($returnErrorMessage){
+ return $e->getMessage();
+ }
return false;
}
+ if($returnErrorMessage){
+ return "db_type '" . $db_type . "' not supported";
+ }
return false;
}
@@ -109,12 +171,15 @@ function isObfuscationEnabled()
}
/**
- * @return string|false returns the id of the inserted column or false on error
+ * @return string|false returns the id of the inserted column or false on error if returnErrorMessage is false or a error message if returnErrorMessage is true
*/
-function insertSpeedtestUser($ip, $ispinfo, $extra, $ua, $lang, $dl, $ul, $ping, $jitter, $log)
+function insertSpeedtestUser($ip, $ispinfo, $extra, $ua, $lang, $dl, $ul, $ping, $jitter, $log, $returnExceptionOnError = false)
{
$pdo = getPdo();
if (!($pdo instanceof PDO)) {
+ if($returnExceptionOnError){
+ return new Exception("Failed to get database connection object");
+ }
return false;
}
@@ -129,6 +194,9 @@ function insertSpeedtestUser($ip, $ispinfo, $extra, $ua, $lang, $dl, $ul, $ping,
]);
$id = $pdo->lastInsertId();
} catch (Exception $e) {
+ if($returnExceptionOnError){
+ return $e;
+ }
return false;
}
@@ -142,16 +210,19 @@ function insertSpeedtestUser($ip, $ispinfo, $extra, $ua, $lang, $dl, $ul, $ping,
/**
* @param int|string $id
*
- * @return array|null|false returns the speedtest data as array, null
+ * @return array|null|false|exception returns the speedtest data as array, null
* if no data is found for the given id or
- * false if there was an error
+ * false or an exception if there was an error (based on returnExceptionOnError)
*
* @throws RuntimeException
*/
-function getSpeedtestUserById($id)
+function getSpeedtestUserById($id,$returnExceptionOnError = false)
{
$pdo = getPdo();
if (!($pdo instanceof PDO)) {
+ if($returnExceptionOnError){
+ return new Exception("Failed to get database connection object");
+ }
return false;
}
@@ -170,6 +241,9 @@ function getSpeedtestUserById($id)
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (Exception $e) {
+ if($returnExceptionOnError){
+ return $e;
+ }
return false;
}
@@ -195,14 +269,20 @@ function getLatestSpeedtestUsers()
return false;
}
+ require TELEMETRY_SETTINGS_FILE;
+
try {
- $stmt = $pdo->query(
- 'SELECT
- id, timestamp, ip, ispinfo, ua, lang, dl, ul, ping, jitter, log, extra
+ $sql = 'SELECT ';
+
+ if('mssql' === $db_type) {$sql .= ' TOP(100) ';}
+
+ $sql .= ' id, timestamp, ip, ispinfo, ua, lang, dl, ul, ping, jitter, log, extra
FROM speedtest_users
- ORDER BY timestamp DESC
- LIMIT 100'
- );
+ ORDER BY timestamp DESC ';
+
+ if('mssql' !== $db_type) {$sql .= ' LIMIT 100 ';}
+
+ $stmt = $pdo->query($sql);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
diff --git a/results/telemetry_mssql.sql b/results/telemetry_mssql.sql
new file mode 100644
index 0000000..6c68d84
--- /dev/null
+++ b/results/telemetry_mssql.sql
@@ -0,0 +1,30 @@
+SET ANSI_NULLS ON
+GO
+
+SET QUOTED_IDENTIFIER ON
+GO
+
+CREATE TABLE [dbo].[speedtest_users](
+ [id] [bigint] IDENTITY(120,1) NOT NULL,
+ [timestamp] [datetime] NOT NULL,
+ [ip] [nvarchar](max) NOT NULL,
+ [ispinfo] [nvarchar](max) NULL,
+ [extra] [nvarchar](max) NULL,
+ [ua] [nvarchar](max) NOT NULL,
+ [lang] [nvarchar](max) NOT NULL,
+ [dl] [nvarchar](max) NULL,
+ [ul] [nvarchar](max) NULL,
+ [ping] [nvarchar](max) NULL,
+ [jitter] [nvarchar](max) NULL,
+ [log] [nvarchar](max) NULL,
+ CONSTRAINT [PK_speedtest_users] PRIMARY KEY CLUSTERED
+(
+ [id] ASC
+)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[speedtest_users] ADD CONSTRAINT [DF_speedtest_users_timestamp] DEFAULT (getdate()) FOR [timestamp]
+GO
+
+
diff --git a/results/telemetry_settings.php b/results/telemetry_settings.php
index 78bc343..ea19938 100755
--- a/results/telemetry_settings.php
+++ b/results/telemetry_settings.php
@@ -1,6 +1,6 @@