pip_services4_postgres

Last updated:

0 purchases

pip_services4_postgres Image
pip_services4_postgres Images
Add to Cart

Description:

pip services4 postgres

PostgreSQL components for Pip.Service in Dart #
This module is a part of the Pip.Services polyglot microservices toolkit. It provides a set of components to implement PostgreSQL persistence.
The module contains the following packages:

Build - Factory to create PostreSQL persistence components.
Connect - Connection component to configure PostgreSQL connection to database.
Persistence - abstract persistence components to perform basic CRUD operations.

Quick links:

Configuration
API Reference
Change Log
Get Help
Contribute

Use #
Add this to your package's pubspec.yaml file:
dependencies:
pip_services3_postgres: version
copied to clipboard
As an example, lets create persistence for the following data object.
import 'package:pip_services3_commons/pip_services3_commons.dart';

class MyObject implements IStringIdentifiable, ICloneable {
@override
String? id;
String? key;
String? content;

MyObject();

MyObject.from(this.id, this.key, this.content);

Map<String, dynamic> toJson() {
return <String, dynamic>{'id': id, 'key': key, 'content': content};
}

void fromJson(Map<String, dynamic> json) {
id = json['id'];
key = json['key'];
content = json['content'];
}

@override
MyObject clone() {
return MyObject.from(id, key, content);
}
}
copied to clipboard
The persistence component shall implement the following interface with a basic set of CRUD operations.
abstract class IMyPersistence {
Future<DataPage<MyObject>> getPageByFilter(
IContext? context, FilterParams? filter, PagingParams? paging);

Future<MyObject?> getOneById(IContext? context, String id);

Future<MyObject?> getOneByKey(IContext? context, String key);

Future<MyObject?> create(IContext? context, MyObject? item);

Future<MyObject?> update(IContext? context, MyObject? item);

Future<MyObject?> set(IContext? context, MyObject? item);

Future<MyObject?> deleteById(IContext? context, String? id);
}
copied to clipboard
To implement postgresql persistence component you shall inherit IdentifiablePostgresPersistence.
Most CRUD operations will come from the base class. You only need to override getPageByFilter method with a custom filter function.
And implement a getOneByKey custom persistence method that doesn't exist in the base class.
class MyPostgresPersistence
extends IdentifiablePostgresPersistence<MyObject, String> {
MyPostgresPersistence() : super('myobjects', null) {
ensureSchema_(
"CREATE TABLE myobjects (id VARCHAR(32) PRIMARY KEY, key VARCHAR(50), content VARCHAR(255))");
ensureIndex_("myobjects_key", {'key': 1}, {'unique': true});
}

@override
void defineSchema_() {
// pass
}

String? _composeFilter(FilterParams? filter) {
filter = filter ?? FilterParams();

var criteria = [];

var id = filter.getAsNullableString('id');
if (id != null) criteria.add("id='" + id + "'");

var tempIds = filter.getAsNullableString("ids");
if (tempIds != null) {
var ids = tempIds.split(",");
criteria.add("id IN ('" + ids.join("','") + "')");
}

var key = filter.getAsNullableString("key");
if (key != null) criteria.add("key='" + key + "'");

return criteria.length > 0 ? criteria.join(" AND ") : null;
}

Future<DataPage<MyObject>> getPageByFilter(
IContext? context, FilterParams? filter, PagingParams? paging) {
return super.getPageByFilter_(
context, _composeFilter(filter), paging, null, null);
}

Future<MyObject?> getOneByKey(IContext? context, String key) async {
var query =
"SELECT * FROM " + this.quotedTableName_() + " WHERE \"key\"=@1";
var params = {'1': key};

var res = await client_!.query(query, substitutionValues: params);

var resValues = res.isNotEmpty ? res.first[0][1] : null;

var item = this.convertToPublic_(resValues);

if (item == null)
this.logger_.trace(context, "Nothing found from %s with key = %s",
[this.tableName_, key]);
else
this.logger_.trace(context, "Retrieved from %s with key = %s",
[this.tableName_, key]);

item = this.convertToPublic_(item);
return item;
}
}
copied to clipboard
Alternatively you can store data in non-relational format using IdentificableJsonPostgresPersistence.
It stores data in tables with two columns - id with unique object id and data with object data serialized as JSON.
To access data fields you shall use data->'field' expression or data->>'field' expression for string values.
class MyPostgresJsonPersistence
extends IdentifiableJsonPostgresPersistence<MyObject, String> {
MyPostgresJsonPersistence() : super('myobjects_json', null) {
clearSchema();
ensureTable_(idType: "VARCHAR(32)", dataType: "JSONB");
ensureIndex_(this.tableName_! + '_json_key', {"(data->>'key')": 1},
{'unique': true});
}

@override
void defineSchema_() {
// pass
}

String? _composeFilter(FilterParams? filter) {
filter = filter ?? FilterParams();

var criteria = [];

var id = filter.getAsNullableString('id');
if (id != null) criteria.add("data->>'id'='" + id + "'");

var tempIds = filter.getAsNullableString("ids");
if (tempIds != null) {
var ids = tempIds.split(",");
criteria.add("data->>'id' IN ('" + ids.join("','") + "')");
}

var key = filter.getAsNullableString("key");
if (key != null) criteria.add("data->>'key'='" + key + "'");

return criteria.length > 0 ? criteria.join(" AND ") : null;
}

Future<DataPage<MyObject>> getPageByFilter(
IContext? context, FilterParams? filter, PagingParams? paging) {
return super.getPageByFilter_(
context, _composeFilter(filter), paging, 'id', null);
}

Future<MyObject?> getOneByKey(IContext? context, String key) async {
var query =
"SELECT * FROM " + this.quotedTableName_() + " WHERE data->>'key'=@1";
var params = {'1': key};

var res = await client_!.query(query, substitutionValues: params);

var resValues = res.isNotEmpty ? res.first[0][1] : null;

var item = this.convertToPublic_(resValues);

if (item == null)
this.logger_.trace(context, "Nothing found from %s with key = %s",
[this.tableName_, key]);
else
this.logger_.trace(context, "Retrieved from %s with key = %s",
[this.tableName_, key]);

item = this.convertToPublic_(item);
return item;
}
}
copied to clipboard
Configuration for your microservice that includes postgresql persistence may look the following way.
...
{{#if POSTGRES_ENABLED}}
- descriptor: pip-services:connection:postgres:con1:1.0
connection:
uri: {{{POSTGRES_SERVICE_URI}}}
host: {{{POSTGRES_SERVICE_HOST}}}{{#unless POSTGRES_SERVICE_HOST}}localhost{{/unless}}
port: {{POSTGRES_SERVICE_PORT}}{{#unless POSTGRES_SERVICE_PORT}}5432{{/unless}}
database: {{POSTGRES_DB}}{{#unless POSTGRES_DB}}app{{/unless}}
credential:
username: {{POSTGRES_USER}}
password: {{POSTGRES_PASS}}

- descriptor: myservice:persistence:postgres:default:1.0
dependencies:
connection: pip-services:connection:postgres:con1:1.0
table: {{POSTGRES_TABLE}}{{#unless POSTGRES_TABLE}}myobjects{{/unless}}
{{/if}}
...
copied to clipboard
Now you can install package from the command line:
pub get
copied to clipboard
Develop #
For development you shall install the following prerequisites:

Dart SDK 3
Visual Studio Code or another IDE of your choice
Docker

Install dependencies:
pub get
copied to clipboard
Run automated tests:
pub run test
copied to clipboard
Generate API documentation:
./docgen.ps1
copied to clipboard
Before committing changes run dockerized build and test as:
./build.ps1
./test.ps1
./clear.ps1
copied to clipboard
Contacts #
The module is created and maintained by

Sergey Seroukhov
Danil Prisiazhnyi

License:

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Files In This Product:

Customer Reviews

There are no reviews.