Skip to content

Commit 8fdfe14

Browse files
committed
Merge branch 'master' of https://github.com/datajoint/datajoint-matlab into read-32-bit-flag
2 parents c7c8530 + ad36667 commit 8fdfe14

File tree

4 files changed

+77
-14
lines changed

4 files changed

+77
-14
lines changed

+dj/+internal/Header.m

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,17 +152,25 @@ function project(self, params)
152152

153153
include = [self.attributes.iskey]; % always include the primary key
154154
for iAttr=1:length(params)
155-
if strcmp('*',params{iAttr})
155+
if strcmp('*', params{iAttr})
156156
include = include | true; % include all attributes
157157
else
158158
% process a renamed attribute
159159
toks = regexp(params{iAttr}, ...
160160
'^([a-z]\w*)\s*->\s*(\w+)', 'tokens');
161161
if ~isempty(toks)
162-
ix = find(strcmp(toks{1}{1},self.names));
163-
assert(length(ix)==1,'Attribute `%s` not found',toks{1}{1});
164-
assert(~ismember(toks{1}{2},union({self.attributes.alias}, ...
165-
self.names)), 'Duplicate attribute alias `%s`',toks{1}{2})
162+
ix = find(strcmp(toks{1}{1}, self.names));
163+
if ~length(ix)
164+
ix = find(strcmp(toks{1}{1}, {self.attributes.alias}));
165+
assert(length(ix)==1, 'Attribute `%s` not found', toks{1}{1});
166+
self.attributes(self.count + 1) = self.attributes(ix);
167+
self.attributes(self.count).name = self.attributes(self.count).alias;
168+
self.attributes(self.count).alias = '';
169+
ix = self.count;
170+
end
171+
assert(length(ix)==1, 'Attribute `%s` not found', toks{1}{1});
172+
assert(~ismember(toks{1}{2}, union({self.attributes.alias}, ...
173+
self.names)), 'Duplicate attribute alias `%s`', toks{1}{2})
166174
self.attributes(ix).name = toks{1}{2};
167175
self.attributes(ix).alias = toks{1}{1};
168176
else

+dj/Relvar.m

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,17 +98,16 @@ function cleanup(self)
9898
rels(ix).restrict(proj(rels(i)));
9999
else
100100
% Determine which foreign keys have been renamed
101-
alias_index = cellfun(...
102-
@(ref_attr, attr) ~strcmp(ref_attr, attr), ...
103-
fks.ref_attrs, fks.attrs, 'uni', true);
104-
% Create rename arguments for projection
105-
aliased_attrs = cellfun(...
106-
@(ref_attr, attr) sprintf('%s->%s', ref_attr, attr), ...
107-
fks.ref_attrs(alias_index), fks.attrs(alias_index), ...
108-
'uni', false);
101+
fks_ref_attrs_flattened = arrayfun(@(x) x.ref_attrs{:}, fks, 'UniformOutput', false);
102+
fks_attrs_flattened = arrayfun(@(x) x.attrs{:}, fks, 'UniformOutput', false);
103+
% Build OR string query using original and renamed attributes
104+
or_string_query = strjoin(cellfun(...
105+
@(attr,ref_attr) sprintf('%s = "%s"', attr, rels(i).fetch1(ref_attr)), ...
106+
fks_attrs_flattened, fks_ref_attrs_flattened, ...
107+
'uni', 0), ' OR ');
109108
% Restrict table based on projection with rename arguments on
110109
% foreign keys.
111-
rels(ix).restrict(proj(rels(i), aliased_attrs{:}));
110+
rels(ix).restrict(or_string_query);
112111
end
113112
else
114113
rels(ix).restrict(rels(i).restrictions{:});

tests/TestDelete.m

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,33 @@ function TestDelete_testRenamedDelete(testCase)
3636
testCase.verifyEqual(...
3737
length(fetch(Company.Machine & struct('employee_id', 'shan'))), 0);
3838
end
39+
function TestDelete_testTwoFKOnePK(testCase)
40+
st = dbstack;
41+
disp(['---------------' st(1).name '---------------']);
42+
% https:%github.com/datajoint/datajoint-matlab/issues/379
43+
dj.config('safemode', false);
44+
package = 'TestLab';
45+
46+
dj.createSchema(package,[testCase.test_root '/test_schemas'], ...
47+
[testCase.PREFIX '_testlab']);
48+
49+
users = [{'user0'; 'user1'; 'user2'}];
50+
51+
insert(TestLab.User, users);
52+
53+
duty = [{'2020-01-01','user0','user1'},
54+
{'2020-01-02','user1','user2'},
55+
{'2020-12-31','user0','user2'}];
56+
57+
insert(TestLab.Duty, duty);
58+
59+
key.user_id = 'user1';
60+
del(TestLab.User & key);
61+
62+
testCase.verifyEqual(length(fetch(TestLab.User)), 2);
63+
testCase.verifyEqual(length(fetch(TestLab.Duty)), 1);
64+
testCase.verifyEqual(length(fetch(TestLab.User & 'user_id = "user1"')), 0);
65+
testCase.verifyEqual(length(fetch(TestLab.Duty & 'duty_first = "user1" OR duty_second = "user1"')), 0);
66+
end
3967
end
4068
end

tests/TestProjection.m

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,34 @@ function TestProjection_testDateConversion(testCase)
2525

2626
res = q.fetch1('enrolled_date');
2727
testCase.verifyEqual(res, '2018-01-24');
28+
29+
dj.config('safemode', 0);
30+
drop(University.Student);
31+
end
32+
function TestProjection_testRenameSameKey(testCase)
33+
st = dbstack;
34+
disp(['---------------' st(1).name '---------------']);
35+
package = 'University';
36+
37+
c1 = dj.conn(...
38+
testCase.CONN_INFO.host,...
39+
testCase.CONN_INFO.user,...
40+
testCase.CONN_INFO.password,'',true);
41+
42+
dj.createSchema(package,[testCase.test_root '/test_schemas'], ...
43+
[testCase.PREFIX '_university']);
44+
45+
insert(University.Student, {
46+
10 'Raphael' 'Guzman' datestr(datetime, 'yyyy-mm-dd HH:MM:SS')
47+
11 'Shan' 'Shen' '2019-11-25 12:34:56'
48+
12 'Joe' 'Schmoe' '2018-01-24 14:34:16'
49+
});
50+
51+
q = proj(University.Student & 'first_name = "Raphael"', 'student_id->faculty_id', 'student_id->school_id');
52+
testCase.verifyEqual(q.fetch('faculty_id', 'school_id'), struct('faculty_id', 10, 'school_id', 10));
53+
54+
dj.config('safemode', 0);
55+
drop(University.Student);
2856
end
2957
end
3058
end

0 commit comments

Comments
 (0)