Merge branch 'dev' into perf_change_iter

This commit is contained in:
Yuki Wong 2017-08-22 09:46:20 -07:00 committed by GitHub
commit 459840e4b2
9 changed files with 1130 additions and 212 deletions

View file

@ -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'

View file

@ -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

349
README.md
View file

@ -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 "<FilesMatch .php$>"; echo "SetHandler application/x-httpd-php"; echo "</FilesMatch>";) >> /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 "<FilesMatch .php$>"; echo "SetHandler application/x-httpd-php"; echo "</FilesMatch>";) >> /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.
<?php
$serverName = "yourServername";
@ -338,7 +411,7 @@ For samples, please see the sample folder. For setup instructions, see [here](h
## Limitations
- This release contains the PHP 7 port of the SQLSRV and PDO_SQLSRV drivers, and does not provide backwards compatibility with PHP 5.
- Binding output parameter using emulate prepare is not supported.
- Binding output parameters using emulate prepare is not supported.
- Linux
- ODBC 3.52 is supported but not 3.8.
- Connection using named instances using '\' is not supported.
@ -370,11 +443,11 @@ version number MAY have trailing pre-release version to indicate the stability,
*Note that PECL package version does not have the hyphen before pre-release version, due to restrictions in PECL. Example of PECL package version: 1.2.3preview*
- Build metadata MAY be denoted by a plus sign followed by 4 digits, such as `1.2.3-preview+5678` or `1.2.3+5678`. Build meta data does NOT figure into the precedence order.
## Future Plans
- Expand SQL 16 Feature Support (example: Always Encrypted).
- Build Verification/Fundamental Tests.
- Add More Verification/Fundamental Tests.
- Bug Fixes.
## Guidelines for Reporting Issues
@ -395,15 +468,15 @@ Thank you!
## FAQs
**Q:** Can we get dates for any of the Future Plans listed above?
**A:** At this time, Microsoft is not able to announce dates. We are working extremely hard to release future versions of the driver. We will share future plans once they solidify over the next few weeks.
**A:** At this time, Microsoft is not able to announce dates. We are working extremely hard to release future versions of the driver. We will share future plans as appropriate.
**Q:** What's next?
**A:** On July 20, 2016 we released the early technical preview for our PHP Driver. We will continue releasing frequent technical previews until we reach production quality.
**A:** On July 6, 2017 we released the production release version 4.3.0 of our PHP Driver. We will continue working on our future plans and releasing previews of upcoming releases frequently.
**Q:** Is Microsoft taking pull requests for this project?
**A:** We will not be seeking to take pull requests until GA, Build Verification, and Fundamental tests are released. At this point Microsoft will also begin actively developing using this GitHub project as the prime repository.
**A:** Yes. Please submit pull requests to the **dev** branch and not the **master** branch.
@ -417,7 +490,7 @@ This project has adopted the Microsoft Open Source Code of Conduct. For more inf
## Resources
**Documentation**: [MSDN Online Documentation][phpdoc]. Please note that this documentation is not yet updated for PHP 7.
**Documentation**: [MSDN Online Documentation][phpdoc].
**Team Blog**: Browse our blog for comments and announcements from the team in the [team blog][blog].

100
buildscripts/README.md Normal file
View file

@ -0,0 +1,100 @@
# Windows
## Prerequisites
To build extensions for
1. PHP 7.0* or PHP 7.1*
* install Visual Studio 2015 and make sure C++ tools are enabled.
2. PHP 7.2*
* install Visual Studio 2017, including Visual C++ toolset and the Windows SDK components.
To use the sample build scripts `builddrivers.py` and `buildtools.py`, install Python 3.x and Git for Windows (which comes with Visual Studio 2017). If `git` is unrecognized in a regular command prompt, make sure the environment path is set up correctly.
## Compile the drivers
You must first be able to build PHP 7.* without including our PHP extensions. For help with building PHP 7.0* or PHP 7.1* in Windows, see the [official PHP website](https://wiki.php.net/internals/windows/stepbystepbuild). For PHP 7.2 or above, visit [PHP SDK page](https://github.com/OSTC/php-sdk-binary-tools) for new instructions.
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.
### Manually building from source
1. Download the *source* directory from this repository
2. Make a copy of the *shared* folder as a subfolder in *sqlsrv* and/or *pdo_sqlsrv* folder
3. Copy the *sqlsrv* and/or *pdo_sqlsrv* folder(s) into the PHP source *ext* subdirectory
4. Run `buildconf --force` to rebuild the configure.js script to include the *sqlsrv* and/or *pdo_sqlsrv* driver(s).
5. Run `configure.bat` with the desired driver options (as shown below) to generate the makefile. You can run `configure.bat --help` to see what other options are available. For example, for non-thread safe build, add this option `--disable-zts`.
* For SQLSRV add: `--enable-sqlsrv=shared`
* For PDO_SQLSRV add: `--enable-pdo --with-pdo-sqlsrv=shared`
6. Run `nmake`. Optionally, you can run `nmake clean` first.
7. To install the drivers, there are two ways:
* Run `nmake install`, or
* Copy the drivers:
* Find the directory where the newly compiled *php.exe* is
* Locate the compiled *php_sqlsrv.dll* and/or *php_pdo_sqlsrv.dll*
* Copy the dll(s) to the *ext* subfolder
### Using the sample build scripts
The sample build scripts, `builddrivers.py` and `buildtools.py`, can be used to build our extensions for PHP in Windows.
#### Overview
When asked to provide the PHP version, you should enter values like `7.1.7`. If it's alpha, beta, or RC version, make sure the name you provide matches the PHP tag name without the prefix `php-`. For example, for PHP 7.2 beta 2, the tag name is `php-7.2.0beta2`, so you will enter `7.2.0beta2`. Visit [PHP SRC]( https://github.com/php/php-src) to find the appropriate tag names.
PHP recommends to unzip the PHP SDK into the shortest possible path, preferrably somewhere near the root drive. Therefore, this script will, by default, create a `php-sdk` folder in the C:\ drive, and this `php-sdk` directory tree will remain unless you remove it yourself. For ongoing development, we suggest you keep it around. The build scripts will handle updating the PHP SDK if a new version is available.
#### Steps
1. Launch a regular `cmd` prompt
2. Change to the directory where the Python scripts `builddrivers.py` and `buildtools.py` are
3. Interactive mode:
* Type `py builddrivers.py` to start the interactive mode. Use lower cases to answer the following questions:
* PHP Version (e.g. `7.1.7` or `7.2.0beta2`)
* 64-bit?
* Thread safe?
* Driver?
* Debug enabled?
* Download source from GitHub?
* For `yes/no` questions, you can simply hit `ENTER` key for `yes`. Other questions are self-explanatory.
4. Use Command-line arguments
* Type `py builddrivers.py -h` to get a list of options and their descriptions
* For example,
* `py builddrivers.py --PHPVER=7.0.22 --ARCH=x64 --THREAD=nts --DRIVER=sqlsrv --SOURCE`
* `py builddrivers.py --PHPVER=7.1.8 --ARCH=x86 --THREAD=ts --DEBUG`
5. Based on the given configuration, if the script detects the presence of the PHP source directory, you can choose whether to rebuild, clean or superclean:
* `rebuild` to build again using the same configuration (32 bit, thread safe, etc.)
* `clean` to remove previous builds (binaries)
* `superclean` to remove the entire `php-<version>-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=<some valid path>`, 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.

View file

@ -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()

476
buildscripts/buildtools.py Normal file
View file

@ -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-<vc>-<arch>.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

16
entrypoint.sh Normal file
View file

@ -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

View file

@ -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 <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.

View file

@ -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..."