function rs = jdb_fetch_struct(conn, sql, varargin)
%JDB_FETCH_STRUCT  Executes a SQL query and imports database data into matlab
%
%   Executes a SQL query with the (i) licensed Mathworks database
%   toolbox or otherwise with (ii) the JDBC driver directly
%   fetches the result and checks the result for
%   errors. Returns the resulting data in a struct with columns names as fields.
%   Doubles and integers are returned as numbers,
%   timestamps as DateNumbers and others as cell array of strings.
%
%   Syntax:
%   rs = jdb_fetch_struct(conn, sql, varargin)
%
%   Input:
%   conn      = Database connection object
%   sql       = SQL query string
%   varargin  = none
%
%   Output:
%   rs        = Fetched data from result set from SQL query
%
%   Example
%   conn = jdb_connectdb('someDatabase');
%   jdb_fetch_struct(conn, 'SELECT * FROM someTable');
%
%   See also jdb_exec, jdb_select_struct, jdb_insert_struct, jdb_update_struct, fetch, jdb_fetch2struct


%% execute sql query
% inspect conn object to find out whether is was created with
% the licensed database toolbox or the JDCB driver directly.
OPT.database_toolbox = 0;
try %#ok<TRYNC>
    if any(strfind(char(conn.Constructor),'mathworks'))
        OPT.database_toolbox = 1;
    end
end

if OPT.database_toolbox
    setdbprefs('DataReturnFormat','structure')
    rs = fetch(conn, sql);
else
    % http://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html
    pstat = conn.prepareStatement(sql,...
                                  java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,...
                                  java.sql.ResultSet.CONCUR_READ_ONLY);
    rsraw = pstat.executeQuery();

    % get row count
    rsraw.last();
    nRows = rsraw.getRow();
    rsraw.beforeFirst();

    % http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSetMetaData.html
    nCols = rsraw.getMetaData().getColumnCount();
    rs = struct();
    [names,typs] = deal(cell(nCols,1));
    for iCol=1:nCols
        names{iCol} = char(rsraw.getMetaData().getColumnName(iCol));
        typs{iCol}  = char(rsraw.getMetaData().getColumnTypeName(iCol));
        % pre-allocate
        if strncmp(typs{iCol},'float',5) || strncmp(typs{iCol},'numeric',7)
            rs.(names{iCol}) = NaN([nRows,1]);
        elseif strncmp(typs{iCol},'int',3)
            rs.(names{iCol}) = NaN([nRows,1]);
        else
            rs.(names{iCol}) = cell(nRows,1);
        end
    end

    count=0;
    while rsraw.next()
        count=count+1;
        for iCol=1:nCols
            if strncmp(typs{iCol},'float',5) || strncmp(typs{iCol},'numeric',7)
                rs.(names{iCol})(count)=rsraw.getDouble(iCol);
            elseif strncmp(typs{iCol},'int',3)
                rs.(names{iCol})(count)=rsraw.getInt(iCol);
            else
                rs.(names{iCol}){count}=char(rsraw.getString(iCol));
            end
        end
    end

    pstat.close();
    rsraw.close();
end


prefs = getpref('postgresql');
if isstruct(prefs) && isfield(prefs, 'verbose') && prefs.verbose
    disp(sql);
end

if isstruct(prefs) && isfield(prefs, 'file') && ~isempty(prefs.file)
    fid = fopen(prefs.file, 'a');
    fprintf(fid, '%s\n', sql);
    fclose(fid);
end


%% Copyright notice
%   --------------------------------------------------------------------
%   Copyright (C) 2012 Deltares
%       Bas Hoonhout
%   Copyright (C) 2014 Van Oord
%       R.A. van der Hout
%
%       bas.hoonhout@deltares.nl
%       ronald.vanderhout@vanoord.com
%
%   JDBC: Copyright (C) 2012 Deltares for Building with Nature
%       Gerben J. de Boer
%       gerben.deboer@deltares.nl
%
%   Copyright (C) 2013 Nederlands eScience Center
%       Stefan Verhoeven
%       s.verhoeven@esciencecenter.nl
%
%   This library is free software: you can redistribute it and/or modify
%   it under the terms of the GNU General Public License as published by
%   the Free Software Foundation, either version 3 of the License, or
%   (at your option) any later version.
%
%   This library is distributed in the hope that it will be useful,
%   but WITHOUT ANY WARRANTY; without even the implied warranty of
%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%   GNU General Public License for more details.
%
%   You should have received a copy of the GNU General Public License
%   along with this library.  If not, see <http://www.gnu.org/licenses/>.
%   --------------------------------------------------------------------

% This tool is part of <a href="http://www.OpenEarth.eu">OpenEarthTools</a>.
% OpenEarthTools is an online collaboration to share and manage data and
% programming tools in an open source, version controlled environment.
% Sign up to recieve regular updates of this function, and to contribute
% your own tools.

%% Version <http://svnbook.red-bean.com/en/1.5/svn.advanced.props.special.keywords.html>
% Created: 27 Jul 2012
% Created with Matlab version: 7.14.0.739 (R2012a)

% $Id$
% $Date$
% $Author$
% $Revision$
% $HeadURL$
% $Keywords: $
