Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions +dj/Relvar.m
Original file line number Diff line number Diff line change
Expand Up @@ -352,14 +352,25 @@ function update(self, attrname, value)

switch true
case isNull
assert(header.attributes(ix).isnullable, ...
'attribute `%s` is not nullable.', attrname)
valueStr = 'NULL';
value = {};
case header.attributes(ix).isString
assert(dj.lib.isString(value), 'Value must be a string')
valueStr = '"{S}"';
value = {char(value)};
if isempty(value)
assert(header.attributes(ix).isnullable, ...
'attribute `%s` is not nullable.', attrname)
valueStr = 'NULL';
value = {};
else
valueStr = '"{S}"';
value = {char(value)};
end
case header.attributes(ix).isBlob
if isempty(value) && header.attributes(ix).isnullable
assert(header.attributes(ix).isnullable, ...
'attribute `%s` is not nullable.', attrname)
valueStr = 'NULL';
value = {};
else
Expand Down
100 changes: 100 additions & 0 deletions +tests/+lib/compareVersions.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
function res = compareVersions(verArray, verComp)
% compareVersions - Semantic version comparison (greater than or equal)
%
% This function evaluates if an array of semantic versions is greater than
% or equal to a reference version.
%
% DISTRIBUTION:
% GitHub: https://github.com/guzman-raphael/compareVersions
% FileExchange: https://www.mathworks.com/matlabcentral/fileexchange/71849-compareversions
%
% res = compareVersions(verArray, verComp)
% INPUT:
% verArray: Cell array with the following conditions:
% - be of length >= 1,
% - contain only string elements, and
% - each element must be of length >= 1.
% verComp: String or Char array that verArray will compare against for
% greater than evaluation. Must be:
% - be of length >= 1, and
% - a string.
% OUTPUT:
% res: Logical array that identifies if each cell element in verArray
% is greater than or equal to verComp.
% TESTS:
% Tests included for reference. From root package directory,
% use command: runtests
%
% EXAMPLES:
% output = compareVersions({'3.2.4beta','9.5.2.1','8.0'}, '8.0.0'); %logical([0 1 1])
%
% NOTES:
% Tests included for reference. From root package directory,
% use command: runtests
%
% Tested: Matlab 9.5.0.944444 (R2018b) Linux
% Author: Raphael Guzman, DataJoint
%
% $License: MIT (use/copy/change/redistribute on own risk) $
% $File: compareVersions.m $
% History:
% 001: 2019-06-12 11:00, First version.
%
% OPEN BUGS:
% - None
res_n = length(verArray);
if ~res_n || max(cellfun(@(c) ~ischar(c) && ...
~isstring(c),verArray)) > 0 || min(cellfun('length',verArray)) == 0
msg = {
'compareVersions:Error:CellArray'
'Cell array to verify must:'
'- be of length >= 1,'
'- contain only string elements, and'
'- each element must be of length >= 1.'
};
error('compareVersions:Error:CellArray', sprintf('%s\n',msg{:}));
end
if ~ischar(verComp) && ~isstring(verComp) || length(verComp) == 0
msg = {
'compareVersions:Error:VersionRef'
'Version reference must:'
'- be of length >= 1, and'
'- a string.'
};
error('compareVersions:Error:VersionRef', sprintf('%s\n',msg{:}));
end
res = false(1, res_n);
for i = 1:res_n
shortVer = strsplit(verArray{i}, '.');
shortVer = cellfun(@(x) str2double(regexp(x,'\d*','Match')), shortVer(1,:));
longVer = strsplit(verComp, '.');
longVer = cellfun(@(x) str2double(regexp(x,'\d*','Match')), longVer(1,:));
shortVer_p = true;
longVer_p = false;
shortVer_s = length(shortVer);
longVer_s = length(longVer);

if shortVer_s > longVer_s
[longVer shortVer] = deal(shortVer,longVer);
[longVer_s shortVer_s] = deal(shortVer_s,longVer_s);
[longVer_p shortVer_p] = deal(shortVer_p,longVer_p);
end

shortVer = [shortVer zeros(1,longVer_s - shortVer_s)];
diff = shortVer - longVer;
match = diff ~= 0;

if ~match
res(i) = true;
else
pos = 1:longVer_s;
pos = pos(match);
val = diff(pos(1));
if val > 0
res(i) = shortVer_p;
elseif val < 0
res(i) = longVer_p;
end
end
end
end
101 changes: 2 additions & 99 deletions +tests/Main.m
Original file line number Diff line number Diff line change
@@ -1,102 +1,5 @@
classdef Main < ...
tests.TestConnection & ...
tests.TestRelationalOperand & ...
tests.TestTls

