Chris Codeblog

Tipps, Tricks & Tutorials rund ums Programmieren

[C++ Builder]: BaaS-Komponenten, erstellen u. laden von Objekten auf Parse

Heute möchte ich euch erklären wie ihr auf parse.com Objekte erstellen und laden könnt – mit den BaaS-Komponenten (Backend as a Serivce) von Embarcadero.

Vorbereitung

Als erstes braucht ihr dazu natürlich einen Account auf parse.com. Ich erstelle mir dazu eine neue App auf parse und nenne diese einfach „Adressen“. Anschließend gehe ich in den „Data Browser“ und lege mir zwei neue Klassen an, „Person“ und „Adressen“.

In den Klassen selbst lege ich folgende Spalten an:

Person

  1. Name (String)
  2. Vorname (String)

Adressen

  1. PLZ (String)
  2. Ort (String)
  3. Strasse (String)
  4. Person (Pointer)

Das Ergebnis sollte dann in etwa so aussehen:

Adressen

Person


Den Dialog gestalten

Nun können wir mit dem Programmieren loslegen. Dazu erstellen wir eine leere VCL-Formularanwendung (das funktioniert natürlich auch mit Firemonkey). Um eine Person zu erfassen lege ich als erstes die entsprechenden Edit-Felder an. Außerdem brauchen wir die BaaS-Komponenten „TParseProvider“ und „TBackendStorage“.
In der Komponente „TBackendStorage“ muss unter „Provider“ der „TParseProvider“ eingetragen werden. In der Eigenschaftenliste des „TParseProviders“ müsst ihr die „ApplicationID“ sowie den „Rest API Key“ eintragen. Beide Schlüssel findet ihr bei Parse unter „Settings -> Application Keys“.

Unsere VCL-Form sieht dann so aus:

VCL-Form


Die erste Person anlegen

Mit einem Doppelklick auf den „Person anlegen“-Button erzeugen wir ein OnClick-Ereigniss. In diesem legen wir über die Komponenten eine neue Person in Parse an.
Daten müssen per JSON übergeben werden. Dazu verwenden wir die schon mitgelieferte Klasse TJSONObject. Diesem können wir beliebig viele TJSONPair übergeben. Dabei gilt immer „Feldname“ : „Wert“.

Mit der Methode CreateObject, die über BackendStorage::Storage zu erreichen ist können wir die Person dann „hochladen“.

Über TBackendEntityValue wird von CreateObject die objectId des erzeugten Objekts zurückgegeben. Der erste Parameter der an CreateObject übergeben wird ist die Klasse (BackendClassName) in der der Datensatz gespeichert werden soll. In unserem Fall also „Person“.

Daraus ergibt sich folgender Code:

	TJSONObject *pPerson;
	TBackendEntityValue entity;

	// JSON-Objekt erzeugen
	pPerson = new TJSONObject();
	// Name
	pPerson->AddPair("Name", this->edtName->Text);
	// Vorname
	pPerson->AddPair("Vorname", this->edtVorname->Text);

	// Objekt an Parse schicken, "entity" enthält die erzeugte objectId
	this->BackendStorage->Storage->CreateObject("Person", pPerson, entity);

	// Speicher wieder freigeben
	delete pPerson;

Eine Person haben wir jetzt angelegt. Wir wollen aber zu dieser Person auch eine Adresse anlegen, die Adresse soll auf die Person Zeigen, zu der sie gehört.


Person incl. Adresse anlegen

Als erstes habe ich die zusätzlich benötigten Felder im Designer angelegt. Das sieht dann so aus:

Person und Adresse

