Flutter ObjectDB cleanup during dispose - database

Well, I have a Cubit initialization in State<> class by value loaded from ObjectDB.
#override
void initState() {
super.initState();
final path = (Platform.isAndroid || Platform.isLinux) ? (Directory.current.path + '/theme.db') : '';
final storage = path == '' ? IndexedDBStorage('theme') : FileSystemStorage(path);
final db = SchemaDB<ColorThemeObjectdbSchema> (
storage,
(themeMap) => ColorThemeObjectdbSchema.fromMap(themeMap),
);
initTheme(db);
}
And during disposing of the state I need to update data of database. This is my implementation
#override
void dispose() {
db.cleanup();
db.insert({'themeObject': defaultTheme});
super.dispose();
}
But I am getting these errors
Undefined name 'db' • lib/widgets/states/my_home_page_state.dart:72:3 • undefined_identifier
Undefined name 'db' • lib/widgets/states/my_home_page_state.dart:73:3 • undefined_identifier
The 72nd and 73rd lines are
db.cleanup();
db.insert({'themeObject': defaultTheme});
Thank you for help!

Related

Failing to update value sembast database Flutter

I'm trying to use sambas database as I need it for the web version of my app but I'm struggling with it.
I have an OpeningTimes form in my app that I save to db as a Map.
The logic I use in the saving method is: Load the form from db using the userName parameter of the OpeningTimes object I pass in , if none is found then save it, if instead a record is found then update it with the passed in object. I'm using flutter_bloc to manage it all so in OpeningTimesBloc when the form is saved to db, it loads it and yield it so to update UI to last saved sate. The problem is that when loading from db after updating, the loaded value is not the one passed in update method( eg monMorAct: to be updated from true to false):
flutter: updateOpeningTimes() : update opening time received {userName: zazza zenigata, monMorOp: 10:00, monMorCl: 19:00, monMorAct: false, monAftOp: , monAftCl: , monAftAct: false, tueMorOp: , tueMorCl: , tueMorAct: false, tueAftOp: , tueAftCl: , tueAftAct: false, wedMorOp: , wedMorCl: , wedMorAct: false, wedAftOp: , wedAftCl: , wedAftAct: false, thuMorOp: , thuMorCl: , thuMorAct: false, thuAftOp: , thuAftCl: , thuAftAct: false, friMorOp: , friMorCl: , friMorAct: false, friAftOp: , friAftCl: , friAftAct: false, satMorOp: , satMorCl: , satMorAct: false, satAftOp: , satAftCl: , satAftAct: false, sunMorOp: , sunMorCl: , sunMorAct: false, sunAftOp: , sunAftCl: , sunAftAct: false}
but when loading it:
flutter: loadOpeningTimes() snapshot is: Record(openingTimeStorage, 1) {userName: zazza zenigata, monMorOp: 10:00, monMorCl: 19:00, monMorAct: true, monAftOp: , monAftCl: , monAftAct: false, tueMorOp: , tueMorCl: , tueMorAct: false, tueAftOp: , tueAftCl: , tueAftAct: false, wedMorOp: , wedMorCl: , wedMorAct: false, wedAftOp: , wedAftCl: , wedAftAct: false, thuMorOp: , thuMorCl: , thuMorAct: false, thuAftOp: , thuAftCl: , thuAftAct: false, friMorOp: , friMorCl: , friMorAct: false, friAftOp: , friAftCl: , friAftAct: false, satMorOp: , satMorCl: , satMorAct: false, satAftOp: , satAftCl: , satAftAct: false, sunMorOp: , sunMorCl: , sunMorAct: false, sunAftOp: , sunAftCl: , sunAftAct: false}
Can you spot what I am doing wrong?
As always thank you very much for your time and help.
This is the singleton:
import 'dart:async';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sembast/sembast.dart';
import 'package:sembast/sembast_io.dart';
class AppDatabase {
// Singleton instance
static final AppDatabase _singleton = AppDatabase._();
// Singleton accessor
static AppDatabase get instance => _singleton;
// Completer is used for transforming synchronous code into asynchronous code.
Completer<Database> _dbOpenCompleter;
// A private constructor. Allows us to create instances of AppDatabase
// only from within the AppDatabase class itself.
AppDatabase._();
// Sembast database object
Database _database;
// Database object accessor
Future<Database> get database async {
// If completer is null, AppDatabaseClass is newly instantiated, so database is not yet opened
if (_dbOpenCompleter == null) {
_dbOpenCompleter = Completer();
// Calling _openDatabase will also complete the completer with database instance
_openDatabase();
}
// If the database is already opened, awaiting the future will happen instantly.
// Otherwise, awaiting the returned future will take some time - until complete() is called
// on the Completer in _openDatabase() below.
return _dbOpenCompleter.future;
}
Future _openDatabase() async {
// Get a platform-specific directory where persistent app data can be stored
final appDocumentDir = await getApplicationDocumentsDirectory();
// Path with the form: /platform-specific-directory/demo.db
final dbPath = join(appDocumentDir.path, 'demo.db');
final database = await databaseFactoryIo.openDatabase(dbPath);
// Any code awaiting the Completer's future will now start executing
_dbOpenCompleter.complete(database);
}
}
This is the bloc:
class OpeningTimesBloc extends Bloc<OpeningTimesEvent, OpeningTimesState> {
OpeningTimesRepository _openingTimesRepository = OpeningTimesRepository();
#override
OpeningTimesState get initialState => InitialState();
#override
Stream<OpeningTimesState> mapEventToState(OpeningTimesEvent event) async* {
if (event is LoadOpeningTimes) {
print('GetOpeningTimes event received');
yield* _mapLoadOpeningTimesToState(event);
}
if (event is SaveOpeningTimes) {
yield* _mapSaveOpeningTimesToState(event);
}
}
Stream<OpeningTimesState> _mapLoadOpeningTimesToState(
LoadOpeningTimes event) async* {
OpeningTimes openingTimes = await _openingTimesRepository.loadOpeningTimes(
userName: event.user.name);
print(
'_mapLoadOpeningTimesToState() loaded openingTimes is: ${openingTimes.toMap().toString()}');
yield ShopOpeningTimes(openingTimes);
}
Stream<OpeningTimesState> _mapSaveOpeningTimesToState(
SaveOpeningTimes event) async* {
await _openingTimesRepository.saveOpeningTimes(event.openingTimes);
add(LoadOpeningTimes(event.user));
}
}
this is the repository:
import 'package:sembast/sembast.dart';
class OpeningTimesRepository {
// name for the storage
static const String openingTimeStorage = 'openingTimeStorage';
// storage reference
final _openingTimesFolder = intMapStoreFactory.store(openingTimeStorage);
// database instance
Future<Database> get _db async => await AppDatabase.instance.database;
Future saveOpeningTimes(OpeningTimes openingTimes) async {
print(
'saveOpeningTimes(): save opening times received ${openingTimes.toMap().toString()}'); // prints correct
final snapshot = await loadOpeningTimes(userName: openingTimes.userName);
print('saveOpeningTimes() snapshot is $snapshot');
if (snapshot == null) {
print('opening times are to save');
await _openingTimesFolder.add(await _db, openingTimes.toMap());
} else {
print('opening times are to update');
await updateOpeningTimes(openingTimes);
}
}
Future updateOpeningTimes(OpeningTimes openingTimes) async {
print(
'updateOpeningTimes() : update opening time received ${openingTimes.toMap().toString()}'); // correct
final Finder finder = Finder(filter: Filter.byKey(openingTimes.userName));
await _openingTimesFolder.update(await _db, openingTimes.toMap(),
finder: finder);
}
Future<OpeningTimes> loadOpeningTimes({String userName}) async {
print(
'loadOpeningTimes() called userName is $userName'); // prints correct userName
final finder = Finder(sortOrders: [SortOrder('userName')]);
final snapshot =
await _openingTimesFolder.findFirst(await _db, finder: finder);
print('loadOpeningTimes() snapshot is: ${snapshot}'); // correct
return OpeningTimes.fromMap(snapshot.value);
}
}
and this is the model:
import 'package:flutter/material.dart';
class OpeningTimes {
int id;
final String userName;
final String monMorOp;
final String monMorCl;
final bool monMorAct;
final String monAftOp;
final String monAftCl;
final bool monAftAct;
final String tueMorOp;
final String tueMorCl;
final bool tueMorAct;
final String tueAftOp;
final String tueAftCl;
final bool tueAftAct;
final String wedMorOp;
final String wedMorCl;
final bool wedMorAct;
final String wedAftOp;
final String wedAftCl;
final bool wedAftAct;
final String thuMorOp;
final String thuMorCl;
final bool thuMorAct;
final String thuAftOp;
final String thuAftCl;
final bool thuAftAct;
final String friMorOp;
final String friMorCl;
final bool friMorAct;
final String friAftOp;
final String friAftCl;
final bool friAftAct;
final String satMorOp;
final String satMorCl;
final bool satMorAct;
final String satAftOp;
final String satAftCl;
final bool satAftAct;
final String sunMorOp;
final String sunMorCl;
final bool sunMorAct;
final String sunAftOp;
final String sunAftCl;
final bool sunAftAct;
OpeningTimes(
{#required this.userName,
#required this.monMorOp,
#required this.monMorCl,
#required this.monMorAct,
#required this.monAftOp,
#required this.monAftCl,
#required this.monAftAct,
#required this.tueMorOp,
#required this.tueMorCl,
#required this.tueMorAct,
#required this.tueAftOp,
#required this.tueAftCl,
#required this.tueAftAct,
#required this.wedMorOp,
#required this.wedMorCl,
#required this.wedMorAct,
#required this.wedAftOp,
#required this.wedAftCl,
#required this.wedAftAct,
#required this.thuMorOp,
#required this.thuMorCl,
#required this.thuMorAct,
#required this.thuAftOp,
#required this.thuAftCl,
#required this.thuAftAct,
#required this.friMorOp,
#required this.friMorCl,
#required this.friMorAct,
#required this.friAftOp,
#required this.friAftCl,
#required this.friAftAct,
#required this.satMorOp,
#required this.satMorCl,
#required this.satMorAct,
#required this.satAftOp,
#required this.satAftCl,
#required this.satAftAct,
#required this.sunMorOp,
#required this.sunMorCl,
#required this.sunMorAct,
#required this.sunAftOp,
#required this.sunAftCl,
#required this.sunAftAct});
#override
List<Object> get props => [
userName,
monMorOp,
monMorCl,
monMorAct,
monAftOp,
monAftCl,
monAftAct,
tueMorOp,
tueMorCl,
tueMorAct,
tueAftOp,
tueAftCl,
tueAftAct,
wedMorOp,
wedMorCl,
wedMorAct,
wedAftOp,
wedAftCl,
wedAftAct,
thuMorOp,
thuMorCl,
thuMorAct,
thuAftOp,
thuAftCl,
thuAftAct,
friMorOp,
friMorCl,
friMorAct,
friAftOp,
friAftCl,
friAftAct,
satMorOp,
satMorCl,
satMorAct,
satAftOp,
satAftCl,
satAftAct,
sunMorOp,
sunMorCl,
sunMorAct,
sunAftOp,
sunAftCl,
sunAftAct
];
factory OpeningTimes.fromMap(Map<String, dynamic> map) => new OpeningTimes(
userName: map['userName'],
monMorOp: map['monMorOp'],
monMorCl: map['monMorCl'],
monMorAct: map['monMorAct'],
monAftOp: map['monAftOp'],
monAftCl: map['monAftCl'],
monAftAct: map['monAftAct'],
tueMorOp: map['tueMorOp'],
tueMorCl: map['tueMorCl'],
tueMorAct: map['tueMorAct'],
tueAftOp: map['tueAftOp'],
tueAftCl: map['tueAftCl'],
tueAftAct: map['tueAftAct'],
wedMorOp: map['wedMorOp'],
wedMorCl: map['wedMorCl'],
wedMorAct: map['wedMorAct'],
wedAftOp: map['wedAftOp'],
wedAftCl: map['wedAftCl'],
wedAftAct: map['wedAftAct'],
thuMorOp: map['thuMorOp'],
thuMorCl: map['thuMorCl'],
thuMorAct: map['thuMorAct'],
thuAftOp: map['thuAftOp'],
thuAftCl: map['thuAftCl'],
thuAftAct: map['thuAftAct'],
friMorOp: map['friMorOp'],
friMorCl: map['friMorCl'],
friMorAct: map['friMorAct'],
friAftOp: map['friAftOp'],
friAftCl: map['friAftCl'],
friAftAct: map['friAftAct'],
satMorOp: map['satMorOp'],
satMorCl: map['satMorCl'],
satMorAct: map['satMorAct'],
satAftOp: map['satAftOp'],
satAftCl: map['satAftCl'],
satAftAct: map['satAftAct'],
sunMorOp: map['sunMorOp'],
sunMorCl: map['sunMorCl'],
sunMorAct: map['sunMorAct'],
sunAftOp: map['sunAftOp'],
sunAftCl: map['sunAftCl'],
sunAftAct: map['sunAftAct'],
);
Map<String, dynamic> toMap() => {
'userName': userName,
'monMorOp': monMorOp,
'monMorCl': monMorCl,
'monMorAct': monMorAct,
'monAftOp': monAftOp,
'monAftCl': monAftCl,
'monAftAct': monAftAct,
'tueMorOp': tueMorOp,
'tueMorCl': tueMorCl,
'tueMorAct': tueMorAct,
'tueAftOp': tueAftOp,
'tueAftCl': tueAftCl,
'tueAftAct': tueAftAct,
'wedMorOp': wedMorOp,
'wedMorCl': wedMorCl,
'wedMorAct': tueMorAct,
'wedAftOp': wedAftOp,
'wedAftCl': wedAftCl,
'wedAftAct': wedAftAct,
'thuMorOp': thuMorOp,
'thuMorCl': thuMorCl,
'thuMorAct': thuMorAct,
'thuAftOp': thuAftOp,
'thuAftCl': thuAftCl,
'thuAftAct': thuAftAct,
'friMorOp': friMorOp,
'friMorCl': friMorCl,
'friMorAct': friMorAct,
'friAftOp': friAftOp,
'friAftCl': friAftCl,
'friAftAct': friAftAct,
'satMorOp': satMorOp,
'satMorCl': satMorCl,
'satMorAct': satMorAct,
'satAftOp': satAftOp,
'satAftCl': satAftCl,
'satAftAct': satAftAct,
'sunMorOp': sunMorOp,
'sunMorCl': sunMorCl,
'sunMorAct': sunMorAct,
'sunAftOp': sunAftOp,
'sunAftCl': sunAftCl,
'sunAftAct': sunAftAct
};
}
Updated repository methods to use autogenerated key:
static const String openingTimeStorage = 'openingTimeStorage';
// storage reference
final _openingTimesFolder = intMapStoreFactory.store(openingTimeStorage);
// database instance
Future<Database> get _db async => await AppDatabase.instance.database;
Future saveOpeningTimes(OpeningTimes openingTimes) async {
print(
'saveOpeningTimes(): save opening times received ${openingTimes.toMap().toString()}'); // prints correct
final snapshot = await loadOpeningTimes();
print('saveOpeningTimes() snapshot is $snapshot');
if (snapshot == null) {
print('opening times are to save');
await _openingTimesFolder.add(await _db, openingTimes.toMap());
return;
} else {
print('opening times are to update');
await updateOpeningTimes(openingTimes);
}
}
Future updateOpeningTimes(OpeningTimes openingTimes) async {
print(
'updateOpeningTimes() : update opening time received ${openingTimes.toMap().toString()}'); // correct
final Finder finder = Finder(
filter: Filter.byKey(
_openingTimesFolder.record(openingTimes.id).get(await _db)));
await _openingTimesFolder.update(await _db, openingTimes.toMap(),
finder: finder);
}
Future<OpeningTimes> loadOpeningTimes() async {
final finder = Finder(sortOrders: [SortOrder('userName')]);
final snapshot =
await _openingTimesFolder.findFirst(await _db, finder: finder);
if (snapshot != null) {
print('loadOpeningTimes() snapshot is: $snapshot'); // correct
OpeningTimes openingTimes = OpeningTimes.fromMap(snapshot.value);
openingTimes.id = snapshot.key;
return openingTimes;
} else {
return null;
}
}
on updating I get flutter: Erros is Invalid argument(s): Record key cannot be null.
In updateOpeningTimes your filter looks incorrect.
final Finder finder = Finder(filter: Filter.byKey(openingTimes.userName));
Here you are looking for objects with the userName as the key but the key is an int (autogenerated) here so it cannot match. You should have something like:
final Finder finder = Finder(filter: Filter.equals('userName', userName));
In loadOpeningTimes, you just take the first record sorted by userName. If you look for an explicit userName, you should use the same finder than for update.
As a side note, it is a lot faster to load records by key: store.record(key).get(db)

Laravel UUID from SQL Server Database Errors

I am having issues with a Laravel application using an existing database where MS SQL UUIDs are used. My application has a customer:
class Customer extends Model
{
protected $table = 'ERP.Customer';
public $timestamps = false;
protected $primaryKey = 'CustID';
protected $keyType = 'string';
protected $fillable = [
'CustID',
'SysRowID',
'CustNum',
'LegalName',
'ValidPayer',
'TerritoryID',
'Address1',
'Address2',
'Address3',
'City',
'State',
'Zip',
'Country',
'SalesRepCode',
'CurrencyCode',
'TermsCode',
'CreditHold',
'FaxNum',
'PhoneNum',
'CustomerType'
];
public function SalesTer()
{
return $this->belongsTo(SalesTer::class,'TerritoryID', 'TerritoryID');
}
public function Shipments()
{
return $this->hasMany(Shipment::class, 'CustNum', 'CustNum');
}
public function Equipments()
{
return $this->hasMany(Equipment::class,'CustNum', 'CustNum');
}
public function Customer_UD()
{
return $this->hasOne(Customer_UD::class,'ForeignSysRowID', 'SysRowID');
}
}
Which (in the native ERP application) has a UD table which end users can used to customise the Customer entity:
class Customer_UD extends Model
{
protected $table = 'ERP.Customer_UD';
protected $primaryKey = 'ForeignSysRowID';
public $timestamps = false;
public $incrementing = false;
protected $keyType = 'string';
protected $fillable = [
'ForeignSysRowID',
'MakesCans_c',
'MakesEnds_c',
'Industry_c'
];
public function Customer()
{
return $this->hasOne(Customer::class,'SysRowID', 'ForeignSysRowID');
}
}
CustomerController:
public function show($CustID)
{
if(Customer::find($CustID))
{
$Customer = Customer::find($CustID);
$Customer_UD = $Customer->Customer_UD()
->get();
$Shipments = $Customer->Shipments()
->where('Voided', '0')
->get();
$Equipments = $Customer->Equipments()
->with('Part') // load the Part too in a single query
->where('SNStatus', 'SHIPPED')
->get();
return view('Customer.show', ['NoCust' => '0'],
compact('Equipments', 'Customer','Shipments', 'Parts', 'Customer_UD'));
}
else
{
return view('Customer.show', ['NoCust' => '1']);
}
}
The Customer has (for whatever reason) a CustID (which people use to refer to the customer) a CustNum (which is not used outside of the database and a SysRowID. The SysRowID is used to link the Customer table with the Customer_UD table.
An example row from Customer_UD is:
My issue is that when trying to return the UD fields along with the Customer fields I get an error:
SQLSTATE[HY000]: General error: 20018 Incorrect syntax near ''.
[20018] (severity 15) [select * from [ERP].[Customer_UD] where [ERP].
[Customer_UD].[ForeignSysRowID] = '���_�X�O�Q׊3�^w' and [ERP].
[Customer_UD].[ForeignSysRowID] is not null]
I thought it was odd, so I commended out the Customer_UD lines in the CustomerController and simply tried to display the Customer UUID field in the show blade:
SysRowID: {{$Customer->SysRowID}}
I get nothing, no errors but no data. I created a controller and index blade for the Customer_UD model and can display all of the Customer_UD database fields apart from the UUID field.
I don't actually want to display the UUID fields - but do need to use them to build the relationships. Can anyone help point me in the right direction?
I found that adding:
'options' => [
PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER => true,
],
To the database configuration in config\database.php resolved the issue.

Fatal error: Declaration of CRMCoreContactController::save($contact) must be compatible with EntityAPIController::save

I recently installed CRM Core and all of its missing modules needed to run it. Sadly I need this module for the project that I am working on but the second I installed them I got this error.
Fatal error: Declaration of CRMCoreContactController::save($contact) must be compatible with EntityAPIController::save($entity, ?DatabaseTransaction $transaction = NULL) in /opt/lampp/htdocs/drupal/modules/crm_core/modules/crm_core_contact/includes/crm_core_contact.controller.inc on line 111
I went back in the code and I couldn't see what to change. Line 111 is the ver last line of the code. Ill paste the code as well maybe someone out there knows how to solve this, please.
<?php
/**
* CRM Contact Entity Class.
*/
class CRMCoreContactEntity extends Entity {
protected function defaultLabel() {
return crm_core_contact_label($this);
}
protected function defaultUri() {
return array(
'path' => 'crm-core/contact/' . $this->identifier(),
'options' => array(
'absolute' => TRUE,
),
);
}
/**
* Method for de-duplicating contacts.
*
* Allows various modules to identify duplicate contact records through
* hook_crm_core_contact_match. This function should implement it's
* own contact matching scheme.
*
* #return array
* Array of matched contact IDs.
*/
public function match() {
$checks = & drupal_static(__FUNCTION__);
$matches = array();
if (!isset($checks->processed)) {
$checks = new stdClass();
$checks->engines = module_implements('crm_core_contact_match');
$checks->processed = 1;
}
// Pass in the contact and the matches array as references.
// This will allow various matching tools to modify the contact
// and the list of matches.
$values = array(
'contact' => &$this,
'matches' => &$matches,
);
foreach ($checks->engines as $module) {
module_invoke($module, 'crm_core_contact_match', $values);
}
// It's up to implementing modules to handle the matching logic.
// Most often, the match to be used should be the one
// at the top of the stack.
return $matches;
}
}
/**
* #file
* Controller class for contacts.
*
* This extends the DrupalDefaultEntityController class, adding required
* special handling for contact objects.
*/
class CRMCoreContactController extends EntityAPIController {
public $revisionKey = 'vid';
public $revisionTable = 'crm_core_contact_revision';
/**
* Create a basic contact object.
*/
public function create(array $values = array()) {
global $user;
$values += array(
'contact_id' => '',
'vid' => '',
'uid' => $user->uid,
'created' => REQUEST_TIME,
'changed' => REQUEST_TIME,
);
return parent::create($values);
}
/**
* Update contact object before saving revision.
*/
protected function saveRevision($entity) {
if (!isset($entity->log)) {
$entity->log = '';
}
$entity->is_new_revision = TRUE;
$entity->uid = $GLOBALS['user']->uid;
return parent::saveRevision($entity);
}
/**
* Updates 'changed' property on save.
*/
public function save($contact) {
$contact->changed = REQUEST_TIME;
// Storing formatted contact label for autocomplete lookups.
$contact->name = crm_core_contact_label($contact);
return parent::save($contact);
}
}
Changing
public function save($contact)
to
public function save($contact, DatabaseTransaction $transaction = NULL)
should work.
You need to switch from PHP 7.x+ to PHP 5.6. This will resolve this error.
Can't give you more advice on how to downgrade without more details on what system you're running but there are many guides out there on this topic.

handling events that do not generate alerts in Apache Flink

I'm using Flink CEP and I need to handle even events that do not generate alerts. Please how can I do it?
I'm consuming events from rabbitMq and have defined some patterns. Now what I need to do is to send all the events received in another Queue to a distant API. I'm new at Flink so I followed the example in the documentation. When I try to send them after matching the received events with the patterns defined I only get those how match with the patterns. What I want to do is just to put an attribute to true in my events for example and send them all to the output queue.
public static void cep() throws Exception {
/**
* RabbitMQ connection
*/
final RMQConnectionConfig connectionConfig = new RMQConnectionConfig.Builder()
.setHost(HOST)
.setPort(PORTS[RD.getValue()])
.setUserName("guest")
.setPassword("guest")
.setVirtualHost("/")
.build();
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
/**
* Retrieve data inputEventstream from rabbitMQ
*/
final DataStream<String> inputEventstream = env
.addSource(new RMQSource<>(
connectionConfig, // config for the RabbitMQ connection
"input", // name of the RabbitMQ queue to consume
true, // use correlation ids; can be false if only at-least-once is required
new SimpleStringSchema())) // deserialization schema to turn messages into Java objects
.setParallelism(1);
/**
* Change DataStream<String> to DataStream<MonitoringEvent> where
* MonitoringEvent refer to a class which modelize our event.
*/
DataStream<MonitoringEvent> inputEventStreamClean = inputEventstream.flatMap(new Tokenizer());
Pattern<MonitoringEvent, ?> warningPattern = Pattern.<MonitoringEvent>begin("start")
.subtype(MonitoringEvent.class)
.where(new SimpleCondition<MonitoringEvent>() {
#Override
public boolean filter(MonitoringEvent value) {
return Integer.parseInt(value.getAncienneChute())>=CHUTE_GRAVE;
}
}).or(new SimpleCondition<MonitoringEvent>() {
#Override
public boolean filter(MonitoringEvent value) {
return value.isChaiseRoulante();
}
}).or(new SimpleCondition<MonitoringEvent>() {
#Override
public boolean filter(MonitoringEvent value) {
return value.isDeambulateur();
}
}).or(new SimpleCondition<MonitoringEvent>() {
#Override
public boolean filter(MonitoringEvent value) {
return value.isDeambulateur();
}
})
.or(new SimpleCondition<MonitoringEvent>() {
#Override
public boolean filter(MonitoringEvent value) {
return EntityManager.getInstance().hasCurrentYearFallTwice(value.getIdClient());
}
});
//PatternStream<MonitoringEvent> fallPatternStream = CEP.pattern(inputEventStreamClean.keyBy("idClient"), warningPattern);
inputEventStreamClean.print();
// Create a pattern stream from our warning pattern
PatternStream<MonitoringEvent> tempPatternStream = CEP.pattern(
inputEventStreamClean.keyBy("idClient"),
warningPattern);
DataStream<FallWarning> warnings = tempPatternStream.select(
(Map<String, List<MonitoringEvent>> pattern) -> {
MonitoringEvent first = (MonitoringEvent) pattern.get("start").get(0);
return new FallWarning(first.getIdClient(), Integer.valueOf(first.getAncienneChute()));
}
);
// Alert pattern: Two consecutive temperature warnings appearing within a time interval of 20 seconds
Pattern<FallWarning, ?> alertPattern = Pattern.<FallWarning>begin("start");
// Create a pattern stream from our alert pattern
PatternStream<FallWarning> alertPatternStream = CEP.pattern(
//warnings.keyBy("idClient"),
warnings,
alertPattern);
// Generate alert
DataStream<Alert> alerts = alertPatternStream.flatSelect(
(Map<String, List<FallWarning>> pattern, Collector<Alert> out) -> {
FallWarning first = pattern.get("start").get(0);
if (first.idNiveauUrgence>=CHUTE_GRAVE && (first.isChaiseRoulante() || first.isDeambulateur() || first.isFracture())) {
out.collect(new Alert(first.idClient));
}
});
// Print the warning and alert events to stdout
warnings.print();
alerts.print(); // here I can send them to RabbitMq
env.execute();
}
You just need to add a Sink to your "alert" DataStream like
alert.addSink(new RMQSink<String>(
connectionConfig, // config for the RabbitMQ connection
"queueName", // name of the RabbitMQ queue to send messages to
new SimpleStringSchema())); // serialization schema to turn Java objects to messages
per example at
https://ci.apache.org/projects/flink/flink-docs-release-1.2/dev/connectors/rabbitmq.html

Symfony3 FOS UserBundle how to load choice as entity

I am using Symfony3.1 with FOS UsersBundle and I want some added fields to be loaded as specific Entity.
In RegistrationType I have
->add('country', ChoiceType::class, array(
'label' => 'label.country',
'required' => false,
'placeholder' => 'label.select_country',
'choices' => array(
'France' => '7v8tqr',
),
))
In my Entity User I have
/**
* #ORM\OneToOne(targetEntity="Country")
* #ORM\JoinColumn(name="country", referencedColumnName="short")
*/
protected $country;
I can't use the EntityType as it loads every available entity and I use the same kind of field for provinces and cities which are quite huge (I manage their content with javascript).
When I load a registered user, the country field is served as a Country Entity but when I register a new user or modify an existing one, I only have the string "short" which causes an error Expected value of type "AppBundle\Entity\Country" for association field "AppBundle\Entity\User#$country", got "string" instead..
Is there a solution ?
Thanks to #mcriecken who led me in the right direction, I have implemented the following solution, using an EventListener
in services.yml
app_user.registration:
class: AppBundle\EventListener\UserRegistrationListener
arguments: ['#doctrine.orm.entity_manager']
tags:
- { name: kernel.event_subscriber }
and the EventListener UserRegistrationListener.php
<?php
namespace AppBundle\EventListener;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Doctrine\ORM\EntityManager;
class UserRegistrationListener implements EventSubscriberInterface
{
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
/**
* {#inheritDoc}
*/
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess',
);
}
public function onRegistrationSuccess(FormEvent $event)
{
$form = $event->getForm()->getData();
//Gets the locations
$form->setCountry($this->getCountry($form->getCountry()));
$form->setProvince($this->getProvince($form->getProvince()));
$form->setCity($this->getCity($form->getCity()));
}
//Loads the country as an entity
public function getCountry($short)
{
if ($short == null) return null;
$repository = $this->em->getRepository('AppBundle:Country');
return $repository->findOneByShort($short);
}
//Loads the province as an entity
public function getProvince($short)
{
if ($short == null) return null;
$repository = $this->em->getRepository('AppBundle:Province');
return $repository->findOneByShort($short);
}
//Loads the city as an entity
public function getCity($short)
{
if ($short == null) return null;
$repository = $this->em->getRepository('AppBundle:City');
return $repository->findOneByShort($short);
}
}
Then at the end my FOS User object contains COuntry, Province and City as Objects and it can be saved to DB :-)

Resources