GitHub    Download    Forum
Overview
Tutorial
Database setup
Preparing the project
Establish the connection
Shut down the connection
DTDL types
Creating the schema
DADL classes
Entry point object
Write and read attributes
Write and read lists
Extending the schema
Modified entry point object
Write and read objects
Write and read object lists
C++ API
C# API
DTDL
DADL
Setup
C++
C#

Write and read object lists

Storing objects in lists uses a combination of both techniques we have seen before both for lists and for objects.

Create, link and store

First, we create the object.
WShopArticle* pShopArticle;
WShopArticle::Create(&pShopArticle, pInventory);
WShopArticle pShopArticle;
WShopArticle.Create(out pShopArticle, pInventory);
Next, we link the object by writing it to the list.
ArticleList* pArticleList;
pInventory->SetItems(&pArticleList);

ArticleListItem Item;
Item.olShopArticle = pShopArticle;

pArticleList->Insert(NULL, &Item);
ArticleList pArticleList;
pInventory.SetItems(out pArticleList);

ArticleListItem Item = new ArticleListItem();
Item.WShopArticle = pShopArticle;

uint _i;
pArticleList.Insert(out _i, Item);
Next, we have to tell both pShopArticle and pInventory to store the changes we made to them. The store function queues changes into the transaction, waiting for it to be executed.
pShopArticle->Store();
pInventory->Store();
pShopArticle.Store(Transaction.Store);
pInventory.Store(Transaction.Store);
Execute then changes the database.
pInventory->GetDomain()->Execute(Transaction::Store);
pInventory.GetDomain().Execute(Transaction.Store)))
And finally, of course, we can release pShopArticle, because we don't need that object anymore.
pShopArticle->Release();

Open and load

An existing object is opened like before.
const ArticleList* pArticleList;
pInventory->GetItems(&pArticleList);

const ArticleListItem* pItem;
pList->Get(0, &pItem);

WShopArticle* pShopArticle;
WShopArticle::Open(&pShopArticle, pItem->olShopArticle, pInventory);
pShopArticle->Load();
pShopArticle->GetDomain()->Execute(Transaction::Load);
ArticleList pArticleList;
pInventory.GetItems(out pArticleList);

ArticleListItem pItem;
pList.Get(0, out pItem);

WShopArticle pShopArticle;
WShopArticle.Open(out pShopArticle, pItem.ShopArticle.oiObjectId, pInventory, Transaction.Load);
pShopArticle.Load(_WShopArticle.ALL_ATTRIBUTES, Transaction.Load);
pShopArticle.GetDomain().Execute(Transaction.Load);
Now, we can read your data (or perform any other operation).
const wchar_t* strArticleName;
pShopArticle->GetArticleName(&strArticleName);

UINT16 usCount;
pShopArticle->GetCount(&usCount);
string strArticleName;
pShopArticle.GetArticleName(out strArticleName);

UInt16 usCount;
pShopArticle.GetCount(out usCount);
If we don't need the object anymore, we finally release it.
pShopArticle->Release();

Final code

This is what our files might look like in the end:
writeObjectList.cpp
writeObjectList.cs
#include "pch.h"

void writeObjectList(WInventory* pInventory)
{
	// create object
	WShopArticle* pShopArticle;
	WShopArticle::Create(&pShopArticle, pInventory);

	// ArticleName
	wprintf(L"Article name:  \n");
	std::wstring input1;
	getline(std::wcin, input1);
	pShopArticle->SetArticleName(input1.c_str());

	// Count
	wprintf(L"Count: \n");
	std::wstring input2;
	getline(std::wcin, input2);
	pShopArticle->SetCount((UINT16)_wtoi(input2.c_str()));

	// insert objectlink into list
	ArticleList* pArticleList;
	pInventory->SetItems(&pArticleList);

	ArticleListItem Item;
	Item.olArticle = pShopArticle;

	pArticleList->Insert(NULL, &Item);

	// Store
	pShopArticle->Store();	// new object
	pInventory->Store();	// we added an item to the list

	// Execute
	HRESULT hRes;
	if(FAILED(hRes = pInventory->GetDomain()->Execute(Transaction::Store)))
	{
		wprintf(L"Domain failed to execute the transaction (0x%x)", hRes);
	}

	pShopArticle->Release();
}
using System;
using DataFoundationAccess;