Nun muss unser OnClick-Event noch ein wenig angepasst werden. Als erstes legen wir wie vorher auch den Personensatz an. Über den TBackendEntityValue-Wert können wir dann einen Personen-Pointer definieren und damit dann den kompletten Adress-Satz anlegen. Wichtig ist immer dass man auf die korrekte Schreibung der Feld-/Klassennamen aufpasst (Groß-/Kleinschreibung), sonst funktioniert es nicht. Hier der Code:

	TJSONObject *pPerson, *pPersonPointer, *pAdresse;
	TBackendEntityValue entity;

	// JSON-Objekt erzeugen
	pPerson = new TJSONObject();
	// Name
	pPerson->AddPair("Name", this->edtName->Text);
	// Vorname
	pPerson->AddPair("Vorname", this->edtVorname->Text);

	// Objekt an Parse "schicken", "entity" enthält die erzeugte objectId
	this->BackendStorage->Storage->CreateObject("Person", pPerson, entity);

	// JSON-Objekt erzeugen
	pPersonPointer = new TJSONObject();
	// Typ "Pointer"
	pPersonPointer->AddPair("__type", "Pointer");
	// Klassenname (wo soll der Zeiger hinzeigen)
	pPersonPointer->AddPair("className", "Person");
	// Object-ID (auf welchen Satz soll der Zeiger zeigen?)
	pPersonPointer->AddPair("objectId", entity.ObjectID);

	// Den Adressen-Datensatz basteln
	pAdresse = new TJSONObject();
	pAdresse->AddPair("Person", pPersonPointer);
	pAdresse->AddPair("PLZ", this->edtPLZ->Text);
	pAdresse->AddPair("Ort", this->edtOrt->Text);
	pAdresse->AddPair("Strasse", this->edtStrasse->Text);

	// Adressen-Satz an Parse "schicken"
	this->BackendStorage->Storage->CreateObject("Adressen", pAdresse, entity);

	// Speicher wieder freigeben
	delete pPerson;
	delete pAdresse;

Sehen wir uns nun die Datensätze in Parse an, sehen wir dass erwartete Ergebnis. Wir haben mittlerweile 2 Personensätze und in der Adressen-Klasse befindet sich ein Satz mit einem Zeiger auf eine bestimmte Person. Klickt man darauf wird man auch gleich zur entsprechenden Person „verlinkt“.

Personen

Adressen - Pointer


Daten abfragen

Einfache Abfrage
Natürlich wollen wir die in Parse gespeicherten Daten auch wieder abrufen. Der Einfachheit halber nehme ich zur Anzeige der Daten ein Memofeld. Außerdem brauchen wir für die Abfrage die Komponente TBackendQuery. Hier ein Bild meines fertigen Dialogs:

Abfrage

Beim Klick auf den Lesen-Button sollen erstmal alle Personen ausgegeben werden. Die TBackendQuery-Komponente gibt wieder einen JSON-String zurück den wir – wie beim anlegen auch – mit TJSONObject parsen.

	TJSONObject *pPerson;

	// Der "Abfragetyp"
	this->BackendQuery->BackendService = "Storage";
	// Aus welcher Parse-Klasse wollen wir Daten lesen?
	this->BackendQuery->BackendClassName = "Person";
	// Wie soll sortiert werden?
	this->BackendQuery->QueryLines->Clear();
	this->BackendQuery->QueryLines->Add("order=Name");
	// Die Abfrage ausfuehren
	this->BackendQuery->Execute();

	// Die alten Zeilen aus dem Memofeld loeschen
	this->mePersonen->Lines->Clear();

	// Die Ergebnisliste durchlaufen
	for(int i = 0; i < this->BackendQuery->JSONResult->Count; ++i)
	{
		pPerson = static_cast<TJSONObject*>(this->BackendQuery->JSONResult->Items[i]);

		this->mePersonen->Lines->Add(pPerson->GetValue("Name")->Value() + ", " + pPerson->GetValue("Vorname")->Value());
	}

Über den Parameter QueryLines kann man zusätzliche Einschränkungen festlegen, die ihr der Parse-Dokumentation entnehmen könnt. Wie man in diesem Beispiel sehen kann, nehme ich dadurch die Sortierung vor. Mit „order=Name“, lege ich fest, dass aufsteigend nach dem Namen sortiert werden soll. Eine Absteigende Sortierung würde man durch „order=-Name“ erreichen.

