u
This commit is contained in:
@@ -206,3 +206,37 @@ WHERE ca.category_id = @categoryId
|
||||
ORDER BY a.id ASC
|
||||
`;
|
||||
|
||||
export const TOUCH_SUBTREE_CATEGORIES = `
|
||||
;WITH cats AS (
|
||||
SELECT id FROM category WHERE id = @id
|
||||
UNION ALL
|
||||
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||
)
|
||||
UPDATE category
|
||||
SET updated_at = SYSUTCDATETIME()
|
||||
WHERE id IN (SELECT id FROM cats)
|
||||
`;
|
||||
|
||||
export const TOUCH_SUBTREE_ARTICLES = `
|
||||
;WITH cats AS (
|
||||
SELECT id FROM category WHERE id = @id
|
||||
UNION ALL
|
||||
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||
)
|
||||
UPDATE article
|
||||
SET updated_at = SYSUTCDATETIME()
|
||||
WHERE id IN (
|
||||
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||
UNION
|
||||
SELECT child.id FROM article child
|
||||
WHERE child.parentarticle_id IN (
|
||||
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||
)
|
||||
UNION
|
||||
SELECT parent.parentarticle_id FROM article parent
|
||||
WHERE parent.id IN (
|
||||
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||
) AND parent.parentarticle_id IS NOT NULL
|
||||
)
|
||||
`;
|
||||
|
||||
|
||||
@@ -129,4 +129,38 @@ FROM categoryarticle ca
|
||||
INNER JOIN article a ON a.id = ca.article_id
|
||||
WHERE ca.category_id IN (SELECT id FROM tree)
|
||||
AND a.parentarticle_id IS NULL
|
||||
`;
|
||||
|
||||
export const TOUCH_SUBTREE_CATEGORIES = `
|
||||
WITH RECURSIVE cats AS (
|
||||
SELECT id FROM category WHERE id = @id
|
||||
UNION ALL
|
||||
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||
)
|
||||
UPDATE category
|
||||
SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
||||
WHERE id IN (SELECT id FROM cats)
|
||||
`;
|
||||
|
||||
export const TOUCH_SUBTREE_ARTICLES = `
|
||||
WITH RECURSIVE cats AS (
|
||||
SELECT id FROM category WHERE id = @id
|
||||
UNION ALL
|
||||
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||
)
|
||||
UPDATE article
|
||||
SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
||||
WHERE id IN (
|
||||
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||
UNION
|
||||
SELECT child.id FROM article child
|
||||
WHERE child.parentarticle_id IN (
|
||||
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||
)
|
||||
UNION
|
||||
SELECT parent.parentarticle_id FROM article parent
|
||||
WHERE parent.id IN (
|
||||
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||
) AND parent.parentarticle_id IS NOT NULL
|
||||
)
|
||||
`;
|
||||
@@ -2,11 +2,15 @@ import {
|
||||
GET_NEXT_SIBLING_SORT as MSSQL_GET_NEXT_SIBLING_SORT,
|
||||
IS_ANCESTOR as MSSQL_IS_ANCESTOR,
|
||||
MOVE as MSSQL_MOVE,
|
||||
TOUCH_SUBTREE_CATEGORIES as MSSQL_TOUCH_SUBTREE_CATEGORIES,
|
||||
TOUCH_SUBTREE_ARTICLES as MSSQL_TOUCH_SUBTREE_ARTICLES,
|
||||
} from '../../providers/mssql/queries/category.js';
|
||||
import {
|
||||
GET_NEXT_SIBLING_SORT as SQLITE_GET_NEXT_SIBLING_SORT,
|
||||
IS_ANCESTOR as SQLITE_IS_ANCESTOR,
|
||||
MOVE as SQLITE_MOVE,
|
||||
TOUCH_SUBTREE_CATEGORIES as SQLITE_TOUCH_SUBTREE_CATEGORIES,
|
||||
TOUCH_SUBTREE_ARTICLES as SQLITE_TOUCH_SUBTREE_ARTICLES,
|
||||
} from '../../providers/sqlite3/queries/category.js';
|
||||
import resolveCategoryAccess from './resolveCategoryAccess.js';
|
||||
import makeRunner from '../runner.js';
|
||||
@@ -20,6 +24,12 @@ export default function move(provider) {
|
||||
? SQLITE_GET_NEXT_SIBLING_SORT
|
||||
: MSSQL_GET_NEXT_SIBLING_SORT;
|
||||
const moveSql = isSqlite ? SQLITE_MOVE : MSSQL_MOVE;
|
||||
const touchCategoriesSql = isSqlite
|
||||
? SQLITE_TOUCH_SUBTREE_CATEGORIES
|
||||
: MSSQL_TOUCH_SUBTREE_CATEGORIES;
|
||||
const touchArticlesSql = isSqlite
|
||||
? SQLITE_TOUCH_SUBTREE_ARTICLES
|
||||
: MSSQL_TOUCH_SUBTREE_ARTICLES;
|
||||
|
||||
/**
|
||||
* Moves a category to a new parent, preventing cycles and cross-company moves.
|
||||
@@ -70,6 +80,9 @@ export default function move(provider) {
|
||||
throw new Error('Category not found');
|
||||
}
|
||||
|
||||
await runner.query(touchCategoriesSql, { id });
|
||||
await runner.query(touchArticlesSql, { id });
|
||||
|
||||
return { id, parentId, sort };
|
||||
};
|
||||
|
||||
|
||||
@@ -225,6 +225,42 @@ describe('store.category', () => {
|
||||
/Not authorized|Parent not found/,
|
||||
);
|
||||
});
|
||||
|
||||
it('touches updated_at on moved category, subcategories, and associated articles', async () => {
|
||||
const topTarget = await create('Move Target');
|
||||
const movedCat = await create('Moved Cat');
|
||||
const subCat = await create('Sub Cat', movedCat.id);
|
||||
const artMoved = await createArticle(store, tenant, { parentId: movedCat.id, name: 'Article in Moved' });
|
||||
const artSub = await createArticle(store, tenant, { parentId: subCat.id, name: 'Article in Sub' });
|
||||
|
||||
const oldDate = '2020-01-01T00:00:00.000Z';
|
||||
await ctx.provider.query(
|
||||
`UPDATE category SET updated_at = '${oldDate}' WHERE id IN (${movedCat.id}, ${subCat.id})`
|
||||
);
|
||||
await ctx.provider.query(
|
||||
`UPDATE article SET updated_at = '${oldDate}' WHERE id IN (${artMoved.id}, ${artSub.id})`
|
||||
);
|
||||
|
||||
await store.category.move({
|
||||
googleAuthId: tenant.googleAuthId,
|
||||
id: movedCat.id,
|
||||
parentId: topTarget.id,
|
||||
});
|
||||
|
||||
const cats = await ctx.provider.query(
|
||||
`SELECT id, updated_at FROM category WHERE id IN (${movedCat.id}, ${subCat.id})`
|
||||
);
|
||||
for (const row of cats.rows) {
|
||||
assert.ok(new Date(row.updated_at) > new Date(oldDate), `Category ${row.id} updated_at was touched`);
|
||||
}
|
||||
|
||||
const arts = await ctx.provider.query(
|
||||
`SELECT id, updated_at FROM article WHERE id IN (${artMoved.id}, ${artSub.id})`
|
||||
);
|
||||
for (const row of arts.rows) {
|
||||
assert.ok(new Date(row.updated_at) > new Date(oldDate), `Article ${row.id} updated_at was touched`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('order', () => {
|
||||
|
||||
Reference in New Issue
Block a user