namespace TutorialCs
{
	partial class Tutorial
	{
		public static void writeObjectList(WInventory pInventory)
		{
			// create object
			WShopArticle pShopArticle;
			WShopArticle.Create(out pShopArticle, pInventory);

			// ArticleName
			Console.WriteLine("Article name:");
			string input1 = Console.ReadLine();
			pShopArticle.SetArticleName(input1);

			// Count
			Console.WriteLine("Count:");
			ushort input2 = ushort.Parse(Console.ReadLine());
			pShopArticle.SetCount(input2);

			// insert objectlink into list
			ArticleList pArticleList;
			pInventory.SetItems(out pArticleList);

			ArticleListItem Item = new ArticleListItem();
			Item.WShopArticle = pShopArticle;

			uint _i;
			pArticleList.Insert(out _i, Item);

			// Store
			pShopArticle.Store(Transaction.Store);	// new object
			pInventory.Store(Transaction.Store);	// we added an item to the list

			// Execute
			int hRes;
			if(0 > (hRes = pInventory.GetDomain().Execute(Transaction.Store)))
			{
				Console.WriteLine("Domain failed to execute the transaction (0x{0:x})", hRes);
			}

			pShopArticle.Dispose();
		}
	}
}

readObjectList.cpp
readObjectList.cs
#include "pch.h"

void readObjectList(WInventory* pInventory)
{
	HRESULT hRes;

	const ArticleList* pList;
	if(S_OK == (hRes = pInventory->GetItems(&pList)))
	{
		WShopArticle** apArticle = new WShopArticle* [pList->GetLength()];

		for(UINT32 i = 0; i < pList->GetLength(); i++)
		{
			const ArticleListItem* pItem;
			pList->Get(i, &pItem);

			// Open
			WShopArticle::Open(&apArticle[i], pItem->olArticle, pInventory);

			// Load
			apArticle[i]->Load();
		}

		// Execute
		if(FAILED(hRes = pInventory->GetDomain()->Execute(Transaction::Load)))
		{
			wprintf(L"Domain failed to execute the transaction (0x%x)\n", hRes);
		}
		else
		{
			wprintf(L"All ArticleList items (%i)\n\n", pList->GetLength());

			for(UINT32 i = 0; i < pList->GetLength(); i++)
			{
				const wchar_t* strArticleName;
				apArticle[i]->GetArticleName(&strArticleName);

				UINT16 usCount;
				apArticle[i]->GetCount(&usCount);

				wprintf(L"LinkIndex: %i || Article: %ix %s\n", i, usCount, strArticleName);
			}
		}

		for(UINT32 i = 0; i < pList->GetLength(); i++)
			apArticle[i]->Release();

		delete[] apArticle;
	}
	else
		wprintf(L"Cannot read article list (0x%x)\n", hRes);
}
using System;
using DataFoundationAccess;

namespace TutorialCs
{
	partial class Tutorial
	{
		public static void readObjectList(WInventory pInventory)
		{
			int hRes;

			ArticleList pList;
			if(0 == (hRes = pInventory.GetItems(out pList)))
			{
				WShopArticle[] apArticle = new WShopArticle[pList.GetLength()];

				for(UInt32 i = 0; i < pList.GetLength(); i++)
				{
					ArticleListItem pItem;
					pList.Get(i, out pItem);

					// Open
					WShopArticle.Open(out apArticle[i], pItem.Article.oiObjectId, pInventory, Transaction.Load);

					// Load
					apArticle[i].Load(_WShopArticle.ALL_ATTRIBUTES, Transaction.Load);
				}

				// Execute
				if(0 > (hRes = pInventory.GetDomain().Execute(Transaction.Load)))
				{
					Console.WriteLine("Domain failed to execute the transaction (0x{0:x})", hRes);
				}
				else
				{
					Console.WriteLine("All ArticleList items ({0})\n", pList.GetLength());

					for(UInt32 i = 0; i < pList.GetLength(); i++)
					{
						string strArticleName;
						apArticle[i].GetArticleName(out strArticleName);

						UInt16 usCount;
						apArticle[i].GetCount(out usCount);

						Console.WriteLine("LinkIndex: {0} || Article: {1}x {2}", i, usCount, strArticleName);
					}
				}

				for (UInt32 i = 0; i < pList.GetLength(); i++)
					apArticle[i].Dispose();
			}
			else
				Console.WriteLine("Cannot read article list (0x{0:x}))", hRes);
		}
	}
}

