Skip to content
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

Fix for storing table extension field and enumextension values on base table, Make Range and Assignment Explorer work (mostly) with simple pools and other smaller stuff #78

Open
wants to merge 59 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
71bf9ef
Show multiple entries even if there's no description given
Dec 20, 2023
d0cac47
correcting
Jun 6, 2024
25ee188
Improve "Show multiple entries even if there's no description given" …
Jun 11, 2024
20dd06e
nextIdCompletionProvider should show only one id for multiple Ranges …
Jun 5, 2024
9166e60
Add fieldAndValueIdsStayInsideObjectRange configuration option
Jun 6, 2024
2107cc0
Store ExtensionValues on Base Object Id
Jun 6, 2024
2ab44a1
avoid "No more objects..." error when assigning from public range (1.…
May 29, 2024
2bf9930
Do not return Id 1 as valid enumextension value id
Apr 24, 2024
65e303f
Add redirectExtensions
Jun 6, 2024
085f4c0
Use AppId (app or pool hash) for consumptions
Apr 29, 2024
5baca32
activate managedPools flag
Apr 29, 2024
7fac2db
include dist and node_modules dir for publishing to Azure Function
Apr 29, 2024
ef6c78e
Temp Commit for vsixName-change and workspace colors
Jun 5, 2024
ecb0f5c
Add reminder that ObjIdConfigJson should have nullable properties
Jun 5, 2024
6223667
remove feature flag
Jun 6, 2024
0b717c4
AppPool Consumption in RangeExplorerView
Apr 26, 2024
3b2fafa
make sure that Assignment Explorer can deal with "codeunit "-file (wi…
Jun 6, 2024
3f182b2
make assignment explorer work with pool, but remove lost nodes as mos…
Jun 6, 2024
6803529
WIP: Make range explorer work with pool. What's missing: Probably a c…
Jun 6, 2024
49ab1c8
Improve view and refactor code: getChildrenOfLogicalObjectTypeNode, g…
Jun 11, 2024
39e57a4
Add SymbolReference and load them async in WorkspaceManager, also acc…
Jun 11, 2024
4688c12
Add dependency packages:
Jul 3, 2024
91f3b0a
avoid processing dependencies when `storeExtensionValuesOrIdsOnBaseOb…
Jul 4, 2024
36ed62b
Add changelog
Jul 4, 2024
e14826c
Split ConsumptionDataOfObject and ConsumptionDataOfFields
Jul 8, 2024
e76d125
Improve getStorageId and Namepsace using HoverProvider (maybe better …
Jul 8, 2024
42a547f
fix duplicated objects
Jul 8, 2024
e987df6
dependencies were loaded again and again
Jul 8, 2024
dff5b90
change getNamespace using usings
Jul 8, 2024
28492d2
add fieldId diagnostic and storeAssignment (reclaim probably not work…
Jul 9, 2024
37c9c49
Add Field/Value diagnostics and add them to the assignment explorer (…
Jul 10, 2024
ff2ee6a
rename "assigned" objects to "lost" objects and hide them in pool usage
Jul 10, 2024
7599cc2
Weakmap.Get(uri) doesn't work, so therefore multiple diagnostics in a…
Jul 10, 2024
84909f8
Add changelog and readme
Jul 11, 2024
836e381
comply with eslint stuff, but turn off naming-convention and curly as…
Jul 12, 2024
6c5ba46
remove temporary suffix from package.json-version
Jul 12, 2024
d0efd41
Combine logical ranges, object type ranges and physical ranges in ran…
Jul 15, 2024
2d16482
re-load root nodes of range and assignment-explorer if config has cha…
Jul 16, 2024
fb90dde
normal sync command wasn't working anymore
Jul 17, 2024
49fe4bf
`Ninja: Automatically Synchronize Object IDs for Entire Workspace` no…
Jul 17, 2024
837cceb
Show which objects aren't updated on auto-sync
Jul 17, 2024
7bc3d40
Show error log if sync has errors
Jul 18, 2024
c8617d3
Merge dirty docs when creating diagnostics/using Assignment Explorer
Jul 18, 2024
22d2020
Add setting `rangesToShowInRangeExplorer`
Jul 18, 2024
f8fb5ac
Fix getting enum value
Jul 25, 2024
ad896e9
respect redirectExtensions when storingAssignments
Sep 3, 2024
3516ec9
Directly refresh diagnostics and assignmentExplorer after Store ID As…
Sep 3, 2024
1d59d6c
2.12.3-david
Sep 3, 2024
71363ba
Loading packages without source fails, so make it optional
Oct 24, 2024
069d3b7
2.12.4-david
Oct 24, 2024
feb2645
Exclude "dist" and "node_modules" again
Oct 24, 2024
089f48e
Remove color customizations, `debug.internalConsoleOptions` and `svg.…
Oct 24, 2024
07e23c0
GetNextRequest.type = ALObjectType | string
Oct 24, 2024
5a316e4
Create own class for temporary parser fix
Oct 24, 2024
7ba87cc
add curly brackets and create new line after if statements
Oct 24, 2024
5367c52
Use `2.13.0` as version
Oct 24, 2024
9c34164
Write in Ninja output instead of console.log
Oct 24, 2024
a4b16fc
If the symbols cannot be loaded because the project was loaded with a…
Nov 14, 2024
0da7e16
If there's no .objidconfig at all, then the warning that no number is…
Jan 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions Ninja Azure Back End.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"files.exclude": {
"**/.git": true,
"**/dist": true,
"**/node_modules": true
"**/node_modules": true,
},
"cSpell.words": [
"alext",
Expand All @@ -52,7 +52,6 @@
"vjeko",
"vjekocom",
"xmlport"
],
"debug.internalConsoleOptions": "neverOpen"
]
}
}
3 changes: 1 addition & 2 deletions Ninja VS Code Extension.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
"xmlport"
],
"typescript.referencesCodeLens.enabled": true,
"editor.formatOnSave": true,
"svg.preview.background": "editor"
"editor.formatOnSave": true
}
}
4 changes: 2 additions & 2 deletions azure-function-app/.vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"**/CVS": true,
"**/.DS_Store": true,
"**/Thumbs.db": true,
"dist": true,
"node_modules": true
"**/dist": true,
"**/node_modules": true
}
}
28 changes: 18 additions & 10 deletions azure-function-app/src/functions/v2/getNext/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,22 @@ import { AppInfo, Range } from "../TypesV2";
import { GetNextRequest, GetNextResponse } from "./types";
import { updateConsumption } from "./update";

