Skip to content

Commit

Permalink
fix: For the decimal type, HANA and SQLite have different behaviors. (#…
Browse files Browse the repository at this point in the history
…119)

Co-authored-by: Nick Josipovic <nick.josipovic@gmail.com>
  • Loading branch information
Sv7enNowitzki and nkaputnik authored Oct 15, 2024
1 parent b355dcd commit 36de362
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 5 deletions.
41 changes: 41 additions & 0 deletions lib/change-log.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,25 @@ const { localizeLogFields } = require("./localization")
const isRoot = "change-tracking-isRootEntity"


function formatDecimal(str, scale) {
if (typeof str === "number" && !isNaN(str)) {
str = String(str);
} else return str;

if (scale > 0) {
let parts = str.split(".");
let decimalPart = parts[1] || "";

while (decimalPart.length < scale) {
decimalPart += "0";
}

return `${parts[0]}.${decimalPart}`;
}

return str;
}

const _getRootEntityPathVals = function (txContext, entity, entityKey) {
const serviceEntityPathVals = []
const entityIDs = _getEntityIDs(txContext.params)
Expand Down Expand Up @@ -316,6 +335,28 @@ function _trackedChanges4 (srv, target, diff) {
const eleParentKeys = element.parent.keys
if (from === to) return

/**
*
* HANA driver always filling up the defined decimal places with zeros,
* need to skip the change log if the value is not changed.
* Example:
* entity Books : cuid {
* price : Decimal(11, 4);
* }
* When price is updated from 3000.0000 to 3000,
* the change log should not be created.
*/
if (
row._op === "update" &&
element.type === "cds.Decimal" &&
cds.db.kind === "hana" &&
typeof to === "number"
) {
const scaleNum = element.scale || 0;
if (from === formatDecimal(to, scaleNum))
return;
}

/**
*
* For the Inline entity such as Items,
Expand Down
4 changes: 2 additions & 2 deletions tests/bookshop/db/data/sap.capire.bookshop-Books.csv
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ID;title;descr;isUsed;author_ID;stock;price;genre_ID;bookStore_ID
9d703c23-54a8-4eff-81c1-cdce6b8376b1;Wuthering Heights;"Wuthering Heights, Emily Brontë's only novel, was published in 1847 under the pseudonym ""Ellis Bell"". It was written between October 1845 and June 1846. Wuthering Heights and Anne Brontë's Agnes Grey were accepted by publisher Thomas Newby before the success of their sister Charlotte's novel Jane Eyre. After Emily's death, Charlotte edited the manuscript of Wuthering Heights and arranged for the edited version to be published as a posthumous second edition in 1850.";true;d4d4a1b3-5b83-4814-8a20-f039af6f0387;12;11.11;11;64625905-c234-4d0d-9bc1-283ee8946770
9d703c23-54a8-4eff-81c1-cdce6b8376b1;Wuthering Heights;"Wuthering Heights, Emily Brontë's only novel, was published in 1847 under the pseudonym ""Ellis Bell"". It was written between October 1845 and June 1846. Wuthering Heights and Anne Brontë's Agnes Grey were accepted by publisher Thomas Newby before the success of their sister Charlotte's novel Jane Eyre. After Emily's death, Charlotte edited the manuscript of Wuthering Heights and arranged for the edited version to be published as a posthumous second edition in 1850.";true;d4d4a1b3-5b83-4814-8a20-f039af6f0387;12;3000.0000;11;64625905-c234-4d0d-9bc1-283ee8946770
676059d4-8851-47f1-b558-3bdc461bf7d5;Jane Eyre;"Jane Eyre /ɛər/ (originally published as Jane Eyre: An Autobiography) is a novel by English writer Charlotte Brontë, published under the pen name ""Currer Bell"", on 16 October 1847, by Smith, Elder & Co. of London. The first American edition was published the following year by Harper & Brothers of New York. Primarily a bildungsroman, Jane Eyre follows the experiences of its eponymous heroine, including her growth to adulthood and her love for Mr. Rochester, the brooding master of Thornfield Hall. The novel revolutionised prose fiction in that the focus on Jane's moral and spiritual development is told through an intimate, first-person narrative, where actions and events are coloured by a psychological intensity. The book contains elements of social criticism, with a strong sense of Christian morality at its core and is considered by many to be ahead of its time because of Jane's individualistic character and how the novel approaches the topics of class, sexuality, religion and feminism.";true;47f97f40-4f41-488a-b10b-a5725e762d5e;11;12.34;11;5ab2a87b-3a56-4d97-a697-7af72334a384
42bc7997-f6ce-4ae9-8a64-ee5e02ef1087;The Raven;"""The Raven"" is a narrative poem by American writer Edgar Allan Poe. First published in January 1845, the poem is often noted for its musicality, stylized language, and supernatural atmosphere. It tells of a talking raven's mysterious visit to a distraught lover, tracing the man's slow fall into madness. The lover, often identified as being a student, is lamenting the loss of his love, Lenore. Sitting on a bust of Pallas, the raven seems to further distress the protagonist with its constant repetition of the word ""Nevermore"". The poem makes use of folk, mythological, religious, and classical references.";true;5c30d395-db0a-4095-bd7e-d4de34646607;333;13.13;16;5ab2a87b-3a56-4d97-a697-7af72334a384
9297e4ea-396e-47a4-8815-cd4622dea8b1;Eleonora;"""Eleonora"" is a short story by Edgar Allan Poe, first published in 1842 in Philadelphia in the literary annual The Gift. It is often regarded as somewhat autobiographical and has a relatively ""happy"" ending.";true;5c30d395-db0a-4095-bd7e-d4de34646607;555;14;16;8aaed432-8336-4b0d-be7e-3ef1ce7f13ea
574c8add-0ee3-4175-ab62-ca09a92c723c;Catweazle;Catweazle is a British fantasy television series, starring Geoffrey Bayldon in the title role, and created by Richard Carpenter for London Weekend Television. The first series, produced and directed by Quentin Lawrence, was screened in the UK on ITV in 1970. The second series, directed by David Reid and David Lane, was shown in 1971. Each series had thirteen episodes, most but not all written by Carpenter, who also published two books based on the scripts.;true;a45da28a-7f55-4b53-8a63-48b61132d1b9;22;15;13;8aaed432-8336-4b0d-be7e-3ef1ce7f13ea
574c8add-0ee3-4175-ab62-ca09a92c723c;Catweazle;Catweazle is a British fantasy television series, starring Geoffrey Bayldon in the title role, and created by Richard Carpenter for London Weekend Television. The first series, produced and directed by Quentin Lawrence, was screened in the UK on ITV in 1970. The second series, directed by David Reid and David Lane, was shown in 1971. Each series had thirteen episodes, most but not all written by Carpenter, who also published two books based on the scripts.;true;a45da28a-7f55-4b53-8a63-48b61132d1b9;22;15;13;8aaed432-8336-4b0d-be7e-3ef1ce7f13ea
2 changes: 1 addition & 1 deletion tests/bookshop/db/schema.cds
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ entity Books : managed, cuid {
@title : '{i18n>books.genre}'
genre : Association to Genres;
stock : Integer;
price : Decimal;
price : Decimal(11, 4);
isUsed : Boolean;
image : LargeBinary @Core.MediaType : 'image/png';
@title : '{i18n>books.bookType}'
Expand Down
18 changes: 16 additions & 2 deletions tests/integration/fiori-draft-enabled.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,14 @@ describe("change log integration test", () => {
});

it("2.2 Child entity update - should log basic data type changes (ERP4SMEPREPWORKAPPPLAT-32 ERP4SMEPREPWORKAPPPLAT-613)", async () => {
cds.services.AdminService.entities.Books.elements.price["@changelog"] = true;

const action = PATCH.bind({}, `/odata/v4/admin/Books(ID=9d703c23-54a8-4eff-81c1-cdce6b8376b1,IsActiveEntity=false)`, {
title: "new title",
author_ID: "47f97f40-4f41-488a-b10b-a5725e762d5e",
genre_ID: 16,
isUsed: false
isUsed: false,
price: 3000
});
await utils.apiAction("admin", "BookStores", "64625905-c234-4d0d-9bc1-283ee8946770", "AdminService", action);
const bookChanges = await adminService.run(
Expand Down Expand Up @@ -344,6 +347,17 @@ describe("change log integration test", () => {
expect(isUsedChange.valueChangedFrom).to.equal("true");
expect(isUsedChange.valueChangedTo).to.equal("false");

// The current price is 3000.0000, and update operation via OData service is price: 3000. In this case, a changelog should not be generated.
const priceChanges = await adminService.run(
SELECT.from(ChangeView).where({
entity: "sap.capire.bookshop.Books",
attribute: "price",
})
);

expect(priceChanges.length).to.equal(0);

delete cds.services.AdminService.entities.Books.elements.price["@changelog"];
});

it("2.3 Child entity delete - should log basic data type changes (ERP4SMEPREPWORKAPPPLAT-32 ERP4SMEPREPWORKAPPPLAT-613)", async () => {
Expand Down Expand Up @@ -604,7 +618,7 @@ describe("change log integration test", () => {
expect(titleChanges.length).to.equal(1);

const titleChange = titleChanges[0];
expect(titleChange.objectID).to.equal("11.11, new title, 12");
expect(titleChange.objectID).to.equal("3000, new title, 12");

cds.services.AdminService.entities.Books["@changelog"] = [
{ "=": "title" },
Expand Down

0 comments on commit 36de362

Please sign in to comment.