-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow commas in state of history download #20088
Allow commas in state of history download #20088
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍 |
86185ac
to
1ac5710
Compare
Should we only escape when it's needed? In most case, it will be string without comma or number and we will have quotes for each state even it's not needed. |
Checking to see if the escape is needed will require more overhead than just replacing. You would have to iterate over every string to search for commas and/or quotes, then iterate over the string that contain commas and/or quotes to replace any internal quotes. Also, the state (TimelineState.state) will always be a string, so we don't need to check if it is of a different type. The surrounding quotes won't show up in any system meant to handle CSV as it is part of the CSV spec. It simply means that everything between quotes is a single cell. This may even catch edge-cases we have not considered. |
1ac5710
to
52414e0
Compare
This change would bring us into compliance with points 7 and 8 of https://csv-spec.org/ |
Point 10 does suggest only using quotes when required, but permits the usage even if it is not required. |
We can do something like this. WDYT? const safeState = s.state.includes(",") ? `"${s.state.replaceAll('"', '""')}"` : s.state;
csv.push(`${entityId},${safeState},${formatDate(s.last_changed)}\n`); |
That would be better since it is the recommendation of Point 10 in the CSV standard. We would need to check for a We could extract the "," as a const. Maybe, EDIT: const CSV_DELIMETER = ",";
const safeState = /`${CSV_DELIMETER}|"`/.test(s.state) ? `"${s.state.replaceAll('"', '""')}"` : s.state;
csv.push(`${entityId}${CSV_DELIMETER}${safeState}${CSV_DELIMETER}${formatDate(s.last_changed)}\n`); If REGEX is frowned upon, we can do: const CSV_DELIMETER = ",";
const safeState = (s.state.includes(CSV_DELIMETER) || s.state.includes('"'))? `"${s.state.replaceAll('"', '""')}"` : s.state;
csv.push(`${entityId}${CSV_DELIMETER}${safeState}${CSV_DELIMETER}${formatDate(s.last_changed)}\n`); Where would be the best place for that const? Would it make sense in |
52414e0
to
3ba80cd
Compare
I don't think we need a delimiter const for now. If we want to extend the csv export in the future, I think we should rely on library that do it properly to avoid recoding the wheel. |
ad0c718
to
40720a6
Compare
40720a6
to
60b65a1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you ❤️
Proposed change
When exporting history data to a CSV, surround the state value in quotes so that any internal commas do not create new columns in the output file. Additionally, escape any quotes in the state value.
Type of change
Additional information
Checklist
If user exposed functionality or configuration variables are added/changed: