In my program I need to share connection between many struct for updating data in database.
I use rusqlite for my database
and egui for my GUI
Here my source code.
I put a FIXME in the file counter.rs.
I implemented Widget for displaying data easily.
And when I click on a button I would like to perform a SQL UPDATE ... request but I cannot get database connection.
Thank for you help.
I think I found a solution with the singleton DP but I think it's a bad way to do it.
You may want to separate data from interface - create a separate struct for the Counter UI which holds a DB reference and a copy of the Counter data. Then you can straightforwardly construct such a Counter UI object when you instantiate your counter app, passing your DB connection onwards.
Related
I recently updated an old Delphi project to separate the creation of its data module and opening of that module's TDatabase, TTable and TClientDataSet components from the creation and showing of the app's form. Now, the app can toggle on and off the data components of the app. This new capacity isn't critical of course, but is "nice to have." My tool chain is RS v21 (the marketing version 10.4.1).
Yet there's a problem: after closing and reopening the data components from the UI, data aware controls show no data. Tests show that the underlying tables are open, can be navigated, and field values can be retrieved programmatically.
I've also established that resetting a data aware component's DataSource restores its display of underlying field data.
NB: data aware controls' DataSource are set at design time and, at run time after closing and reopening data tables, are not nil.
I conclude that resetting DataSource has a side effect -- probably tickling the DataLink within.
You can imagine I would like a means to obviate the need to reset a whole bunch of DataSources. The easy hopes that TDataSet methods like Refresh all fail. ;-)
A sketch of the coding inside the app's form looks like this -- to open:
dm:=Tdm.Create(nil);
dm.OpenDatabase;
dm.OpenDataTables;
And closing is the reverse:
dm.CloseDataTables;
dm.CloseDatabase;
dm.Free;
dm:=nil;
In the database Tdm: In design, the datasets are not active, and the database is not connected. Tdm.OpenDatabase envokes Open on the TDatabase; Tdm.OpenDataTables runs through the needed tables using their Open method. Tdm.CloseDatabase and Tdm.CloseDataTables are symmetrical.
Thank you for any insights.
Is there any best practice to bind database connection instances to INDY HTTP Server sessions?
I store usual session data in ARequestInfo.Session.Content.Values but this is only for strings. My current approach for database objects is (TDatabaseis just an example class):
Create a TDictionary<String,TDatabase>.
Create TDatabase instances for every session and store references along with the session id in the dictionary.
Access the dictionary enclosed in critical sections within the session processing to be thread safe.
Destroy TDatabase instances when sessions are destroyed.
I suspect that my approach is overhead and there are much more elegant ways to achieve what I want. If this is the case - Tips are very welcome.
The Session.Content property is a TStrings, which can hold strings AND TObject pointers. You don't need a separate TDictionary to map strings to objects, you can store them together in the Content itself.
Alternatively, you can derive a new class from TIdHTTPSession, add your database connection to that class, and then use the TIdHTTPServer.OnCreateSession event to create instances of that class. Then, to access the database connection, simply typecast any TIdHTTPSession object to your class type.
We are porting a D6 application to XE3.
In D6 I inherited a complex code which used shared datasets and datasources everywhere.
This worked well in D6.
After we could run the XE3 version, we experienced that lookup combo boxes changed.
On dropdown they reset the other dropdown's keyvalues (everywhere in the program)!
If two dropdowns use on dataset, and if I click on the first to down it, and select, on down the second keyvalue changed to NULL; and reverse - if I click on the second, the first's keyvalue change to NULL...
This is global in this program, so I need to find fast solution.
May somebody have any information about this "bug" (or "feature"? :-) ), or have a solution in his/her hand?
Thanks for any answer!
This is intentional. Take a look at the implemention of TCustomDBLookupComboBox.ListLinkDataChanged; in Vcl.DBCtrls. You will find the comment:
{ Fix for Defect# 204311, Non-bound control should clear when list datasource changes }
Solution: put your datasets on a data module. Instantiate that for every form, so every form works with a separate instance of the dataset. Make sure you set the name of the data module to an empty string after instantiation, or the Delphi streaming system will still use the first correctly named instance when hooking up the form's datasources with the datasets.
When the data module(s) are in the form's uses clause (interface or implementation doesn't matter) the IDE will still offer you their components through the Object Inspector.
You will want to put the database connection on a different data module that you only instantiate once (possibly automatically).
Hello People of Stackoverflow, I am using a persistent SharedObject for Adobe Media Server to store and share date in real-time for multiple clients. I am using the SyncEvent to dispatch any event that has been updated.
Reading through the documerntation the SyncEvent contains numerous properties. What i want to achieve is to use remote shared object to store a list of people who are online when one client disconnects all the other clients listed will be updated of the disconnection.
Adobe docs unfortunately doesnt provide any examples how to do this.
Would the best approach be to create a changeList array that contains properties of all members then execute a loop?
Or can anyone suggest any other method?
Thanks
The changelist property of the event contains only the properties that got changed. So, if your shared object contains the list of ids, you should be able to get what you achieve.
Note, that the notification is done for the top level properties stored in the shared object. So, what you want would probably look like:
idSo.setProperty("1", true);
while adding. To remove the user, you should use:
idSo.setProperty("1", null);
To reassert, having
idSo.setProperty("ids", <array of ids>)
would send the whole array when it's updated. So, this would be a bad approach
This sync event would be sent to all the connected shared objects.
In his book on DbContext, #RowanMiller shows how to use the DbSet.Local property to avoid 1.) unnecessary roundtrips to the database and 2.) passing around collections (created with e.g. ToList()) in the application (page 24). I then tried to follow this approach. However, I noticed that from one using [} – block to another, the DbSet.Local property becomes empty:
ObservableCollection<Destination> destinationsList;
using (var context = new BAContext())
{
var query = from d in context.Destinations …;
query.Load();
destinationsList = context.Destinations.Local; //Nonzero here.
}
//Do stuff with destinationsList
using (var context = new BAContext())
{
//context.Destinations.Local zero here again;
//So no way of getting the in-memory data from the previous using- block here?
//Do I have to do another roundtrip to the database here to get the same data I wanted
//to cache locally???
}
Then, what is the point on page 24? How can I avoid the passing around of my collections if the DbSet.Local is only usable inside the using- block? Furthermore, how can I benefit from the change tracking if I use these short-lived context instances not handing over any cache data to each others under the hood? So, if the contexts should be short-lived for freeing resources such as connections, have I to give up the caching for this? I.e. I can’t use both at the same time (short-lived connections but long-lived cache)? So my only option would be to store the results returned by the query in my own variables, exactly what is discouraged in the motivation on page 24?
I am developing a WPF application which maybe will also become multi-tiered in the future, involving WCF. I know Julia has an example of this in her book, but I currently don’t have access to it. I found several others on the web, e.g. http://msdn.microsoft.com/en-us/magazine/cc700340.aspx (old ObjectContext, but good in explaining the inter-layer-collaborations). There, a long-lived context is used (although the disadvantages are mentioned, but no solution to these provided).
It’s not only that the single Destinations.Local gets lost, as you surely know all other entities fetched by the query are, too.
[Edit]:
After some more reading in Julia Lerman’s book, it seems to boil down to that EF does not have 2nd level caching per default; with some (considerable, I think) effort, however, ones can add 3rd party caching solutions, as is also described in the book and in various articles on MSDN, codeproject etc.
I would have appreciated if this problem had been mentioned in the section about DbSet.Local in the DbContext book that it is in fact a first level cache which is destroyed when the using {} block ends (just my proposal to make it more transparent to the readers). After first reading I had the impression DbSet.Local would always return the same reference (Singleton-style) also in the second using {} block despite the new DbContext instance.
But I am still unsure whether the 2nd level cache is the way to go for my WPF application (as Julia mentions the 2nd level cache in her article for distributed applications)? Or is the way to go to get my aggregate root instances (DDD, Eric Evans) of my domain model into memory by one or some queries in a using {} block, disposing the DbContext and only holding the references to the aggregate instances, this way avoiding a long-lived context? It would be great if you could help me with this decision.
http://msdn.microsoft.com/en-us/magazine/hh394143.aspx
http://www.codeproject.com/Articles/435142/Entity-Framework-Second-Level-Caching-with-DbConte
http://blog.3d-logic.com/2012/03/31/using-tracing-and-caching-provider-wrappers-with-codefirst/
The Local property provides a “local view of all Added, Unchanged, and Modified entities in this set”. Like all change tracking it is specific to the context you are currently using.
The DB Context is a workspace for loading data and preparing changes.
If two users were to add changes at the same time, they must not know of the others changes before they saved them. They may discard their prepared changes which suddenly would lead to problems for other other user as well.
A DB Context should be short lived indeed, but may be longer than super short when necessary. Also consider that you may not save resources by keeping it short lived if you do not load and discard data but only add changes you will save. But it is not only about resources but also about the DB state potentially changing while the DB Context is still active and has data loaded; which may be important to keep in mind for longer living contexts.
If you do not know yet all related changes you want to save into the database at once then I suggest you do not use the DB Context to store your changes in-memory but in a data structure in your code.
You can of course use entity objects for doing so without an active DB Context. This makes sense if you do not have another appropriate data class for it and do not want to create one, or decide preparing the changes in them make more sense. You can then use DbSet.Attach to attach the entities to a DB Context for saving the changes when you are ready.