/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


CentOS 6.5 build

Install Prerequisites
---------------------
0) Install development tools
    $>yum groupinstall 'Development Tools'

1) CMAKE 3.0
    $> yum install cmake3

2.1) Download protobuf 2.5 from :
    http://rpm.pbone.net/index.php3/stat/4/idpl/23552166/dir/centos_6/com/protobuf-2.5.0-16.1.x86_64.rpm.html
    http://rpm.pbone.net/index.php3/stat/4/idpl/23552167/dir/centos_6/com/protobuf-compiler-2.5.0-16.1.x86_64.rpm.html
    http://rpm.pbone.net/index.php3/stat/4/idpl/23552169/dir/centos_6/com/protobuf-devel-2.5.0-16.1.x86_64.rpm.html

2.2) Install Protobufs
    $> sudo yum install protobuf
    $> sudo yum install protobuf-compiler
    $> sudo yum install protobuf-devel

3)
3.1) Install Zookeeper prerequisites
    - autoconf 2.59 or greater (should be installed with dev tools)
    - cppunit 1.10.x or higher

3.1.1) install cppuint
    $> sudo yum install cppunit
    $> sudo yum install cppunit-devel

3.2) Download Zookeeper from :
    - http://apache.mirror.quintex.com/zookeeper/zookeeper-3.4.6/
    - untar and then follow instructions in ZOOKEEPER_DIR/src/c/README to build and install the client libs

3.3) run autoreconf
    $> autoreconf -if

3.4) Build Zookeeper libs
    $> ./configure --enable-debug --with-syncapi --enable-static --enable-shared
    $> make && sudo make install

4) Install boost. The minumim version required is 1.53, which will probably have to be built from source

    # Remove any previous boost
    $> sudo yum -y erase boost

    # fetch the boost source rpm and create binary rpms
    $> wget ftp://ftp.icm.edu.pl/vol/rzm2/linux-fedora-secondary/development/rawhide/source/SRPMS/b/boost-1.53.0-6.fc19.src.rpm
    $> rpmbuild --rebuild boost-1.53.0-6.fc19.src.rpm

    #install the binary rpms
    #(Note: the "rpm" utility does not clean up old versions very well.)
    $> sudo yum -y install ~/rpmbuild/RPMS/x86_64/*

OR 
    Download and build using boost build. 
    See this link for how to build: http://www.boost.org/doc/libs/1_53_0/more/getting_started/unix-variants.html#prepare-to-use-a-boost-library-binary 
    After building boost the hard way, you will need to do some symlinks for compatibility:
    cd /usr/lib
    ln -svf libboost_regex.so libboost_regex-mt.so
    ln -svf libboost_system.so libboost_system-mt.so
    ln -svf libboost_filesystem.so libboost_filesystem-mt.so
    ln -svf libboost_date_time.so libboost_date_time-mt.so
    ln -svf libboost_regex.a libboost_regex-mt.a
    ln -svf libboost_system.a libboost_system-mt.a
    ln -svf libboost_filesystem.a libboost_filesystem-mt.a
    ln -svf libboost_date_time.a libboost_date_time-mt.a

Build drill client
-------------------
    $> cd DRILL_DIR/contrib/native/client
    $> mkdir build
    $> cd build && cmake3 -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug ..
    $> make

Test
----
Run query submitter from the command line
    $> querySubmitter query='select * from dfs.`/Users/pchandra/work/data/tpc-h/customer.parquet`' type=sql connectStr=local=10.250.0.146:31010 api=async logLevel=trace user=yourUserName password=yourPassWord

Valgrind
--------
Examples to run Valgrind and see the log in Valkyrie
    $> valgrind --leak-check=yes --xml=yes --xml-file=qs-vg-log-a.xml querySubmitter query='select LINEITEM from dfs.`/Users/pchandra/work/data/tpc-h/customer.parquet`' type=sql connectStr=local=10.250.0.146:31010 api=async logLevel=trace
    $> valkyrie -l qs-vg-log-a.xml