const getRealRanges = (type: string, ranges: Range[]) => {
interface ObjectStorageInfo {
storageId: string;
ranges: Range[];
}

const getObjectStorageInfo = (type: string, ranges: Range[], redirectExtensions?: true): ObjectStorageInfo => {
let storageId = type;

if (!type.includes("_")) {
return ranges;
return { storageId, ranges };
}

const parts = type.split("_");
if (parts[0].toLowerCase() === "tableextension") {
return ranges;
if (["tableextension", "enumextension"].includes(parts[0].toLowerCase())) {
storageId = redirectExtensions ? storageId.replace("extension", "") : storageId;
return { storageId, ranges };
}

const id = parseInt(parts[1]);
Expand All @@ -28,7 +36,7 @@ const getRealRanges = (type: string, ranges: Range[]) => {
ranges = [{ from: 1, to: 49999 }, ...ranges];
}

return ranges;
return { storageId, ranges };
}

const limitRanges = (ranges: Range[], require?: number) => {
Expand All @@ -47,10 +55,10 @@ const limitRanges = (ranges: Range[], require?: number) => {

const getNext = new ALNinjaRequestHandler<GetNextRequest, GetNextResponse>(async (request) => {
const appInfo: AppInfo = request.bindings.app || {} as AppInfo;
const { appId, type, perRange, require } = request.body;
const ids = appInfo[type] || [];
const ranges = request.method === "POST" && perRange && require ? limitRanges(request.body.ranges, require) : request.body.ranges;
const realRanges = getRealRanges(type, ranges);
const { appId, type, perRange, require, redirectExtensions } = request.body;
let { storageId, ranges } = getObjectStorageInfo(type, request.body.ranges, redirectExtensions);
const ids = appInfo[storageId] || [];
const realRanges = request.method === "POST" && perRange && require ? limitRanges(ranges, require) : ranges;

const result = {
id: perRange ? findAvailablePerRange(realRanges, ids) : findFirstAvailableId(realRanges, ids),
Expand All @@ -69,7 +77,7 @@ const getNext = new ALNinjaRequestHandler<GetNextRequest, GetNextResponse>(async
};

if (request.method === "POST" && (Array.isArray(result.id) ? result.id.length : result.id)) {
const { app, success } = await updateConsumption(appId, request, type, realRanges, request.body.ranges, updateContext);
const { app, success } = await updateConsumption(appId, request, type, storageId, realRanges, request.body.ranges, updateContext);
if (!success) {
throw new ErrorResponse("Too many attempts at updating BLOB", 409);
}
Expand Down
26 changes: 26 additions & 0 deletions azure-function-app/src/functions/v2/getNext/test.http
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,29 @@ Content-Type: application/json
"perRange": true,
"require": 60000
}

### Assign a next number from 1 to 49999 of an enum

post http://localhost:7071/api/v2/getNext
Content-Type: application/json

{
"appId": "test_ninja",
"type": "enum_50000",
"ranges": [
{
"from": 50000,
"to": 50150
},
{
"from": 60000,
"to": 60009
},
{
"from": 90000,
"to": 90099
}
],
"perRange": true,
"require": 1
}
3 changes: 2 additions & 1 deletion azure-function-app/src/functions/v2/getNext/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { ALObjectType } from "../ALObjectType";
import { Range } from "../TypesV2";

export interface GetNextRequest {
type: ALObjectType;
type: ALObjectType | string;
ranges: Range[];
perRange?: boolean;
require?: number;
redirectExtensions?: true;
}

export interface GetNextResponse {
Expand Down
14 changes: 7 additions & 7 deletions azure-function-app/src/functions/v2/getNext/update.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Blob } from "@vjeko.com/azure-func";
import { findFirstAvailableId } from "../../../common/util";
import { ALObjectType } from "../ALObjectType";
import { ALNinjaRequestContext, AppInfo, Range } from "../TypesV2";
import { ConsumptionUpdateContext } from "./types";
import { ALObjectType } from "../ALObjectType";

interface UpdateResult {
app: AppInfo;
success: boolean;
}

export async function updateConsumption(appId: string, request: ALNinjaRequestContext, type: ALObjectType, assignFromRanges: Range[], appRanges: Range[], context: ConsumptionUpdateContext): Promise<UpdateResult> {
export async function updateConsumption(appId: string, request: ALNinjaRequestContext, type: ALObjectType | string, storageId: string, assignFromRanges: Range[], appRanges: Range[], context: ConsumptionUpdateContext): Promise<UpdateResult> {
let success = true;

const blob = new Blob<AppInfo>(`${appId}.json`);
Expand All @@ -27,13 +27,13 @@ export async function updateConsumption(appId: string, request: ALNinjaRequestCo
}

app._ranges = appRanges;
const consumption = app[type];
const consumption = app[storageId];

// No ids consumed yet, consume the first one and exit
if (!consumption || !consumption.length) {
context.updated = true;
app[type] = [context.id];
request.log(app, "getNext", { type, id: context.id });
app[storageId] = [context.id];
request.log(app, "getNext", { type: storageId, id: context.id });
return { ...app };
}

Expand All @@ -49,8 +49,8 @@ export async function updateConsumption(appId: string, request: ALNinjaRequestCo
}

context.updated = true;
app[type] = [...consumption, context.id].sort((left, right) => left - right);
request.log(app, "getNext", { type, id: context.id });
app[storageId] = [...consumption, context.id].sort((left, right) => left - right);
request.log(app, "getNext", { type, storageId, id: context.id });
return { ...app };
});

Expand Down
9 changes: 6 additions & 3 deletions azure-function-app/src/functions/v2/storeAssignment/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,22 @@ import { StoreAssignmentRequest, StoreAssignmentResponse } from "./types";
import { addAssignment, removeAssignment } from "./update";

const storeAssignment = new ALNinjaRequestHandler<StoreAssignmentRequest, StoreAssignmentResponse>(async (request) => {
const { appId, type, id } = request.body;
const { appId, type, id, fieldId, redirectExtensions } = request.body;
const storageId = `${redirectExtensions ? type.replace("extension", "") : type}${fieldId ? `_${id}` : ""}`;
const idToStore = fieldId || id;

let app: AppInfo, success: boolean = false;
const logContent = { type, id, ...(fieldId && { fieldId }) };

switch (request.method) {
case "POST":
const addResult = await addAssignment(appId, request, type, id);
const addResult = await addAssignment(appId, request, storageId, idToStore, logContent);
app = addResult.app;
success = addResult.success;
break;

case "DELETE":
const removeResult = await removeAssignment(appId, request, type, id);
const removeResult = await removeAssignment(appId, request, storageId, idToStore, logContent);
app = removeResult.app;
success = removeResult.success;
break;
Expand Down
2 changes: 2 additions & 0 deletions azure-function-app/src/functions/v2/storeAssignment/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { ALObjectType } from "../ALObjectType";
export interface StoreAssignmentRequest {
type: ALObjectType;
id: number;
fieldId?: number;
redirectExtensions?: true;
}

export interface StoreAssignmentResponse {
Expand Down
29 changes: 12 additions & 17 deletions azure-function-app/src/functions/v2/storeAssignment/update.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { Blob } from "@vjeko.com/azure-func";
import { ALObjectType } from "../ALObjectType";
import { ALNinjaRequestContext, AppInfo } from "../TypesV2";

interface UpdateResult {
app: AppInfo;
success: boolean;
}

export async function addAssignment(appId: string, request: ALNinjaRequestContext, type: ALObjectType, id: number): Promise<UpdateResult> {
export async function addAssignment(appId: string, request: ALNinjaRequestContext, storageId: string, idToAssign: number, content: any): Promise<UpdateResult> {
let success = true;

const blob = new Blob<AppInfo>(`${appId}.json`);
Expand All @@ -16,26 +15,20 @@ export async function addAssignment(appId: string, request: ALNinjaRequestContex
app = {} as AppInfo;
}

let consumption = app[type];
if (!consumption) {
consumption = [];
}

if (consumption.includes(id)) {
let consumption = app[storageId] || [];
if (consumption.includes(idToAssign)) {
success = false;
return app;
}

app[type] = [...consumption, id].sort((left, right) => left - right);
request.log(app, "addAssignment", { type, id });

app[storageId] = [...consumption, idToAssign].sort((left, right) => left - right);
request.log(app, "addAssignment", content);
return { ...app };
});

return { app, success };
}

export async function removeAssignment(appId: string, request: ALNinjaRequestContext, type: ALObjectType, id: number): Promise<UpdateResult> {
export async function removeAssignment(appId: string, request: ALNinjaRequestContext, storageId: string, idToRemove: number, content: any): Promise<UpdateResult> {
let success = true;

const blob = new Blob<AppInfo>(`${appId}.json`);
Expand All @@ -45,13 +38,15 @@ export async function removeAssignment(appId: string, request: ALNinjaRequestCon
return app;
}

let consumption = app[type];
if (!consumption || !consumption.includes(id)) {
let consumption: number[] = app[storageId] || [];
if (!consumption.includes(idToRemove)) {
return app;
}

app[type] = consumption.filter(x => x !== id);
request.log(app, "removeAssignment", { type, id });
app[storageId] = consumption.filter(x => x !== idToRemove);
if ((app[storageId] as number[]).length === 0)
delete app[storageId];
request.log(app, "removeAssignment", content);

return { ...app };
});
Expand Down
3 changes: 3 additions & 0 deletions azure-function-app/test/AzureTestLibrary/v2/Storage.stub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ export class StubStorage extends StubBuilder implements ContentAnalyzer {
get content(): {} {
return this._content;
}
get appInfo(): AppInfo {
return this._content[`${this._appId}.json`] || {};
}

objectIds(objectType: ALObjectType): number[] {
const app = this._content[`${this._appId}.json`] || {};
Expand Down
Loading