properties (Constant)
CONN_INFO_ROOT = struct(...
'host', getenv('DJ_HOST'), ...
'user', getenv('DJ_USER'), ...
'password', getenv('DJ_PASS'));
CONN_INFO = struct(...
'host', getenv('DJ_TEST_HOST'), ...
'user', getenv('DJ_TEST_USER'), ...
'password', getenv('DJ_TEST_PASSWORD'));
end

methods (TestClassSetup)
function init(testCase)
disp('---------------INIT---------------');
clear functions;
testCase.addTeardown(@testCase.dispose);

curr_conn = dj.conn(testCase.CONN_INFO_ROOT.host, ...
testCase.CONN_INFO_ROOT.user, testCase.CONN_INFO_ROOT.password,'',true);

ver = curr_conn.query('select @@version as version').version;
if dj.lib.compareVersions(ver,'5.8')
cmd = {...
'CREATE USER IF NOT EXISTS ''datajoint''@''%%'' '
'IDENTIFIED BY ''datajoint'';'
};
curr_conn.query(sprintf('%s',cmd{:}));

cmd = {...
'GRANT ALL PRIVILEGES ON `djtest%%`.* TO ''datajoint''@''%%'';'
};
curr_conn.query(sprintf('%s',cmd{:}));

cmd = {...
'CREATE USER IF NOT EXISTS ''djview''@''%%'' '
'IDENTIFIED BY ''djview'';'
};
curr_conn.query(sprintf('%s',cmd{:}));

cmd = {...
'GRANT SELECT ON `djtest%%`.* TO ''djview''@''%%'';'
};
curr_conn.query(sprintf('%s',cmd{:}));

cmd = {...
'CREATE USER IF NOT EXISTS ''djssl''@''%%'' '
'IDENTIFIED BY ''djssl'' '
'REQUIRE SSL;'
};
curr_conn.query(sprintf('%s',cmd{:}));

cmd = {...
'GRANT SELECT ON `djtest%%`.* TO ''djssl''@''%%'';'
};
curr_conn.query(sprintf('%s',cmd{:}));
else
cmd = {...
'GRANT ALL PRIVILEGES ON `djtest%%`.* TO ''datajoint''@''%%'' '
'IDENTIFIED BY ''datajoint'';'
};
curr_conn.query(sprintf('%s',cmd{:}));

cmd = {...
'GRANT SELECT ON `djtest%%`.* TO ''djview''@''%%'' '
'IDENTIFIED BY ''djview'';'
};
curr_conn.query(sprintf('%s',cmd{:}));

cmd = {...
'GRANT SELECT ON `djtest%%`.* TO ''djssl''@''%%'' '
'IDENTIFIED BY ''djssl'' '
'REQUIRE SSL;'
};
curr_conn.query(sprintf('%s',cmd{:}));
end
end
end

methods (Static)
function dispose()
disp('---------------DISP---------------');
warning('off','MATLAB:RMDIR:RemovedFromPath');

curr_conn = dj.conn(tests.Main.CONN_INFO_ROOT.host, ...
tests.Main.CONN_INFO_ROOT.user, tests.Main.CONN_INFO_ROOT.password, '',true);

cmd = {...
'DROP USER ''datajoint''@''%%'';'
'DROP USER ''djview''@''%%'';'
'DROP USER ''djssl''@''%%'';'
};
res = curr_conn.query(sprintf('%s',cmd{:}));
curr_conn.delete;

warning('on','MATLAB:RMDIR:RemovedFromPath');
end
end
end
end
135 changes: 135 additions & 0 deletions +tests/Prep.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
classdef Prep < matlab.unittest.TestCase
% Setup and teardown for tests.
properties (Constant)
CONN_INFO_ROOT = struct(...
'host', getenv('DJ_HOST'), ...
'user', getenv('DJ_USER'), ...
'password', getenv('DJ_PASS'));
CONN_INFO = struct(...
'host', getenv('DJ_TEST_HOST'), ...
'user', getenv('DJ_TEST_USER'), ...
'password', getenv('DJ_TEST_PASSWORD'));
S3_CONN_INFO = struct(...
'endpoint', getenv('S3_ENDPOINT'), ...
'access_key', getenv('S3_ACCESS_KEY'), ...
'secret_key', getenv('S3_SECRET_KEY'), ...
'bucket', getenv('S3_BUCKET'));
PREFIX = 'djtest';
end
properties
test_root;
end
methods
function obj = Prep()
% Initialize test_root
test_pkg_details = what('tests');
[test_root, ~, ~] = fileparts(test_pkg_details.path);
obj.test_root = [test_root '/+tests'];
end
end
methods (TestClassSetup)
function init(testCase)
disp('---------------INIT---------------');
clear functions;
addpath([testCase.test_root '/test_schemas']);