Abfrage auf bestimmte Datensätze
Angenommen wir wollen nur Personen, die mit Nachnamen „Maier“ heißen. Die Abfrage die Parse erwartet würde in diesem Fall so aussehen: „where={„Name“ : „Maier“}“ – also ganz normales JSON. Erweitern wir also unsere Beispiel um diesen Code, das Parsen übernimmt allerdings wieder TJSONObject für uns, TJSONObject::ToString() gibt das erzeugt Objekt als einen normalen JSON-String aus.

	TJSONObject *pPerson, *pPersonAbfrage;

	// Der "Abfragetyp"
	this->BackendQuery->BackendService = "Storage";
	// Aus welcher Parse-Klasse wollen wir Daten lesen?
	this->BackendQuery->BackendClassName = "Person";
	// Wie soll sortiert werden?
	this->BackendQuery->QueryLines->Clear();
	this->BackendQuery->QueryLines->Add("order=Name");

	// Das JSON-Objekt fuer die Abfrage basteln
	pPersonAbfrage = new TJSONObject();
	pPersonAbfrage->AddPair("Name", "Maier");

	// Die Einschraenkung hinzufuegen
	this->BackendQuery->QueryLines->Add("where=" + pPersonAbfrage->ToString());

	// Die Abfrage ausfuehren
	this->BackendQuery->Execute();

	// Die alten Zeilen aus dem Memofeld loeschen
	this->mePersonen->Lines->Clear();

	// Die Ergebnisliste durchlaufen
	for(int i = 0; i < this->BackendQuery->JSONResult->Count; ++i)
	{
		pPerson = static_cast<TJSONObject*>(this->BackendQuery->JSONResult->Items[i]);

		this->mePersonen->Lines->Add(pPerson->GetValue("Name")->Value() + ", " + pPerson->GetValue("Vorname")->Value());
	}

Als Zeiger hinterlegte Datensätze automatisch mit laden
Nun möchte ich meine Adress-Sätze ausgeben. Zusätzlich soll aber die zugehörige Person ausgegeben werden. Dazu gibt es den „include“-Befehl. Dabei wird der Zeiger „aufgelöst“ und anstelle dessen kommt die ganze Person als JSON-Objekt zurück:

	TJSONObject *pPerson, *pAdresse;

	// Der "Abfragetyp"
	this->BackendQuery->BackendService = "Storage";
	// Aus welcher Parse-Klasse wollen wir Daten lesen?
	this->BackendQuery->BackendClassName = "Adressen";
	// Wie soll sortiert werden?
	this->BackendQuery->QueryLines->Clear();
	this->BackendQuery->QueryLines->Add("include=Person");

	// Die Abfrage ausfuehren
	this->BackendQuery->Execute();

	// Die alten Zeilen aus dem Memofeld loeschen
	this->mePersonen->Lines->Clear();

	// Die Ergebnisliste durchlaufen
	for(int i = 0; i < this->BackendQuery->JSONResult->Count; ++i)
	{
		pAdresse = static_cast<TJSONObject*>(this->BackendQuery->JSONResult->Items[i]);
		pPerson = static_cast<TJSONObject*>(pAdresse->GetValue("Person"));

		this->mePersonen->Lines->Add("Person: " + pPerson->GetValue("Name")->Value() + ", " + pPerson->GetValue("Vorname")->Value());
		this->mePersonen->Lines->Add("Adresse: " + pAdresse->GetValue("Strasse")->Value() + ", " + pAdresse->GetValue("PLZ")->Value() + " " + pAdresse->GetValue("Ort")->Value());
	}

Hier könnt Ihr euch das Beispielprojekt herunterladen (funktioniert nur mit C++ Builder XE6). Natürlich habe ich den Application-Key usw. herausgelöscht, Ihr müsst euch also selbst bei Parse anmelden und diese Keys dann eintragen.

Du hast Fragen, Anregungen, o. ä.? Ich freue mich wenn du einen Kommentar hinterlässt!

[C++ Builder]: BaaS-Komponenten, erstellen u. laden von Objekten auf Parse

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Nach oben scrollen