Initial commit

This commit is contained in:
YUKI VACHOT 2024-06-05 10:18:10 +02:00
commit eed3b364b1
8 changed files with 235 additions and 0 deletions

8
.idea/.gitignore generated vendored Normal file
View file

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View file

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml generated Normal file
View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.9" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/palantir_schema_changes.iml" filepath="$PROJECT_DIR$/.idea/palantir_schema_changes.iml" />
</modules>
</component>
</project>

8
.idea/palantir_schema_changes.iml generated Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

38
index.html Normal file
View file

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Palantir Foundry - Schema Comparison Tool (New and Old)</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<h1>Palantir Foundry - Schema Comparison Tool (New and Old)</h1>
<div id="helpPanel">
<strong>Help:</strong>
<p>Ensure your text follows this format:</p>
<pre>
{message=New schema is incompatible with old schema, newSchema=FoundrySchema{fieldSchemaList=[FoundryFieldSchema{...}], oldSchema=FoundrySchema{fieldSchemaList=[FoundryFieldSchema{...}]}}
</pre>
</div>
<textarea id="schemaText" placeholder="Paste the text with both old and new schema here..."></textarea>
<button onclick="compareSchemas()">Compare</button>
<div id="result" style="display: none;">
<div class="result-section">
<h2>Added Fields</h2>
<table id="addedTable"></table>
</div>
<div class="result-section">
<h2>Removed Fields</h2>
<table id="removedTable"></table>
</div>
<div class="result-section">
<h2>Modified Fields</h2>
<table id="modifiedTable"></table>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

76
script.js Normal file
View file

@ -0,0 +1,76 @@
function compareSchemas() {
const text = document.getElementById("schemaText").value;
const result = parseSchemas(text);
if (result) {
displayResult(result);
}
}
function parseSchemas(text) {
const oldSchemaMatch = text.match(/oldSchema=FoundrySchema\{fieldSchemaList=\[(.*?)\], dataFrameReaderClass/s);
const newSchemaMatch = text.match(/newSchema=FoundrySchema\{fieldSchemaList=\[(.*?)\], dataFrameReaderClass/s);
if (!oldSchemaMatch || !newSchemaMatch) {
alert("Invalid input. Please ensure the text contains both old and new schema definitions.");
return null;
}
const oldSchema = parseFields(oldSchemaMatch[1]);
const newSchema = parseFields(newSchemaMatch[1]);
const added = newSchema.filter(field => !oldSchema.some(oldField => oldField.name === field.name));
const removed = oldSchema.filter(field => !newSchema.some(newField => newField.name === field.name));
const modified = newSchema.filter(field => {
const oldField = oldSchema.find(oldField => oldField.name === field.name);
return oldField && JSON.stringify(oldField) !== JSON.stringify(field);
});
return { added, removed, modified };
}
function parseFields(fieldsText) {
return fieldsText.split('FoundryFieldSchema{').slice(1).map(fieldText => {
const nameMatch = fieldText.match(/name: Optional\[(.*?)\]/);
const typeMatch = fieldText.match(/type: (\w+)/);
const nullableMatch = fieldText.match(/nullable: (\w+)/);
const userDefinedTypeClassMatch = fieldText.match(/userDefinedTypeClass: (\w+)/);
return {
name: nameMatch ? nameMatch[1] : null,
type: typeMatch ? typeMatch[1] : null,
nullable: nullableMatch ? nullableMatch[1] : null,
userDefinedTypeClass: userDefinedTypeClassMatch ? userDefinedTypeClassMatch[1] : null
};
});
}
function displayResult(result) {
document.getElementById("result").style.display = "block";
const addedTable = document.getElementById("addedTable");
const removedTable = document.getElementById("removedTable");
const modifiedTable = document.getElementById("modifiedTable");
populateTable(addedTable, result.added);
populateTable(removedTable, result.removed);
populateTable(modifiedTable, result.modified);
}
function populateTable(table, data) {
table.innerHTML = `
<tr>
<th>Name</th>
<th>Type</th>
<th>Nullable</th>
<th>User Defined Type Class</th>
</tr>
`;
data.forEach(field => {
const row = table.insertRow();
row.insertCell(0).textContent = field.name;
row.insertCell(1).textContent = field.type;
row.insertCell(2).textContent = field.nullable;
row.insertCell(3).textContent = field.userDefinedTypeClass;
});
}

84
styles.css Normal file
View file

@ -0,0 +1,84 @@
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: flex-start;
height: 100vh;
}
.container {
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
width: 80%;
max-width: 1000px;
margin-top: 20px;
}
h1, h2, h3 {
text-align: center;
margin: 0;
padding: 10px 0;
}
textarea {
width: 100%;
height: 150px;
margin: 10px 0;
padding: 10px;
font-size: 14px;
border: 1px solid #ccc;
border-radius: 4px;
resize: vertical;
}
button {
width: 100%;
padding: 10px;
font-size: 16px;
color: #fff;
background-color: #007bff;
border: none;
border-radius: 4px;
cursor: pointer;
margin-bottom: 20px;
}
button:hover {
background-color: #0056b3;
}
pre {
background-color: #f0f0f0;
padding: 10px;
border-radius: 4px;
overflow-x: auto;
}
#helpPanel {
margin-top: 20px;
padding: 10px;
border: 1px solid #ddd;
background: #f9f9f9;
}
table {
width: 100%;
border-collapse: collapse;
margin-bottom: 20px;
}
th, td {
border: 1px solid black;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
.result-section {
margin-bottom: 30px;
}