curr_conn = dj.conn(testCase.CONN_INFO_ROOT.host, ...
testCase.CONN_INFO_ROOT.user, testCase.CONN_INFO_ROOT.password,'',true);
% create test users
ver = curr_conn.query('select @@version as version').version;
if tests.lib.compareVersions(ver,'5.8')
cmd = {...
'CREATE USER IF NOT EXISTS ''datajoint''@''%%'' '
'IDENTIFIED BY ''datajoint'';'
};
curr_conn.query(sprintf('%s',cmd{:}));

cmd = {...
'GRANT ALL PRIVILEGES ON `djtest%%`.* TO ''datajoint''@''%%'';'
};
curr_conn.query(sprintf('%s',cmd{:}));

cmd = {...
'CREATE USER IF NOT EXISTS ''djview''@''%%'' '
'IDENTIFIED BY ''djview'';'
};
curr_conn.query(sprintf('%s',cmd{:}));

cmd = {...
'GRANT SELECT ON `djtest%%`.* TO ''djview''@''%%'';'
};
curr_conn.query(sprintf('%s',cmd{:}));

cmd = {...
'CREATE USER IF NOT EXISTS ''djssl''@''%%'' '
'IDENTIFIED BY ''djssl'' '
'REQUIRE SSL;'
};
curr_conn.query(sprintf('%s',cmd{:}));

cmd = {...
'GRANT SELECT ON `djtest%%`.* TO ''djssl''@''%%'';'
};
curr_conn.query(sprintf('%s',cmd{:}));
else
cmd = {...
'GRANT ALL PRIVILEGES ON `djtest%%`.* TO ''datajoint''@''%%'' '
'IDENTIFIED BY ''datajoint'';'
};
curr_conn.query(sprintf('%s',cmd{:}));

cmd = {...
'GRANT SELECT ON `djtest%%`.* TO ''djview''@''%%'' '
'IDENTIFIED BY ''djview'';'
};
curr_conn.query(sprintf('%s',cmd{:}));

cmd = {...
'GRANT SELECT ON `djtest%%`.* TO ''djssl''@''%%'' '
'IDENTIFIED BY ''djssl'' '
'REQUIRE SSL;'
};
curr_conn.query(sprintf('%s',cmd{:}));
end
end
end
methods (TestClassTeardown)
function dispose(testCase)
disp('---------------DISP---------------');
warning('off','MATLAB:RMDIR:RemovedFromPath');

curr_conn = dj.conn(testCase.CONN_INFO_ROOT.host, ...
testCase.CONN_INFO_ROOT.user, testCase.CONN_INFO_ROOT.password, '',true);

% remove databases
curr_conn.query('SET FOREIGN_KEY_CHECKS=0;');
res = curr_conn.query(['SHOW DATABASES LIKE "' testCase.PREFIX '_%";']);
for i = 1:length(res.(['Database (' testCase.PREFIX '_%)']))
curr_conn.query(['DROP DATABASE ' ...
res.(['Database (' testCase.PREFIX '_%)']){i} ';']);
end
curr_conn.query('SET FOREIGN_KEY_CHECKS=1;');

% remove users
cmd = {...
'DROP USER ''datajoint''@''%%'';'
'DROP USER ''djview''@''%%'';'
'DROP USER ''djssl''@''%%'';'
};
res = curr_conn.query(sprintf('%s',cmd{:}));
curr_conn.delete;

% Remove getSchemas to ensure they are created by tests.
files = dir([testCase.test_root '/test_schemas']);
dirFlags = [files.isdir] & ~strcmp({files.name},'.') & ~strcmp({files.name},'..');
subFolders = files(dirFlags);
for k = 1 : length(subFolders)
delete([testCase.test_root '/test_schemas/' subFolders(k).name ...
'/getSchema.m']);
% delete(['test_schemas/+University/getSchema.m'])
end
rmpath([testCase.test_root '/test_schemas']);
warning('on','MATLAB:RMDIR:RemovedFromPath');
end
end
end
Loading