Modifying objects in lists

Remember the last time we worked with lists, we mentioned that most times when we work with objects in lists we would only change the object itself and not the actual list item. Here is an example of what that might look like:
modifyObjectInList.cpp
modifyObjectInList.cs
#include "pch.h"

void modifyObjectInList(WInventory* pInventory)
{
	wprintf(L"List index: \n");
	std::wstring input0;
	getline(std::wcin, input0);
	UINT32 indexInput = ((UINT32)_wtoi(input0.c_str()));

	HRESULT hRes;

	const ArticleList* pList;
	if(S_OK != (hRes = pInventory->GetItems(&pList)))
	{
		wprintf(L"Cannot read article list (0x%x)\n", hRes);
		return;
	}

	const ArticleListItem* pOldItem;
	if(S_OK != (hRes = pList->Get(indexInput, &pOldItem)))
	{
		wprintf(L"There is no article with this index\n");
		return;
	}

	WShopArticle* pArticle;
	WShopArticle::Open(&pArticle, pOldItem->olArticle, pInventory);

	// Load
	pArticle->Load();

	// Execute
	if(FAILED(hRes = pInventory->GetDomain()->Execute(Transaction::Load)))
	{
		wprintf(L"Domain failed to execute the transaction (0x%x)\n", hRes);
	}
	else
	{
		wprintf(L"Article name: \n");
		std::wstring input1;
		getline(std::wcin, input1);
		if(input1.length() > 0)
			pArticle->SetArticleName(input1.c_str());

		wprintf(L"Count: \n");
		std::wstring input2;
		getline(std::wcin, input2);
		if(input2.length() > 0)
			pArticle->SetCount((UINT16)_wtoi(input2.c_str()));

		// Store
		pArticle->Store();

		// Execute
		if(FAILED(hRes = pInventory->GetDomain()->Execute(Transaction::Store)))
		{
			wprintf(L"Domain failed to execute the transaction (0x%x)", hRes);
		}
	}

	pArticle->Release();
}
using System;
using DataFoundationAccess;

namespace TutorialCs
{
	partial class Tutorial
	{
		public static void modifyObjectInList(WInventory pInventory)
		{
			Console.WriteLine("List index:");
			UInt32 indexInput = UInt32.Parse(Console.ReadLine());

			int hRes;

			ArticleList pList;
			if(0 != (hRes = pInventory.GetItems(out pList)))
			{
				Console.WriteLine("Cannot read article list (0x{0:x})", hRes);
				return;
            }
			
			ArticleListItem pOldItem;
			if(0 != (hRes = pList.Get(indexInput, out pOldItem)))
            {
				Console.WriteLine("There is no article with this index");
				return;
            }

			WShopArticle pArticle;
			WShopArticle.Open(out pArticle, pOldItem.Article.oiObjectId, pInventory, Transaction.Load);

			// Load
			pArticle.Load(_WShopArticle.ALL_ATTRIBUTES, Transaction.Load);
		
			// Execute
			if(0 > (hRes = pInventory.GetDomain().Execute(Transaction.Load)))
			{
				Console.WriteLine("Domain failed to execute the transaction (0x{0:x})", hRes);
			}
			else
			{
				Console.WriteLine("Article name:");
				string input1 = Console.ReadLine();
				if(input1.Length > 0)
					pArticle.SetArticleName(input1);

				Console.WriteLine("Count:");
				string input2 = Console.ReadLine();
				if(input2.Length > 0)
					pArticle.SetCount(ushort.Parse(input2));

				// Store
				pArticle.Store(Transaction.Store);

				// Execute
				if(0 > (hRes = pInventory.GetDomain().Execute(Transaction.Store)))
				{
					Console.WriteLine("Domain failed to execute the transaction (0x{0:x})", hRes);
				}
			}

			pArticle.Dispose();
		}
	}
}
© 2022 Mobiland AG