Server side query rerun for paging, sort or filtering - derbyjs

What is the best approach to rerun a server query/subscription for a specific connected client when some data on that client changes?
This would be very useful for server side filtering, ordering or paging.
For example, the client has a table with thousands of lines that are paginated, when the user changes the filtering text or page number the server would recompute the query subscription with that filter, and update the client on the fly.
The search input doesn't have to be synced across all connected users of the server, and thus its not needed to be present in the database.
Is there any way to perform this with traditional model methods on both client and server or do I have to implement a RPC like approach as mentioned in the FAQ?
Thanks!

var filter = model.root.filter('items', 'temp.pageNumber', function(item, x,y,pageNumber){
if (item.index > pageNumber*10 && item.index < pageNumber*10+10){
return true;
}
return false;
}
model.root.subscribe(filter,function(){
model.ref('filteredItems', filter);
});
and bind to filteredItems in view.
something like this.

Related

Avoid performing server request on row grouping in server side model for ag grid

I have implemented a server side table, with row grouping, using ag grid. The table makes a request to server for the time to load groups, but when you manually open a group it makes another request. There is a way to send the rows for each group in the first request?
In my application I need the ability to expand or collapse all groups manually, but it is a bit annoying to perform a request to server for each possible group.
If I try implementing a client side model and setting data rows like gridOptions.api.setRowData(data) and works, but if I change rowModelType: to 'serverSide' in gridOptions and configure serverSideDatasource sending the same data used in the client side model it doesn't work.
I have find a partial solution here.
Thank you for your help.

Meteor - using snychronised non-persistent / in-memory MongoDB on the server

in a Meteor app, having real-time reactive updates between all connected clients is achieved with writing in collections, publishing and subscribing the right data. In normal case this means also database writes.
But what if I would like to sync particular data which does not need to be persistent and I would like to save the overhead of writing in the database ? Is it possible to use mini-mongo or other in-memory caching on the server by still preserving DDP synchronisation to all clients ?
Example
In my app I have a multiple collapsed threads and I want to show, which users currently expanded particular thread
Viewed by: Mike, Johny, Steven ...
I can store the information in the threads collection or make make a separate viewers collection and publish the information to the clients. But there is actually no meaning in making this information persistent an having the overhead of database writes.
I am confused by the collections documentation. which states:
OPTIONS
connection Object
The server connection that will manage this collection. Uses the default connection if not specified. Pass the return value of calling DDP.connect to specify a different server. Pass null to specify no connection.
and
... when you pass a name, here’s what happens:
...
On the client (and on the server if you specify a connection), a Minimongo instance is created.
But If I create a new collection and pass the option object with conneciton: null
// Creates a new Mongo collections and exports it
export const Presentations = new Mongo.Collection('presentations', {connection: null});
/**
* Publications
*/
if (Meteor.isServer) {
// This code only runs on the server
Meteor.publish(PRESENTATION_BY_MAP_ID, (mapId) => {
check(mapId, nonEmptyString);
return Presentations.find({ matchingMapId: mapId });
});
}
no data is being published to the clients.
TLDR: it's not possible.
There is no magic in Meteor that allow data being synced between clients while the data doesn't transit by the MongoDB database. The whole sync process through publications and subscriptions is triggered by MongoDB writes. Hence, if you don't write to database, you cannot sync data between clients (using the native pub/sub system available in Meteor).
After countless hours of trying everything possible I found a way to what I wanted:
export const Presentations = new Mongo.Collection('presentations', Meteor.isServer ? {connection: null} : {});
I checked the MongoDb and no presentations collection is being created. Also, n every server-restart the collection is empty. There is a small downside on the client, even the collectionHanlde.ready() is truthy the findOne() first returns undefined and is being synced afterwards.
I don't know if this is the right/preferable way, but it was the only one working for me so far. I tried to leave {connection: null} in the client code, but wasn't able to achieve any sync even though I implemented the added/changed/removed methods.
Sadly, I wasn't able to get any further help even in the meteor forum here and here

Add an extra field to collection only on the client side and not affecting server side

Is there a way to add or inject an additional or new field to a collection and then being able to access that newly inserted field to the collection on the client side and displaying it on a template or accessing it without affecting the server side? I didn't want to compromise with the APIs or the database since it's simply a count of something, like when a customer has a total of 8 deliveries.
I was doing this code where I'm subscribing to a collection and then trying to update the collection on the client side but obviously I should have no rights on updating it:
Meteor.subscribe("all_customers", function () {
Customer.find({}).forEach(function(data) {
var delivery_count = Delivery.find({ customerID: data._id }).count();
Customer.update( { _id: data._id } , { $push: { deliveries: delivery_count } } );
});
}),
And then doing this one where I'd try to manipulate the collection by inserting new key-value pair but it won't display or nothing at all when it's sent:
Meteor.subscribe("all_customers", function () {
Customer.find({}).forEach(function(data) {
var delivery_count = Delivery.find({ customerID: data._id }).count();
data.deliveries = delivery_count;
});
}),
My main objective is to basically be able to sort the count of the deliveries in the EasySearch package without compromising with the APIs or database but the package only sorts an existing field. Or is there a way to do this with the package alone?
Forgive me if this question may sound dumb but I hope someone could help.
It's completely possible, for that you can use low level publications described here: https://docs.meteor.com/api/pubsub.html
You have 2 solutions, one standard, the other hacky:
You follow documentation, you transform your document before sending it to the client. Your server data is not affected and you can enhance data (even do joins) from your subscription. It's cool but you can't push it too far as it might collide and conflict with another publication for the same collection on the same page. Solution is well explained here: How to publish a view/transform of a collection in Meteor?
You can do a client-only collection which will be customs objects with only the data you need. You still have a server-side observer on the source collection but you'll fetch new objects that client will treat and display without any calculation. You need more code but this way, you don't mess with classic server-client collections. It's a bit overkill so ping me if you want a detailed example.

Count email submit in Meteor and MongoDB

I just wrote a small program in meteor and using MongoHQ running under Heroku. This simple app will create a live count of how many people submit the email. You can find the example here: DearJJAbrams
Here is the collection:
Counts = new Meteor.Collection("supporters");
On client side, I run:
Template.CountWrapper.SupporterCount = function () {
return Counts.find().count();
};
Template.BodySupporter.events({
'click .support-click' : function () {
if ($("#supportInputName").val() != "") {
Supporters.insert({name: $("#supportInputName").val()});
$(".signup-form").fadeOut(600, function() {
$(".thank-you-message").fadeIn(600);
});
}
return false;
}
})
The problem is that when the number of users submit their email include, the database seems to do the count query very slow. Is there any better way to handle this?
Thank you.
A look over the raw DDP socket shows you're sending down the entire collection to the client, so in effect everyone downloads the entire 'supporters' collection.
This looks like the bit inefficient. This is because you send down the whole collection (~7000 records - which each looks to be ~100 bytes on the DDP wire), in total nearly 1 mb of data to be downloaded.
So these have to be downloaded first, then the count can be displayed. Why not store the count in a separate collection and only send that down? It should be much faster that way. Unless you're giving the entire list of names on a table or something somewhere it might be better to do this.
The other thing is on your hosting provider you're not letting websockets work so meteor falls back to long-polling (XHR) which is a bit slower to initially connect since there is all this extra overhead. You might want to look at something you have in between, typically a proxy or firewall that isn't configured to let through websocket requests.

How to inspect every query going to DB from Zend Framework

I have a complex reporting application that allows clients to login and view reports for their client data. There are several sections of the application where there are database calls, using various controllers. I need to make sure that client A doesn't get client B's information via header manipulation.
The system authenticates, and assignes them a clientID and roleID. If your roleID >1, that means you work for the company hosting the data, and you can see all client info. I want to create a catch-all that basically works like this:
if($roleID > 1) {
...send query to database
}else {
if(...does this query select a record with clientID other than my $auth->clientID){
do not execute query
}else {
execute query
}
}
The problem is, I want this to run for every query that goes to the server... how can I place this code as a "roadblock" between the application and the DB? I already use Zend_Profiler to look at queries, so I know it is somehow possible, but cannot discern this from the Profiler code...
I can always write an authentication function and pass selected queries that way, but this catch-all would be easier to implement across all of the calls and would be future proof. Any help is appreciated.
it's application design fault.
you shoud use 'service architecture' - the only one entry point for queries would be a service. and any checks inside it.
If this is something you want run on every query, I'd suggest extending Zend_Db_Select and overwrite either the query() or assemble() functions to add in your logic. You'll also want to add a way for it to be aware of your $auth object.
Another option is to extend your database adapter so you can intercept the queries directly. IMO, you should try and do this at the application level though.
Depending on your database server, you can put a trace on the DB side.
Here's an example for Oracle:
http://orafaq.com/wiki/SQL_Trace