diff --git a/.travis.yml b/.travis.yml
index 96f02d83..187d7f28 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,22 +15,27 @@ env:
- PHPSQLDIR=/REPO/msphpsql-dev
- TEST_PHP_SQL_SERVER=sql
- SQLSRV_DBNAME=msphpsql_sqlsrv
- - PDOSQLSRV_DBNAME=msphpsql_pdosqlsrv
+ - PDOSQLSRV_DBNAME=msphpsql_pdosqlsrv
before_install:
- docker pull microsoft/mssql-server-linux
install:
+ - docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Password123' -p 1433:1433 --name=$TEST_PHP_SQL_SERVER -d microsoft/mssql-server-linux
- docker build --build-arg PHPSQLDIR=$PHPSQLDIR -t msphpsql-dev -f Dockerfile-msphpsql .
- - docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Password12@' -p 1433:1433 --name=$TEST_PHP_SQL_SERVER -d microsoft/mssql-server-linux
+before_script:
+ - sleep 30
+
script:
- - docker run -e TRAVIS_JOB_ID -t -d -w $PHPSQLDIR --link $TEST_PHP_SQL_SERVER --name=client msphpsql-dev
- - docker ps -a
- - docker exec client python ./test/functional/setup/setup_dbs.py -dbname $SQLSRV_DBNAME
- - docker exec client python ./test/functional/setup/setup_dbs.py -dbname $PDOSQLSRV_DBNAME
- - docker exec client php ./source/pdo_sqlsrv/run-tests.php ./test/functional/pdo_sqlsrv/*.phpt
- - docker exec client php ./source/sqlsrv/run-tests.php ./test/functional/sqlsrv/*.phpt
+ - travis_retry docker run -e TRAVIS_JOB_ID -t -d -w $PHPSQLDIR --name=client --link $TEST_PHP_SQL_SERVER msphpsql-dev
+ - docker ps -a
+ - docker stats
+ - docker logs client
+ - travis_retry docker exec client python ./test/functional/setup/setup_dbs.py -dbname $SQLSRV_DBNAME
+ - travis_retry docker exec client python ./test/functional/setup/setup_dbs.py -dbname $PDOSQLSRV_DBNAME
+ - travis_retry docker exec client php ./source/pdo_sqlsrv/run-tests.php ./test/functional/pdo_sqlsrv/*.phpt
+ - travis_retry docker exec client php ./source/sqlsrv/run-tests.php ./test/functional/sqlsrv/*.phpt
- docker exec client bash -c 'for f in ./test/functional/sqlsrv/*.diff; do ls $f 2>/dev/null; cat $f 2>/dev/null; done || true'
- docker exec client bash -c 'for f in ./test/functional/sqlsrv/*.out; do ls $f 2>/dev/null; cat $f 2>/dev/null; done || true'
- docker exec client bash -c 'for f in ./test/functional/pdo_sqlsrv/*.diff; do ls $f 2>/dev/null; cat $f 2>/dev/null; done || true'
diff --git a/Dockerfile-msphpsql b/Dockerfile-msphpsql
index 81ff073f..6cff1116 100644
--- a/Dockerfile-msphpsql
+++ b/Dockerfile-msphpsql
@@ -4,29 +4,29 @@ FROM ubuntu:16.04
# Update Ubuntu Software repository
RUN export DEBIAN_FRONTEND=noninteractive && apt-get update && \
- apt-get -y install \
- apt-transport-https \
- apt-utils \
- autoconf \
- curl \
- g++ \
- gcc \
- git \
- lcov \
- libxml2-dev \
- locales \
- make \
- php7.0 \
- php7.0-dev \
- python-pip \
- re2c \
- unixodbc-dev \
- unzip && apt-get clean
-
+ apt-get -y install \
+ apt-transport-https \
+ apt-utils \
+ autoconf \
+ curl \
+ g++ \
+ gcc \
+ git \
+ lcov \
+ libxml2-dev \
+ locales \
+ make \
+ php7.0 \
+ php7.0-dev \
+ python-pip \
+ re2c \
+ unixodbc-dev \
+ unzip && apt-get clean
+
ARG PHPSQLDIR=/REPO/msphpsql-dev
ENV TEST_PHP_SQL_SERVER sql
ENV TEST_PHP_SQL_UID sa
-ENV TEST_PHP_SQL_PWD Password12@
+ENV TEST_PHP_SQL_PWD Password123
# set locale to utf-8
RUN locale-gen en_US.UTF-8
@@ -36,10 +36,7 @@ ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
-#RUN echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/mssql-ubuntu-xenial-release/ xenial main" > /etc/apt/sources.list.d/mssqlpreview.list
-#RUN apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893
RUN export DEBIAN_FRONTEND=noninteractive && apt-get update && ACCEPT_EULA=Y apt-get install -y msodbcsql mssql-tools
-
ENV PATH="/opt/mssql-tools/bin:${PATH}"
#install coveralls
@@ -47,11 +44,9 @@ RUN pip install --upgrade pip && pip install cpp-coveralls
#Either Install git / download zip (One can see other strategies : https://ryanfb.github.io/etc/2015/07/29/git_strategies_for_docker.html )
#One option is to get source from zip file of repository.
-
#another option is to copy source to build directory on image
RUN mkdir -p $PHPSQLDIR
COPY . $PHPSQLDIR
-
WORKDIR $PHPSQLDIR/source/
RUN chmod +x ./packagize.sh
@@ -79,6 +74,9 @@ RUN sed -i -e 's/TARGET_DATABASE/msphpsql_sqlsrv/g' MsSetup.inc
RUN sed -i -e 's/TARGET_USERNAME/'"$TEST_PHP_SQL_UID"'/g' MsSetup.inc
RUN sed -i -e 's/TARGET_PASSWORD/'"$TEST_PHP_SQL_PWD"'/g' MsSetup.inc
-ENV REPORT_EXIT_STATUS 1
-ENV TEST_PHP_EXECUTABLE /usr/bin/php
+WORKDIR $PHPSQLDIR
+RUN chmod +x ./entrypoint.sh
+CMD /bin/bash ./entrypoint.sh
+ENV REPORT_EXIT_STATUS 1
+ENV TEST_PHP_EXECUTABLE /usr/bin/php
\ No newline at end of file
diff --git a/README.md b/README.md
index c78c480b..78f2cb43 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,7 @@ Thank you for taking time to take our February survey. Let us know how we are do
* [**Ubuntu + SQL Server + PHP 7**](https://www.microsoft.com/en-us/sql-server/developer-get-started/php/ubuntu)
* [**RedHat + SQL Server + PHP 7**](https://www.microsoft.com/en-us/sql-server/developer-get-started/php/rhel)
+* [**SUSE + SQL Server + PHP 7**](https://www.microsoft.com/en-us/sql-server/developer-get-started/php/sles)
* [**Windows + SQL Server + PHP 7**](https://www.microsoft.com/en-us/sql-server/developer-get-started/php/windows)
* [**Docker**](https://hub.docker.com/r/lbosqmsft/mssql-php-msphpsql/)
@@ -42,27 +43,16 @@ Thank you for taking time to take our February survey. Let us know how we are do
## Build (Windows)
-Note: if you prefer, you can use the pre-compiled binary found [HERE](https://github.com/Azure/msphpsql/releases)
+Note: if you prefer, you can use the pre-compiled binary found [HERE](https://github.com/Microsoft/msphpsql/releases)
#### Prerequisites
-You must first be able to build PHP 7 without including these extensions. For help with doing this, see the [official PHP website][phpbuild] for building your own PHP on Windows.
+You must first be able to build PHP 7* without including these extensions. For help with doing this, see the [official PHP website][phpbuild] for building your own PHP in Windows.
#### Compile the drivers
-1. Copy the sqlsrv and/or pdo_sqlsrv source code directory from this repository into the ext subdirectory.
-
-2. Run `buildconf.bat` to rebuild the configure.js script to include the driver.
-
-3. Run `configure.bat --with-odbcver=0x0380 and the desired driver options (as below) [plus other options such as --disable-zts for the Non Thread Safe build]` to generate the makefile. You can run `configure.bat --help` to see what other options are available.
- * For SQLSRV use: `--enable-sqlsrv=shared`
- * For PDO_SQLSRV use: `--enable-pdo=shared --with-pdo-sqlsrv=shared`
-
-4. Run `nmake`. It is suggested that you run the entire build. If you wish to do so, run `nmake clean` first.
-
-5. To install the resulting build, run `nmake install` or just copy php_sqlsrv.dll and/or php_pdo_sqlsrv.dll to your PHP extension directory.
-
-This software has been compiled and tested under PHP 7.0.8 using the Visual C++ 2015 compiler.
+The Microsoft Drivers for PHP for SQL Server have been compiled and tested with PHP 7.0.* and 7.1.* using Visual C++ 2015 as well as PHP 7.2.0 beta using Visual C++ 2017 v15.0.
+For details, please read the documentation and/or take a look at the sample [build scripts](https://github.com/Microsoft/msphpsql/tree/dev/buildscripts#windows).
## Install (Windows)
@@ -75,155 +65,215 @@ This software has been compiled and tested under PHP 7.0.8 using the Visual C++
1. Make sure that the driver is in your PHP extension directory (you can simply copy it there if you did not use nmake install).
-2. Enable it within your PHP installation's php.ini: `extension=php_sqlsrv.dll` and/or `extension=php_pdo_sqlsrv.dll`. If necessary, specify the extension directory using extension_dir, for example: `extension_dir = "C:\PHP\ext"`
+2. Enable it within your PHP installation's php.ini: `extension=php_sqlsrv.dll` and/or `extension=php_pdo_sqlsrv.dll`. If necessary, specify the extension directory using extension_dir, for example: `extension_dir = "C:\PHP\ext"`. Note that the precompiled binaries have different names -- substitute accordingly in php.ini.
3. Restart the Web server.
## Install (UNIX)
-The following instructions assume a clean environment and show how to install PHP 7.x, Microsoft ODBC driver, apache, and Microsoft PHP drivers on Ubuntu 15, 16, RedHat 7 and Mac OS X. To see how to get PHP SQLSRV drivers running on Debian, please visit [Wiki](https://github.com/Microsoft/msphpsql/wiki/Dockerfile-for-getting-pdo_sqlsrv-for-PHP-7.0-on-Debian-in-3-ways). Note that Debian is not officially supported and this instruction hasn't been tested in our test lab.
+The following instructions assume a clean environment and show how to install PHP 7.x, Microsoft ODBC driver, Apache, and Microsoft PHP drivers on Ubuntu 15, 16, RedHat 7, Debian 8, SUSE 12, and macOS.
### Step 1: Install PHP7+
#### PHP 7.0
-**Ubuntu 15.04, Ubuntu 15.10**
+**Ubuntu 15.10**
- sudo su
- sh -c 'echo "deb http://packages.dotdeb.org jessie all \ndeb-src http://packages.dotdeb.org jessie all" >> /etc/apt/sources.list'
- apt-get update
- apt-get install php7.0 php7.0-fpm php-pear php7.0-dev mcrypt php7.0-mcrypt php-mbstring php7.0-xml re2c gcc g++
+ sudo su
+ sh -c 'echo "deb http://packages.dotdeb.org jessie all \ndeb-src http://packages.dotdeb.org jessie all" >> /etc/apt/sources.list'
+ apt-get update
+ apt-get install php7.0 php7.0-fpm php-pear php7.0-dev mcrypt php7.0-mcrypt php-mbstring php7.0-xml
-
**Ubuntu 16.04**
- sudo su
- apt-get update
- apt-get -y install php7.0 mcrypt php7.0-mcrypt php-mbstring php-pear php7.0-dev php7.0-xml re2c gcc g++
+ sudo su
+ apt-get update
+ apt-get -y install php7.0 mcrypt php7.0-mcrypt php-mbstring php-pear php7.0-dev php7.0-xml
-
**RedHat 7**
- sudo su
- wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
- wget http://rpms.remirepo.net/enterprise/remi-release-7.rpm
- rpm -Uvh remi-release-7.rpm epel-release-latest-7.noarch.rpm
- subscription-manager repos --enable=rhel-7-server-optional-rpms
- yum-config-manager --enable remi-php70
- yum update
- yum install php php-pdo php-xml php-pear php-devel re2c gcc-c++ gcc
+ sudo su
+ wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
+ wget http://rpms.remirepo.net/enterprise/remi-release-7.rpm
+ rpm -Uvh remi-release-7.rpm epel-release-latest-7.noarch.rpm
+ subscription-manager repos --enable=rhel-7-server-optional-rpms
+ yum-config-manager --enable remi-php70
+ yum update
+ yum install php php-pdo php-xml php-pear php-devel re2c gcc-c++ gcc
-**Mac OS X**
+**Debian 8**
- /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
- brew tap
- brew tap homebrew/dupes
- brew tap homebrew/versions
- brew tap homebrew/homebrew-php
- brew install php70 --with-pear --with-httpd24 --with-cgi
- echo 'export PATH="/usr/local/sbin:$PATH"' >> ~/.bash_profile
- echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile
- source ~/.bash_profile
+ sudo su
+ apt-get install curl apt-transport-https
+ curl https://www.dotdeb.org/dotdeb.gpg | apt-key add -
+ echo "deb http://packages.dotdeb.org jessie all" >> /etc/apt/sources.list
+ echo "deb-src http://packages.dotdeb.org jessie all" >> /etc/apt/sources.list
+ apt-get update
+ apt-get install -y php7.0 php-pear php7.0-dev php7.0-xml
+
+**SUSE 12**
+
+ sudo su
+ zypper refresh
+ zypper install -y php7 php7-pear php7-devel
+
+**macOS**
+
+ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
+ brew tap
+ brew tap homebrew/dupes
+ brew tap homebrew/versions
+ brew tap homebrew/homebrew-php
+ brew install php70 --with-pear --with-httpd24 --with-cgi
+ echo 'export PATH="/usr/local/sbin:$PATH"' >> ~/.bash_profile
+ echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile
+ source ~/.bash_profile
#### PHP 7.1
+Note that there are no PHP 7.1 packages available for Ubuntu 15.10.
**Ubuntu 16.04**
- sudo su
- add-apt-repository ppa:ondrej/php
- apt-get update
- apt-get -y install php7.1 mcrypt php7.1-mcrypt php-mbstring php-pear php7.1-dev php7.1-xml
+ sudo su
+ add-apt-repository ppa:ondrej/php
+ apt-get update
+ apt-get -y install php7.1 mcrypt php7.1-mcrypt php-mbstring php-pear php7.1-dev php7.1-xml
**RedHat 7**
-
- sudo su
- wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
- wget http://rpms.remirepo.net/enterprise/remi-release-7.rpm
- rpm -Uvh remi-release-7.rpm epel-release-latest-7.noarch.rpm
- subscription-manager repos --enable=rhel-7-server-optional-rpms
- yum-config-manager --enable remi-php71
- yum update
- yum install php php-pdo php-xml php-pear php-devel
-
-**Mac OS X**
- /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
- brew tap
- brew tap homebrew/dupes
- brew tap homebrew/versions
- brew tap homebrew/homebrew-php
- brew install php71 --with-pear --with-httpd24 --with-cgi
- echo 'export PATH="/usr/local/sbin:$PATH"' >> ~/.bash_profile
- echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile
- source ~/.bash_profile
+ sudo su
+ wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
+ wget http://rpms.remirepo.net/enterprise/remi-release-7.rpm
+ rpm -Uvh remi-release-7.rpm epel-release-latest-7.noarch.rpm
+ subscription-manager repos --enable=rhel-7-server-optional-rpms
+ yum-config-manager --enable remi-php71
+ yum update
+ yum install php php-pdo php-xml php-pear php-devel re2c gcc-c++ gcc
+
+**Debian 8**
+
+ sudo su
+ apt-get install curl apt-transport-https
+ wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
+ echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list
+ apt-get update
+ apt-get install -y php7.1 php-pear php7.1-dev php7.1-xml
+
+**SUSE 12**
+
+ sudo su
+ zypper -n ar -f http://download.opensuse.org/repositories/devel:/languages:/php/openSUSE_Leap_42.3/ devel:languages:php
+ zypper --gpg-auto-import-keys refresh
+ zypper -n install php7 php7-pear php7-devel
+
+**macOS**
+
+ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
+ brew tap
+ brew tap homebrew/dupes
+ brew tap homebrew/versions
+ brew tap homebrew/homebrew-php
+ brew install php71 --with-pear --with-httpd24 --with-cgi
+ echo 'export PATH="/usr/local/sbin:$PATH"' >> ~/.bash_profile
+ echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile
+ source ~/.bash_profile
### Step 2: Install Prerequisites
-
**Ubuntu 15.10**
- sudo su
- curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
- curl https://packages.microsoft.com/config/ubuntu/15.10/prod.list > /etc/apt/sources.list.d/mssql-release.list
- exit
- sudo apt-get update
- sudo ACCEPT_EULA=Y apt-get install msodbcsql mssql-tools
- sudo apt-get install unixodbc-dev
- echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
- echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
- source ~/.bashrc
+ sudo su
+ curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
+ curl https://packages.microsoft.com/config/ubuntu/15.10/prod.list > /etc/apt/sources.list.d/mssql-release.list
+ exit
+ sudo apt-get update
+ sudo ACCEPT_EULA=Y apt-get install msodbcsql mssql-tools
+ sudo apt-get install unixodbc-dev
+ echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
+ echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
+ source ~/.bashrc
-
**Ubuntu 16.04**
- sudo su
- curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
- curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
- exit
- sudo apt-get update
- sudo ACCEPT_EULA=Y apt-get install msodbcsql mssql-tools
- sudo apt-get install unixodbc-dev
- echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
- echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
- source ~/.bashrc
+ sudo su
+ curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
+ curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
+ exit
+ sudo apt-get update
+ sudo ACCEPT_EULA=Y apt-get install msodbcsql mssql-tools
+ sudo apt-get install unixodbc-dev
+ echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
+ echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
+ source ~/.bashrc
**RedHat 7**
- sudo su
- curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/mssql-release.repo
- exit
- sudo yum update
- sudo yum remove unixODBC-utf16-devel #to avoid conflicts
- sudo ACCEPT_EULA=Y yum install msodbcsql mssql-tools
- sudo yum install unixODBC-devel
- echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
- echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
- source ~/.bashrc
-
-**Mac OS X**
+ sudo su
+ curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/mssql-release.repo
+ exit
+ sudo yum update
+ sudo yum remove unixODBC-utf16-devel #to avoid conflicts
+ sudo ACCEPT_EULA=Y yum install msodbcsql mssql-tools
+ sudo yum install unixODBC-devel
+ echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
+ echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
+ source ~/.bashrc
- brew tap microsoft/msodbcsql https://github.com/Microsoft/homebrew-mssql-release
- brew update
- brew install msodbcsql
- brew install mssql-tools
- brew install autoconf
+**Debian 8**
-*Note: You need to make sure you install PHP 7+ before you proceed to step 3. The Microsoft PHP Drivers for SQL Server will only work for PHP 7+.
+ sudo su
+ curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
+ curl https://packages.microsoft.com/config/debian/8/prod.list > /etc/apt/sources.list.d/mssql-release.list
+ apt-get install -y locales
+ echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
+ locale-gen
+ exit
+ sudo apt-get update
+ sudo ACCEPT_EULA=Y apt-get install msodbcsql
+ sudo apt-get install unixodbc-dev
+
+**SUSE 12**
+
+ sudo su
+ zypper ar https://packages.microsoft.com/config/sles/12/prod.repo
+ sudo zypper --gpg-auto-import-keys refresh
+ exit
+ sudo ACCEPT_EULA=Y zypper install msodbcsql
+ sudo ACCEPT_EULA=Y zypper install mssql-tools
+ sudo zypper install unixODBC-devel
+ echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
+ echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
+ source ~/.bashrc
+
+**macOS**
+
+ brew tap microsoft/msodbcsql https://github.com/Microsoft/homebrew-mssql-release
+ brew update
+ brew install --no-sandbox msodbcsql
+ brew install mssql-tools
+ brew install autoconf
+
+*Note: Be sure to install PHP 7+ before proceeding to step 3. The Microsoft PHP Drivers for SQL Server will only work for PHP 7+.
### Step 3: Install the Microsoft PHP Drivers for SQL Server
-*Note: The first step is not required in Mac OS X. PECL installs the stable version when version is not specified. You may run `sudo pecl search sqlsrv` to search for the latest releases and `sudo pecl install sqlsrv-[version]` to install a specific version. Drivers are Mac-compatible starting from `4.1.7preview` release.
+*Note: You can run `sudo pecl search sqlsrv` to search for the latest releases and `sudo pecl install sqlsrv-[version]` to install a specific version. PECL installs the stable version when version is not specified. Drivers are Mac-compatible starting from `4.1.7preview` release.
+
+On Ubuntu, Debian, and SUSE systems only, run:
sudo pear config-set php_ini `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"` system
- sudo pecl install sqlsrv
- sudo pecl install pdo_sqlsrv
+
+On all systems, run:
+
+ pecl install sqlsrv
+ pecl install pdo_sqlsrv
### Step 4: Install and Configure Apache
#### PHP 7.0
-**Ubuntu**
+**Ubuntu and Debian**
sudo su
apt-get install libapache2-mod-php7.0 apache2
@@ -232,19 +282,29 @@ The following instructions assume a clean environment and show how to install PH
a2enmod php7.0
echo "extension=sqlsrv.so" >> /etc/php/7.0/apache2/php.ini
echo "extension=pdo_sqlsrv.so" >> /etc/php/7.0/apache2/php.ini
- exit
-
+
**RedHat**
- sudo yum install httpd
+ sudo su
+ yum install httpd
+ echo "extension=sqlsrv.so" > /etc/php.d/sqlsrv.ini
+ echo "extension=pdo_sqlsrv.so" > /etc/php.d/pdo_sqlsrv.ini
-**Mac OS X**
+**SUSE**
+
+ sudo su
+ zypper install apache2 apache2-mod_php7
+ a2enmod php7
+ echo "extension=sqlsrv.so" >> /etc/php7/apache2/php.ini
+ echo "extension=pdo_sqlsrv.so" >> /etc/php7/apache2/php.ini
+
+**macOS**
(echo ""; echo "SetHandler application/x-httpd-php"; echo "";) >> /usr/local/etc/apache2/2.4/httpd.conf
#### PHP 7.1
-**Ubuntu**
+**Ubuntu and Debian**
sudo su
apt-get install libapache2-mod-php7.1 apache2
@@ -253,35 +313,48 @@ The following instructions assume a clean environment and show how to install PH
a2enmod php7.1
echo "extension=sqlsrv.so" >> /etc/php/7.1/apache2/php.ini
echo "extension=pdo_sqlsrv.so" >> /etc/php/7.1/apache2/php.ini
- exit
-
+
**RedHat**
- sudo yum install httpd
+ sudo su
+ yum install httpd
+ echo "extension=sqlsrv.so" > /etc/php.d/sqlsrv.ini
+ echo "extension=pdo_sqlsrv.so" > /etc/php.d/pdo_sqlsrv.ini
-**Mac OS X**
+**SUSE**
+
+ sudo su
+ zypper install apache2 apache2-mod_php7
+ a2enmod php7
+ echo "extension=sqlsrv.so" >> /etc/php7/apache2/php.ini
+ echo "extension=pdo_sqlsrv.so" >> /etc/php7/apache2/php.ini
+
+**macOS**
(echo ""; echo "SetHandler application/x-httpd-php"; echo "";) >> /usr/local/etc/apache2/2.4/httpd.conf
-
+
### Step 5: Restart Apache to load the new php.ini file
-**Ubuntu**
+**Ubuntu, Debian, and SUSE**
- sudo service apache2 restart
+ sudo systemctl restart apache2
**RedHat**
- sudo apachectl restart
-
-**Mac OS X**
+ sudo systemctl restart httpd
- sudo apachectl restart
+Note: On RedHat, SELinux is installed by default and runs in Enforcing mode. To allow Apache to connect to a database through SELinux, run the following command:
+
+ sudo setsebool -P httpd_can_network_connect_db 1
+
+**macOS**
+
+ sudo apachectl restart
-*Note to RedHat users: SELinux is installed by default and runs in Enforcing mode. To allow Apache to connect to database through SELinux, do this `sudo setsebool -P httpd_can_network_connect_db 1`
### Step 6: Create your sample app
-Navigate to `/var/www/html` (`/usr/local/var/www/htdocs` on Mac) and create a new file called testsql.php. Copy and paste the following code in tetsql.php and change the servername, username, password and databasename.
+Navigate to your system's document root -- `/var/www/html` on Ubuntu, Debian, and Redhat, `/srv/www/htdocs` on SUSE, or `/usr/local/var/www/htdocs` on Mac. Create a new file called testsql.php. Copy and paste the following code into testsql.php and change the servername, username, password and databasename.
-src` directory, which is often unnecessary
+
+6. If you choose not to download from a GitHub repository, you will be asked to provide the full path to your local Source folder.
+
+7. If the compilation is successful, you will be given the option to rebuild or quit.
+
+#### Troubleshooting
+
+If something went wrong or the build failed, the log file will be launched (you can find the log files in `C:\php-sdk`). Otherwise, the log file will not be shown, and they remain in `C:\php-sdk` until you remove them manually.
+
+In addition to the log files in `C:\php-sdk`, you can examine the contents of `C:\php-sdk\phpsdk-build-task.bat`, which is overwritten every time you run the build scripts.
+
+#### Testing mode and/or setting alternative destination
+
+If your main goal is to build the drivers for testing, and/or there is no need to keep the `php-sdk` directory around, you can invoke `py builddrivers.py` with the necessary command-line arguments plus `--TESTING`, which turns on the *testing* mode (it is False by default).
+
+Setting the testing mode automatically turns off the looping mechanism. When the build is finished, you will find a copy of the drivers (unless the build failed) and the `php-sdk` folder in the same directory of these Python scripts.
+
+In addition, you can set an alternative destination using `--DESTPATH=`, which is **None** by default. Note that these two options are *not* available in the interactive mode. However, they are particularly useful for testing purposes (such as testing in a virtual machine) in which these build scripts are copied to a temporary folder. After the drivers have been successfully compiled and copied to the designated location, the temporary folder can be safely removed.
+
+
+
+
+
diff --git a/buildscripts/builddrivers.py b/buildscripts/builddrivers.py
new file mode 100644
index 00000000..f4e14e34
--- /dev/null
+++ b/buildscripts/builddrivers.py
@@ -0,0 +1,288 @@
+#!/usr/bin/python3
+#########################################################################################
+#
+# Description: This script helps to build drivers in a Windows environment for PHP 7+ (32-bit/64-bit)
+#
+# Requirement:
+# python 3.x
+# PHP SDK and PHP Source
+# Driver source code folder / GitHub repository
+# Visual Studio 2015 (PHP 7.0* and 7.1*) and Visual Studio 2017 (PHP 7.2*)
+#
+# Execution: Run with command line with required options.
+# Examples:
+# py builddrivers.py (for interactive mode)
+# py builddrivers.py --PHPVER=7.0.22 --ARCH=x64 --THREAD=nts --DRIVER=all --DEBUG
+#
+# Output: Build the drivers using PHP SDK. When running for local development, if build is unsuccessful,
+# the log file will be launched for examination. Otherwise, the drivers will be renamed
+# and copied to the designated location (if defined).
+#
+#############################################################################################
+
+import sys
+import shutil
+import os.path
+import argparse
+from buildtools import BuildUtil
+
+class BuildDriver(object):
+ """Build sqlsrv and/or pdo_sqlsrv drivers with PHP source with the following properties:
+
+ Attributes:
+ util # BuildUtil object whose constructor takes phpver, driver, arch, thread, debug
+ repo # GitHub repository
+ branch # GitHub repository branch
+ download_source # download source from GitHub or not
+ dest_path # alternative destination for the drivers (None for development builds)
+ rebuild # a boolean flag - whether the user is rebuilding
+ make_clean # a boolean flag - whether make clean is necessary
+ source_path # path to a local source folder
+ testing # whether the user has turned on testing mode
+ """
+
+ def __init__(self, phpver, driver, arch, thread, debug, repo, branch, download, path, testing):
+ self.util = BuildUtil(phpver, driver, arch, thread, debug)
+ self.repo = repo
+ self.branch = branch
+ self.download_source = download
+ self.dest_path = path
+ self.testing = testing
+ self.rebuild = False
+ self.make_clean = False
+ self.source_path = None # None initially but will be set later if not downloading from GitHub
+
+ def show_config(self):
+ print()
+ print('PHP Version: ', self.util.phpver)
+ print('Arch: ', self.util.arch)
+ print('Thread: ', self.util.thread)
+ print('Driver: ', self.util.driver)
+ print('Debug enabled: ', self.util.debug_enabled)
+ print()
+
+ def clean_or_remove(self, root_dir, work_dir):
+ """Only check this for local development and not rebuilding. If the php source directory
+ already exists, this will prompt user whether to rebuild, clean, or superclean, the last option
+ will remove the entire php source directory.
+
+ :param root_dir: the C:\ drive
+ :param work_dir: the directory of this script
+ :outcome: the old binaries, if exist, will be removed
+ """
+ phpsrc = self.util.phpsrc_root(root_dir)
+ if os.path.exists( phpsrc ):
+ print(phpsrc + " exists.")
+ build_choice = validate_input("(r)ebuild for the same configuration, (c)lean otherwise, (s)uperclean if unsure ", "r/c/s")
+ self.make_clean = False
+ if build_choice == 'r':
+ print('Will rebuild the binaries')
+ # only the old binaries based on the current configuration will be removed
+ self.util.remove_prev_build(root_dir)
+ elif build_choice == 'c':
+ print('Will make clean')
+ self.make_clean = True
+ # all old builds are removed, and this step is necessary because
+ # the user might have changed the configuration
+ self.util.remove_old_builds(root_dir)
+ else:
+ print('Will remove ' + phpsrc)
+ os.system('RMDIR /s /q ' + phpsrc)
+
+ os.chdir(work_dir) # change back to the working directory
+
+ def build_extensions(self, root_dir, logfile):
+ """This takes care of getting the drivers' source files, building the drivers.
+ If dest_path is defined, the binaries will be copied to the designated destinations.
+
+ :param root_dir: the root directory
+ :param logfile: the name of the logfile
+ :outcome: the drivers and symbols will renamed and placed in the appropriate location(s)
+
+ """
+ work_dir = os.path.dirname(os.path.realpath(__file__))
+
+ if self.download_source:
+ # This will download from the specified branch on GitHub repo and copy the source
+ self.util.download_msphpsql_source(repo, branch)
+ else:
+ # This case only happens when building for development
+ while True:
+ if self.source_path is None:
+ source = input('Enter the full path to the Source folder: ')
+ else:
+ source = input("Hit ENTER to reuse '" + self.source_path + "' or provide another path to the Source folder: ")
+ if len(source) == 0:
+ source = self.source_path
+
+ valid = True
+ if os.path.exists(source) and os.path.exists(os.path.join(source, 'shared')):
+ # Checking the existence of 'shared' folder only, assuming
+ # sqlsrv and/or pdo_sqlsrv are also present if it exists
+ self.source_path = source
+ break
+
+ print("The path provided is invalid. Please re-enter.")
+
+ print('Copying source files from', source)
+
+ os.system('ROBOCOPY ' + source + '\shared ' + work_dir + '\Source\shared /xx /xo ')
+ os.system('ROBOCOPY ' + source + '\sqlsrv ' + work_dir + '\Source\sqlsrv /xx /xo ')
+ os.system('ROBOCOPY ' + source + '\pdo_sqlsrv ' + work_dir + '\Source\pdo_sqlsrv /xx /xo ')
+
+ print('Start building PHP with the extension...')
+
+ # If not testing, dest should be the root drive. Otherwise, dest should be None.
+ dest = None if self.testing else root_dir
+
+ # ext_dir is the directory where we can find the built extension(s)
+ ext_dir = self.util.build_drivers(self.make_clean, dest, logfile)
+
+ # Copy the binaries if a destination path is defined
+ if self.dest_path is not None:
+ dest_drivers = os.path.join(self.dest_path, self.util.major_version(), self.util.arch)
+ dest_symbols = os.path.join(dest_drivers, 'Symbols', self.util.thread)
+
+ # All intermediate directories will be created in order to create the leaf directory
+ if os.path.exists(dest_symbols) == False:
+ os.makedirs(dest_symbols)
+
+ # Now copy all the binaries
+ if self.util.driver == 'all':
+ self.util.copy_binary(ext_dir, dest_drivers, 'sqlsrv', '.dll')
+ self.util.copy_binary(ext_dir, dest_symbols, 'sqlsrv', '.pdb')
+ self.util.copy_binary(ext_dir, dest_drivers, 'pdo_sqlsrv', '.dll')
+ self.util.copy_binary(ext_dir, dest_symbols, 'pdo_sqlsrv', '.pdb')
+ else:
+ self.util.copy_binary(ext_dir, dest_drivers, self.util.driver, '.dll')
+ self.util.copy_binary(ext_dir, dest_symbols, self.util.driver, '.pdb')
+
+
+ def build(self):
+ """This is the main entry point of building drivers for PHP.
+ For development, this will loop till the user decides to quit.
+ """
+ self.show_config()
+
+ work_dir = os.path.dirname(os.path.realpath(__file__))
+ root_dir = 'C:' + os.sep
+
+ quit = False
+ while not quit:
+ if not self.rebuild and not self.testing:
+ self.clean_or_remove(root_dir, work_dir)
+
+ logfile = self.util.get_logfile_name()
+
+ try:
+ self.build_extensions(root_dir, logfile)
+ print('Build Completed')
+ except:
+ print('Something went wrong, launching log file', logfile)
+ # display log file only when not testing
+ if not self.testing:
+ os.startfile(os.path.join(root_dir, 'php-sdk', logfile))
+ os.chdir(work_dir)
+ break
+
+ if not self.testing:
+ choice = input("Rebuild using the same configuration(yes) or quit (no) [yes/no]: ")
+ choice = choice.lower()
+ if choice == 'yes' or choice == 'y' or choice == '':
+ print('Rebuilding drivers...')
+ self.make_clean = False
+ self.rebuild = True
+ self.util.remove_prev_build(root_dir)
+ else:
+ quit = True
+ else:
+ quit = True
+
+ os.chdir(work_dir)
+
+def validate_input(question, values):
+ """Return the user selected value, and it must be valid based on *values*."""
+ while True:
+ options = values.split('/')
+ prompt = '[' + values + ']'
+ value = input(question + prompt + ': ')
+ value = value.lower()
+ if not value in options:
+ print("An invalid choice is entered. Choose from", prompt)
+ else:
+ break
+ return value
+
+################################### Main Function ###################################
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--PHPVER', help="PHP version, e.g. 7.1.*, 7.2.* etc.")
+ parser.add_argument('--ARCH', choices=['x64', 'x86'])
+ parser.add_argument('--THREAD', choices=['nts', 'ts'])
+ parser.add_argument('--DRIVER', default='all', choices=['all', 'sqlsrv', 'pdo_sqlsrv'], help="driver to build (default: all)")
+ parser.add_argument('--DEBUG', action='store_true', help="enable debug mode (default: False)")
+ parser.add_argument('--REPO', default='Microsoft', help="GitHub repository (default: Microsoft)")
+ parser.add_argument('--BRANCH', default='dev', help="GitHub repository branch (default: dev)")
+ parser.add_argument('--SOURCE', action='store_true', help="get source from a local path (default: False)")
+ parser.add_argument('--TESTING', action='store_true', help="turns on testing mode (default: False)")
+ parser.add_argument('--DESTPATH', default=None, help="an alternative destination for the drivers (default: None)")
+
+ args = parser.parse_args()
+
+ phpver = args.PHPVER
+ arch = args.ARCH
+ thread = args.THREAD
+ driver = args.DRIVER
+ debug = args.DEBUG
+ repo = args.REPO
+ branch = args.BRANCH
+ download = args.SOURCE is False
+ path = args.DESTPATH
+ testing = args.TESTING
+
+ if phpver is None:
+ # starts interactive mode, testing mode is False
+ # will not prompt for drivers' destination path, which is None by default
+ while True:
+ # perform some minimal checks
+ phpver = input("PHP Version (e.g. 7.1.* or 7.2.*): ")
+ if phpver == '':
+ print('Empty PHP version entered! Please try again.')
+ elif phpver[0] < '7':
+ print('Only PHP 7.0 or above is supported. Please try again.')
+ else:
+ break
+
+ arch_version = input("64-bit? [y/n]: ")
+ thread = validate_input("Thread safe? ", "nts/ts")
+ driver = validate_input("Driver to build? ", "all/sqlsrv/pdo_sqlsrv")
+ debug_mode = input("Debug enabled? [y/n]: ")
+
+ answer = input("Download source from a GitHub repo? [y/n]: ")
+ download = False
+ if answer == 'yes' or answer == 'y' or answer == '':
+ download = True
+ repo = input("Name of the repo (hit enter for 'Microsoft'): ")
+ branch = input("Name of the branch (hit enter for 'dev'): ")
+ if repo == '':
+ repo = 'Microsoft'
+ if branch == '':
+ branch = 'dev'
+
+ arch_version = arch_version.lower()
+ arch = 'x64' if arch_version == 'yes' or arch_version == 'y' or arch_version == '' else 'x86'
+
+ debug_mode = debug_mode.lower()
+ debug = debug_mode == 'yes' or debug_mode == 'y' or debug_mode == ''
+
+ builder = BuildDriver(phpver,
+ driver,
+ arch,
+ thread,
+ debug,
+ repo,
+ branch,
+ download,
+ path,
+ testing)
+ builder.build()
diff --git a/buildscripts/buildtools.py b/buildscripts/buildtools.py
new file mode 100644
index 00000000..2176b94e
--- /dev/null
+++ b/buildscripts/buildtools.py
@@ -0,0 +1,476 @@
+#!/usr/bin/python3
+#########################################################################################
+#
+# Description: The class BuildUtil will build Microsoft SQL Server PHP 7+ Drivers
+# for 32 bit and 64 bit.
+#
+# Requirement:
+# python 3.x
+# PHP SDK and PHP Source
+# Driver source code folder
+# Git for Windows
+# Visual Studio 2015 (PHP 7.0* and 7.1*) and Visual Studio 2017 (PHP 7.2*)
+#
+# Output: The drivers will be renamed and copied to the specified location.
+#
+#############################################################################################
+
+import shutil
+import os.path
+import stat
+import datetime
+import urllib.request
+import zipfile
+import fileinput
+
+class BuildUtil(object):
+ """Build sqlsrv and/or pdo_sqlsrv drivers with PHP source with the following properties:
+
+ Attributes:
+ phpver # PHP version, e.g. 7.1.*, 7.2.* etc.
+ driver # all, sqlsrv, or pdo_sqlsrv
+ arch # x64 or x86
+ thread # nts or ts
+ debug_enabled # whether debug is enabled
+ """
+
+ def __init__(self, phpver, driver, arch, thread, debug_enabled = False):
+ self.phpver = phpver
+ self.driver = driver.lower()
+ self.arch = arch.lower()
+ self.thread = thread.lower()
+ self.debug_enabled = debug_enabled
+
+ def major_version(self):
+ """Return the major version number based on the PHP version."""
+ return self.phpver[0:3]
+
+ def version_label(self):
+ """Return the version label based on the PHP version."""
+ major_ver = self.major_version()
+
+ if major_ver[2] == '0':
+ version = major_ver[0]
+ else:
+ version = major_ver[0] + major_ver[2]
+ return version
+
+ def driver_name(self, driver, suffix):
+ """Return the *driver* name with *suffix* after PHP is successfully compiled."""
+ return 'php_' + driver + suffix
+
+ def driver_new_name(self, driver, suffix):
+ """Return the *driver* name with *suffix* based on PHP version and thread."""
+ version = self.version_label()
+ return 'php_' + driver + '_' + version + '_' + self.thread + suffix
+
+ def compiler_version(self):
+ """Return the appropriate compiler version based on PHP version."""
+ VC = 'vc14'
+ version = self.version_label()
+ if version >= '72': # Compiler version for PHP 7.2 or above
+ VC = 'vc15'
+ return VC
+
+ def phpsrc_root(self, sdk_dir):
+ """Return the path to the PHP source folder based on *sdk_dir*."""
+ vc = self.compiler_version()
+ return os.path.join(sdk_dir, 'php-sdk', 'phpdev', vc, self.arch, 'php-'+self.phpver+'-src')
+
+ def build_abs_path(self, sdk_dir):
+ """Return the absolute path to the PHP build folder based on *sdk_dir*."""
+ phpsrc = self.phpsrc_root(sdk_dir)
+
+ build_dir = 'Release'
+ if self.debug_enabled:
+ build_dir = 'Debug'
+
+ if self.thread == 'ts':
+ build_dir = build_dir + '_TS'
+
+ if self.arch == 'x64':
+ build_dir = self.arch + os.sep + build_dir
+
+ return os.path.join(phpsrc, build_dir)
+
+ def remove_old_builds(self, sdk_dir):
+ """Remove the extensions, e.g. the driver subfolders in php-7.*-src\ext."""
+ print('Removing old builds...')
+
+ phpsrc = self.phpsrc_root(sdk_dir)
+ ext_path = os.path.join(phpsrc, 'ext')
+ if os.path.exists( ext_path ):
+ shutil.rmtree(os.path.join(ext_path, 'sqlsrv'), ignore_errors=True)
+ shutil.rmtree(os.path.join(ext_path, 'pdo_sqlsrv'), ignore_errors=True)
+
+ if self.arch == 'x64':
+ shutil.rmtree(os.path.join(phpsrc, self.arch), ignore_errors=True)
+ else:
+ shutil.rmtree(os.path.join(phpsrc, 'Debug'), ignore_errors=True)
+ shutil.rmtree(os.path.join(phpsrc, 'Debug_TS'), ignore_errors=True)
+ shutil.rmtree(os.path.join(phpsrc, 'Release'), ignore_errors=True)
+ shutil.rmtree(os.path.join(phpsrc, 'Release_TS'), ignore_errors=True)
+
+ def remove_prev_build(self, sdk_dir):
+ """Remove all binaries and source code in the Release* or Debug*
+ folders according to the current configuration
+ """
+ print('Removing previous build...')
+ build_dir = self.build_abs_path(sdk_dir)
+ if not os.path.exists(build_dir):
+ return
+
+ os.chdir(build_dir)
+ os.system('DEL *sqlsrv*')
+
+ # remove the extensions in the phpsrc's release* or debug* folder's ext subfolder
+ release_ext_path = os.path.join(build_dir, 'ext')
+ if os.path.exists( release_ext_path ):
+ shutil.rmtree(os.path.join(release_ext_path, 'sqlsrv'), ignore_errors=True)
+ shutil.rmtree(os.path.join(release_ext_path, 'pdo_sqlsrv'), ignore_errors=True)
+
+ # next remove the binaries too
+ os.chdir(release_ext_path)
+ os.system('DEL *sqlsrv*')
+
+ @staticmethod
+ def get_logfile_name():
+ """Return the filename for the log file based on timestamp."""
+ return 'Build_' + datetime.datetime.now().strftime("%Y%m%d_%H%M") + '.log'
+
+ @staticmethod
+ def update_file_content(file, search_str, new_str):
+ """Find *search_str* and replace it by *new_str* in a *file*"""
+ os.chmod(file, stat.S_IWRITE)
+ with fileinput.FileInput(file, inplace=True) as f:
+ for line in f:
+ print(line.replace(search_str, new_str), end='')
+
+ @staticmethod
+ def generateMMDD():
+ """Return the generated Microsoft PHP Build Version Number"""
+ d = datetime.date.today()
+
+ startYear = 2009
+ startMonth = 4
+ passYear = int( '%02d' % d.year ) - startYear
+ passMonth = int( '%02d' % d.month ) - startMonth
+ MM = passYear * 12 + passMonth
+ dd = d.day
+
+ MMDD = "" + str( MM )
+ if( dd < 10 ):
+ return MMDD + "0" + str( dd )
+ else:
+ return MMDD + str( dd )
+
+ @staticmethod
+ def get_driver_version(version_file):
+ """Read the *version_file* and return the driver version."""
+ with open(version_file) as f:
+ for line in f:
+ if 'SQLVERSION_MAJOR' in line: # major version
+ major = line.split()[2]
+ elif 'SQLVERSION_MINOR' in line: # minor version
+ minor = line.split()[2]
+ elif 'SQLVERSION_PATCH' in line: # patch
+ patch = line.split()[2]
+ break
+
+ return major + '.' + minor + '.' + patch
+
+ @staticmethod
+ def write_lines_to_copy_source(driver, file):
+ """Write to file the commands to copy *driver* source."""
+ source = '%currDir%' + os.sep + 'Source' + os.sep + driver
+ dest = '%phpSrc%' + os.sep + 'ext' + os.sep + driver
+ file.write('@CALL ROBOCOPY ' + source + ' ' + dest + ' /s /xx /xo' + os.linesep)
+
+ source = '%currDir%' + os.sep + 'Source' + os.sep + 'shared'
+ dest = '%phpSrc%' + os.sep + 'ext' + os.sep + driver + os.sep + 'shared'
+ file.write('@CALL ROBOCOPY ' + source + ' ' + dest + ' /s /xx /xo' + os.linesep)
+
+ @staticmethod
+ def download_msphpsql_source(repo, branch, dest_folder = 'Source', clean_up = True):
+ """Download to *dest_folder* the msphpsql archive of the specified
+ GitHub *repo* and *branch*. The downloaded files will be removed by default.
+ """
+ try:
+ work_dir = os.path.dirname(os.path.realpath(__file__))
+
+ temppath = os.path.join(work_dir, 'temp')
+ if os.path.exists(temppath):
+ shutil.rmtree(temppath)
+ os.makedirs(temppath)
+ os.chdir(temppath)
+
+ file = branch + '.zip'
+ url = 'https://github.com/' + repo + '/msphpsql/archive/' + branch + '.zip'
+
+ print('Downloading ' + url + ' ...')
+ try:
+ with urllib.request.urlopen(url) as response, open(file, 'wb') as out_file:
+ shutil.copyfileobj(response, out_file)
+ except:
+ print ("Resort to skip ssl verification...")
+ # need to skip ssl verification on some agents
+ # see https://www.python.org/dev/peps/pep-0476/
+ with urllib.request.urlopen(url, context=ssl._create_unverified_context()) as response, open(file, 'wb') as out_file:
+ shutil.copyfileobj(response, out_file)
+
+ print('Extracting ' + file + ' ...')
+ zip = zipfile.ZipFile(file)
+ zip.extractall()
+ zip.close()
+
+ msphpsqlFolder = os.path.join(temppath, 'msphpsql-' + branch)
+ source = os.path.join(msphpsqlFolder, 'source')
+ os.chdir(work_dir)
+
+ os.system('ROBOCOPY ' + source + '\shared ' + dest_folder + '\shared /xx /xo')
+ os.system('ROBOCOPY ' + source + '\pdo_sqlsrv ' + dest_folder + '\pdo_sqlsrv /xx /xo')
+ os.system('ROBOCOPY ' + source + '\sqlsrv ' + dest_folder + '\sqlsrv /xx /xo')
+
+ if clean_up:
+ shutil.rmtree(temppath)
+
+ except:
+ print('Error occurred when downloading source')
+ raise
+
+ def update_driver_source(self, source_dir, driver):
+ """Update the *driver* source in *source_path* with the
+ latest version, file descriptions, etc.
+ If debug is enabled, will remove the optimization flag
+ """
+ driver_dir = os.path.join(source_dir, driver)
+
+ if self.debug_enabled:
+ # Remove the optimization flag in the config file for this driver
+ # because '/O2' option is incompatible with Debug mode
+ print('Removing optimization flag for', driver)
+ config_file = os.path.join(driver_dir, 'config.w32')
+ if driver == 'sqlsrv':
+ self.update_file_content(config_file, 'ADD_FLAG( "CFLAGS_SQLSRV", "/O2" );', '')
+ elif driver == 'pdo_sqlsrv':
+ self.update_file_content(config_file, 'ADD_FLAG( "CFLAGS_PDO_SQLSRV", "/O2" );', '')
+
+ # Update Template.rc
+ template_file = os.path.join(driver_dir, 'template.rc')
+ if driver == 'sqlsrv':
+ drivername = self.driver_new_name(driver, '.dll')
+ self.update_file_content(template_file, 'FILE_NAME \"\\0\"', '"' + drivername + '\\0"')
+ self.update_file_content(template_file, '\"Microsoft Drivers for PHP for SQL Server\\0\"', '"Microsoft Drivers for PHP for SQL Server (SQLSRV Driver)\\0"')
+ elif driver == 'pdo_sqlsrv':
+ drivername = self.driver_new_name(driver, '.dll')
+ self.update_file_content(template_file, 'FILE_NAME \"\\0\"', '"' + drivername + '\\0"')
+ self.update_file_content(template_file, '\"Microsoft Drivers for PHP for SQL Server\\0\"', '"Microsoft Drivers for PHP for SQL Server (PDO Driver)\\0"')
+
+ # Update Version.h
+ version_file = os.path.join(source_dir, 'shared', 'version.h')
+ build_number = self.generateMMDD()
+ self.update_file_content(version_file, 'SQLVERSION_BUILD 0', 'SQLVERSION_BUILD ' + build_number)
+
+ # get the latest version
+ version = self.get_driver_version(version_file) + '.' + build_number
+ print('Driver version is: ', version)
+
+ # Update CREDIT file
+ credits_file = os.path.join(driver_dir, 'CREDITS')
+ if driver == 'sqlsrv':
+ self.update_file_content(credits_file, 'Microsoft Drivers for PHP for SQL Server', 'Microsoft Drivers ' + version + ' for PHP for SQL Server (' + self.driver.upper() + ' driver)')
+ elif driver == 'pdo_sqlsrv':
+ self.update_file_content(credits_file, 'Microsoft Drivers for PHP for SQL Server (PDO driver)', 'Microsoft Drivers ' + version + ' for PHP for SQL Server (' + self.driver.upper() + ' driver)')
+
+ def generate_build_options(self):
+ """Return the generated build configuration and arguments"""
+ cmd_line = ''
+ if self.debug_enabled:
+ cmd_line = ' --enable-debug '
+
+ if self.driver == 'all':
+ cmd_line = ' --enable-sqlsrv=shared --enable-pdo --with-pdo-sqlsrv=shared ' + cmd_line
+ else:
+ if self.driver == 'sqlsrv':
+ cmd_line = ' --enable-sqlsrv=shared ' + cmd_line
+ else: # pdo_sqlsrv
+ cmd_line = ' --enable-pdo --with-pdo-sqlsrv=shared ' + cmd_line
+
+ cmd_line = 'cscript configure.js --disable-all --enable-cli --enable-cgi --enable-embed' + cmd_line
+ if self.thread == 'nts':
+ cmd_line = cmd_line + ' --disable-zts'
+ return cmd_line
+
+ def create_local_batch_file(self, make_clean, cmd_line, log_file):
+ """Generate the batch file to be picked up by the PHP starter script."""
+ filename = 'phpsdk-build-task.bat'
+ print('Generating ', filename)
+ try:
+ file = open(filename, 'w')
+ file.write('@ECHO OFF' + os.linesep)
+ file.write('SET currDir=%CD%' + os.linesep)
+ file.write('SET LOG_NAME=%currDir%\\' + log_file + os.linesep)
+ file.write('@CALL phpsdk_buildtree phpdev > %LOG_NAME% 2>&1' + os.linesep)
+
+ # for PHP version with release tags, such as 'RC', 'beta', etc.
+ # we need to remove the hyphen '-' between the version number and tag
+ # because in https://github.com/php/php-src the released tags have no hyphens
+
+ php_tag = 'php-' + self.phpver.replace('-', '')
+ php_src = 'php-' + self.phpver +'-src'
+
+ # if not exists, check out the specified tag
+ file.write('IF NOT EXIST ' + php_src + ' @CALL git clone -b ' + php_tag + ' --depth 1 --single-branch https://github.com/php/php-src.git ' + php_src + os.linesep)
+ file.write('CD ' + php_src + os.linesep)
+ file.write('SET phpSrc=%CD%' + os.linesep)
+ file.write('@CALL phpsdk_deps -u >> %LOG_NAME% 2>&1' + os.linesep)
+
+ # copy source files to extension
+ if self.driver == 'all':
+ self.write_lines_to_copy_source('sqlsrv', file)
+ self.write_lines_to_copy_source('pdo_sqlsrv', file)
+ else:
+ self.write_lines_to_copy_source(self.driver, file)
+
+ # configure and build
+ file.write('@CALL buildconf --force >> %LOG_NAME% 2>&1' + os.linesep)
+ file.write('@CALL ' + cmd_line + ' >> %LOG_NAME% 2>&1' + os.linesep)
+ if make_clean:
+ file.write('nmake clean >> %LOG_NAME% 2>&1' + os.linesep)
+ file.write('nmake >> %LOG_NAME% 2>&1' + os.linesep)
+ file.write('exit' + os.linesep)
+ file.close()
+ return filename
+ except:
+ print('Cannot create ', filename)
+
+ def build_drivers(self, make_clean = False, dest = None, log_file = None):
+ """Build sqlsrv/pdo_sqlsrv extensions for PHP, assuming the Source folder
+ exists in the working directory, and this folder will be removed when the build
+ is complete.
+ """
+ work_dir = os.path.dirname(os.path.realpath(__file__))
+
+ # First, update the driver source file contents
+ source_dir = os.path.join(work_dir, 'Source')
+ if self.driver == 'all':
+ self.update_driver_source(source_dir, 'sqlsrv')
+ self.update_driver_source(source_dir, 'pdo_sqlsrv')
+ else:
+ self.update_driver_source(source_dir, self.driver)
+
+ # Next, generate the build configuration and arguments
+ cmd_line = self.generate_build_options()
+ print('cmd_line: ' + cmd_line)
+
+ # Generate a batch file based on the inputs
+ if log_file is None:
+ log_file = self.get_logfile_name()
+
+ batch_file = self.create_local_batch_file(make_clean, cmd_line, log_file)
+
+ # Reference: https://github.com/OSTC/php-sdk-binary-tools
+ # Clone the master branch of PHP sdk if the directory does not exist
+ print('Downloading the latest php SDK...')
+
+ # if *dest* is None, simply use the current working directory
+ sdk_dir = dest
+ copy_to_ext = True # this determines where to copy the binaries to
+ if dest is None:
+ sdk_dir = work_dir
+ copy_to_ext = False
+
+ phpSDK = os.path.join(sdk_dir, 'php-sdk')
+ if not os.path.exists( phpSDK ):
+ os.system('git clone https://github.com/OSTC/php-sdk-binary-tools.git --branch master --single-branch --depth 1 ' + phpSDK)
+ os.chdir(phpSDK)
+ os.system('git pull ')
+
+ # Move the generated batch file to phpSDK for the php starter script
+ sdk_batch_file = os.path.join(phpSDK, batch_file)
+ if os.path.exists(sdk_batch_file):
+ os.remove(sdk_batch_file)
+ shutil.move(os.path.join(work_dir, batch_file), phpSDK)
+
+ sdk_source = os.path.join(phpSDK, 'Source')
+ # Sometimes, for various reasons, the Source folder from previous build
+ # might exist in phpSDK. If so, remove it first
+ if os.path.exists(sdk_source):
+ os.chmod(sdk_source, stat.S_IWRITE)
+ shutil.rmtree(sdk_source, ignore_errors=True)
+ shutil.move(source_dir, phpSDK)
+
+ # Invoke phpsdk--.bat
+ vc = self.compiler_version()
+ starter_script = 'phpsdk-' + vc + '-' + self.arch + '.bat'
+ print('Running starter script: ', starter_script)
+ os.system(starter_script + ' -t ' + batch_file)
+
+ # Now we can safely remove the Source folder, because its contents have
+ # already been modified prior to building the extensions
+ shutil.rmtree(os.path.join(phpSDK, 'Source'), ignore_errors=True)
+
+ # Next, rename the newly compiled PHP extensions
+ self.rename_binaries(sdk_dir)
+
+ # Final step, copy the binaries to the right place
+ ext_dir = self.copy_binaries(sdk_dir, copy_to_ext)
+ return ext_dir
+
+ def rename_binary(self, path, driver):
+ """Rename the *driver* binary (sqlsrv or pdo_sqlsrv) (only the dlls)."""
+ driver_old_name = self.driver_name(driver, '.dll')
+ driver_new_name = self.driver_new_name(driver, '.dll')
+
+ os.rename(os.path.join(path, driver_old_name), os.path.join(path, driver_new_name))
+
+ def rename_binaries(self, sdk_dir):
+ """Rename the sqlsrv and/or pdo_sqlsrv dlls according to the PHP
+ version and thread.
+ """
+
+ # Derive the path to where the extensions are located
+ ext_dir = self.build_abs_path(sdk_dir)
+ print("Renaming binaries in ", ext_dir)
+
+ if self.driver == 'all':
+ self.rename_binary(ext_dir, 'sqlsrv')
+ self.rename_binary(ext_dir, 'pdo_sqlsrv')
+ else:
+ self.rename_binary(ext_dir, self.driver)
+
+ def copy_binary(self, from_dir, dest_dir, driver, suffix):
+ """Copy sqlsrv or pdo_sqlsrv binary (based on *suffix*) to *dest_dir*."""
+ if suffix == '.dll':
+ binary = self.driver_new_name(driver, suffix)
+ else:
+ binary = self.driver_name(driver, suffix)
+ shutil.copy2(os.path.join(from_dir, binary), dest_dir)
+
+ def copy_binaries(self, sdk_dir, copy_to_ext):
+ """Copy the sqlsrv and/or pdo_sqlsrv binaries, including the pdb files,
+ to the right place, depending on *copy_to_ext*. The default is to
+ copy them to the 'ext' folder.
+ """
+ build_dir = self.build_abs_path(sdk_dir)
+ print('Copying the binaries from', build_dir)
+ if copy_to_ext:
+ dest_dir = os.path.join(build_dir, 'ext')
+ else:
+ # Simply make a copy of the binaries in sdk_dir
+ dest_dir = sdk_dir
+
+ print('Destination:', dest_dir)
+
+ # Now copy the binaries
+ if self.driver == 'all':
+ self.copy_binary(build_dir, dest_dir, 'sqlsrv', '.dll')
+ self.copy_binary(build_dir, dest_dir, 'sqlsrv', '.pdb')
+ self.copy_binary(build_dir, dest_dir, 'pdo_sqlsrv', '.dll')
+ self.copy_binary(build_dir, dest_dir, 'pdo_sqlsrv', '.pdb')
+ else:
+ self.copy_binary(build_dir, dest_dir, self.driver, '.dll')
+ self.copy_binary(build_dir, dest_dir, self.driver, '.pdb')
+
+ return dest_dir
+
diff --git a/entrypoint.sh b/entrypoint.sh
new file mode 100644
index 00000000..ffa47b4b
--- /dev/null
+++ b/entrypoint.sh
@@ -0,0 +1,16 @@
+set -e
+
+testConnection="/opt/mssql-tools/bin/sqlcmd -S sql -U sa -P Password123"
+
+for run in {1..10}; do
+
+>&2 echo "SQL Server is starting up.."
+if $testConnection; then
+ >&2 echo "SQL Server is up!"
+ break;
+else
+ sleep 6
+fi
+done
+
+
diff --git a/test/Performance/README.md b/test/Performance/README.md
index 1929d1de..b45fb9e0 100644
--- a/test/Performance/README.md
+++ b/test/Performance/README.md
@@ -34,16 +34,6 @@ On Linux and Mac, the script must be executed with `sudo python3` because to ena
python3 run-perf_tests.py -platform | tee run-perf_output.txt
-<<<<<<< HEAD
`-platform` - The platform that the tests are ran on. Must be one of the following: Windows10, WindowsServer2016, WindowsServer2012, Ubuntu16, RedHat7, Sierra.
`-php-driver` (optional) - The driver that the tests are ran on. Must be one of the following: sqlsrv, pdo_sqlsrv, or both. Default is both.
-`-test-only` (optional) - The test to run. Must be the file name (not including path) of one test or 'all'. Default is 'all'. If one test is specified, must also specify the -php-driver option to sqlsrv or pdo_sqlsrv.
-=======
-`-platform` - The platform that the tests are ran on. Must be one of the following: Windows10, WindowsServer2016, WindowsServer2012, Ubuntu16, RedHat7, Sierra.
-`-iterations` - The number of iterations for regular tests.
-`-iterations-large` - The number of iterations for the tests that fetch large data. Usually set to 1.
-`-result-server` - The server containing the result database. It is assumed that the result database s already setup before running the tests.
-`-result-db` - Database name. With the current result database setup files, this should be set to `TestResults`.
-`-result-uid` - Result database username.
-`-result-pwd` - Result database password.
->>>>>>> upstream/dev
+`-test-only` (optional) - The test to run. Must be the file name (not including path) of one test or 'all'. Default is 'all'. If one test is specified, must also specify the -php-driver option to sqlsrv or pdo_sqlsrv.
\ No newline at end of file
diff --git a/test/Performance/setup_env_unix.sh b/test/Performance/setup_env_unix.sh
index d5341bfd..a2f51cb0 100644
--- a/test/Performance/setup_env_unix.sh
+++ b/test/Performance/setup_env_unix.sh
@@ -85,33 +85,6 @@ elif [ $PLATFORM = "RedHat7" ]; then
printf "done\n"
elif [ $PLATFORM = "Sierra" ]; then
-<<<<<<< HEAD
- echo "Installing homebrew..."
- yes | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" >> env_setup.log 2>&1
- echo "OK"
- echo "Installing wget..."
- brew install wget >> env_setup.log 2>&1
- echo "OK"
- echo "Installing svn..."
- brew install svn >> env_setup.log 2>&1
- echo "OK"
- echo "Installing openssl..."
- brew install pkg-config >> env_setup.log 2>&1
- brew install openssl >> env_setup.log 2>&1
- echo "OK"
- echo "Installing python3..."
- brew install python3 >> env_setup.log 2>&1
- echo "OK"
- echo "Installing MSODBCSQL..."
- brew tap microsoft/msodbcsql https://github.com/Microsoft/homebrew-msodbcsql >> env_setup.log 2>&1
- brew update >> env_setup.log 2>&1
- yes | ACCEPT_EULA=Y brew install --no-sandbox msodbcsql >> env_setup.log 2>&1
- echo "OK"
- yes | brew install autoconf >> env_setup.log 2>&1
- echo "Installing pyodbc..."
- pip3 install pyodbc >> env_setup.log 2>&1
- echo "OK"
-=======
printf "Installing homebrew..."
yes | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" >> env_setup.log
printf "done\n"
@@ -143,7 +116,6 @@ elif [ $PLATFORM = "Sierra" ]; then
printf "Installing pyodbc..."
pip3 install pyodbc >> env_setup.log
printf "done\n"
->>>>>>> upstream/dev
fi
printf "Downloading PHP-$PHP_VERSION source tarball..."