Grails named queries as scroll results - grails

I know that I can do Alert.Criteria().scroll() but I cannot seem to do it with named queries. Can it be done?

Right now, and it looks like this won't change, it is not possible to use scroll() with named queries. You can look at the Grails source code of the NamedQueryProxy (which is the actual instance you get back when calling a named query) at GitHub using this path:
grails-data-mapping/grails-datastore-gorm/src/main/groovy/org/grails/datastore/gorm/query/NamedQueriesBuilder.groovy
According to the Grails team, the named query feature has largely been replaced by where queries. There's some other problems with named queries (like when adding additional criteria at invocation, the query automatically executes .list() ). I opened two issues with the Grails team and it seems they will not be evolving the feature set and stability of named queries in favor of using where queries instead.

Related

Grails 3 script or command with domain classes

All I want is a simple script to update some db tables.
My first try was with create-script. These scripts seem not be able to load domain classes. Then I found people saying, you have to create a command.
But in order to create a command you need to create a plugin.
This seems not very straight forward to a have a simple dbupdate script.
Can somebody enlighten me on this.
Thanks
Torsten
Alright! Looks like it is more related to how perform certain db related operations which are not straight forward db-migrations.
Though there could be enormous choices around it, I would like to discuss what could commonly be used:
Groovy Shell: You could create a straight forward groovy shell for your grails project and there run a script you created. No matter it is for some data update or some migration or just a report etc.
The basic idea is to have a command line available to run scripts that perform certain task. This link should help more.
DBMigration: Though in comment you already said it's not a dbmigration,I think your definition of dbmigration is restricted to schema related operations only. That's not true! DBmigration includes schema + CRUD(including a complicated version with join etc as well). We don't prefer crud operations as part of dbmigration as it could be achieved during bootstrap time or using a service method or even some external query or tool.
Like you perform any operation using your application, you could perform this action too. Suppose, you have to perform some updates and inserts in a table. Simply create a service and a controller which access this service to perform desired results. I know this makes least sense, but overall idea is to have a code which could perform desired action.
Well! I would suggest go ahead with first option and create a new shell project pointing to same database. Perform the action there.

Versioning domain instances for approval in Grails

I’m looking for the best approach to extend the Grails CRUD generation functionality. It should be a Grails plugin which provides additional generators for following functionality:
Any changes on extended domain instance should be saved (as a version
of it) for history
Only one version of an instance can be active
User should be able to activate a version of the instance (the
currently active instance should be deactivated) which is not created
by him (4 eyes principle)
A diff view is nice to have
The intervention into Grails out of the box scripts should be as small as possible.
I identified so far 3 design strategies for implementation:
Mirror table with the same schema, which contains versions (doubles
the count of domains/tables). The activated version will be copied
to the native domain and vice versa.
Using discriminator in the domain class. Some new columns will be added to the domain (like state [active,notActive], lastUpdatedBy,
lastUpdatedDate…)
(De-)Serializing instances to a special domain with BLOB (e.g domain.properties as JSON)
Any of the solutions has pros and cons. What is the best approach to implement it? Perhaps there is a more simple way.
I've been developing a system in Grails that makes intense use of the version concept (as you related above). My approach was the 2nd one listed in your question.
I've created two fields: internalVersion e disabled. Every class that needs to be Versionable, must implement an interface called Versionable.
I'll try explain here one of the scenarios which it's necessary to use the version functionality (forgive my english).
The system that uses this concept is a Commercial System where there is a class called Quote.
Every Quote can has one or more versions where only the last version is valid. Every Quote and its versions are generated based in negotiations with an specific client. This way, a client asks us a Quote and if for some reason he doesn't like the prices (for instance), we can generate a new version with some discount. Every Quote has a unique code following by the current version, example: QT-000022/0 (first version), QT-000022/1 (second version).
To generate a new Version I use a method that clones the current object (using a kind of complete and deep Save As). I copy everything (properties and collections) to a new object.
The clone method identifies that the class implements the Versionable interface and does the following:
oldQuote.disabled = true
newQuote.internalVersion = oldQuote.internalVersion + 1
This way it's possible assure that only one version will be enabled.
I hope you understand my approach.

Applying restrictions to Grails Searchable results

I'm developing an application with Grails 2.2.2 / MySQL.
I'd like to integrate the Searchable plugin, however my application is a multi-tenant saas app, and I need to restrict the results that are returned somehow. So for instance if I am a user of my application belonging to organisation A and I search for products, I should not see any products that belong to organisation B.
I currently have a service that carries out this kind of data partitioning when using the regular grails CRUD pages which works by applying restrictions to every criteria query executed. I've also integrated this service with the Filterpane plugin, for 'advanced search' style queries.
Is it possible to filter Searchable results in a similar way?
It's been a while since I looked into this, but I did come across an interesting article about partitioning a lucene index so that 1) there is one index for the application and 2) search results for organisation A are not biased in any way by the stuff that has been indexed for organisation B (I didn't even consider that second point).
https://community.jivesoftware.com/community/developer/blog/2013/06/24/a-new-experimental-approach-to-implement-multi-tenancy-with-lucene-4
Also, for my application, I've sort of met the 'full text searching' requirement (for the short term at least) by using the excellent Quick Search plugin for grails.
Hopefully someone will find these resources useful.

reloading tire/elasticsearch mappings for a model that already has data stored

I am using Tire and elasticsearch to provide search functionality on a MongoMapper model, which is part of a Rails App. I just stumbled across a problem where the mappings for this model were not being updated when I redeployed to an environment that uses the following configuration (in config/environments/env_name.rb):
config.cache_classes = true
reloading the class alone didn't seem to fix the issue (perhaps understandably, the new mappings might not be incompatible with existing data I guess?). instead I had to do the following:
MyModel.index.delete
<restart the app or reload the class>
MyModel.index.import MyModel.all
I just wondered if there's a better way of a). ensuring the latest mappings defined in my model code are being used by elasticsearch after each deployment but b). avoiding unnecessary repopulating the index with the complete dataset?
We normally deploy using Chef, so I could automate the three steps I used successfully without too much trouble. But I'm new to elasticsearch and tire so I thought it's highly likely I'm misusing both or making things unnecessarily difficult.
Couple of points here:
Tire tries to create the index with correct mapping when the class loads
but Tire does not attempt to create the index for the model when it already exists
So, your question is really more about the proper workflow? When you deploy a new version of the application, you shouldn't re-populate the index, in the same way you don't re-populate the database from some kind of backup.
Automatically checking for index mappings conforming to current definition in the model is certainly possible (compare the MyModel.tire.index.mapping with MyModel.tire.mapping, re-populate if different, etc), it's something I'd be wary to do.
The developer usually knows when she changed the mapping and should re-index the data. Dropping the index, and re-populating also means search downtime, and isn't even feasible for large applications.
A nicer solution is to use a specific index name such as my-index-2012-12 when importing the data, and point a my-index alias to this index. Then you can freely re-populate the index, and flip the alias when you're done, without downtime. Tire tries hard to support you in this kind of workflow (the Rake import task, etc).

Does removing a property from a domain class cause an automatic update to the schema, whereby the corresponding column is dropped?

I'm sort of new at Grails. I've worked with it a bit, but not that much. I'm pretty familiar with Java though. My question is regarding schema updates. I understand that Grails creates Hibernate mappings by looking at the domain classes, and so if I add a new property, Grails will automatically add a column for that property in the database. Does the reverse also hold true? If I remove a property, is that column removed? I'm not seeing that behavior and so I'm wondering if it is a configuration issue.
If I wanted to go into more robust database-management, I'm guessing I will have to use the database-management plugin or something like Liquibase. However, the project I'm working on is pretty simple and for the moment, we haven't decided if we are going in that direction yet.
It depends on your dbCreate setting in DataSource.groovy. If it's create or create-drop then everything gets rebuilt when you restart. If it's update then new tables and columns get added. If it's some other setting then no changes are made.
update doesn't do what most people expect though. It's pessimistic and won't make changes that could result in data loss or corruption. So it won't change the size of a column even if it's wider (e.g. VARCHAR(50) -> VARCHAR(200)). It won't add indexes. It will add a new column that's specified as not-null, but it adds it as nullable since otherwise the previously inserted rows won't be valid. But it won't drop a column or table. So you can easily get into a scenario where you rename a column and end up with two - the old and the new.
Liquibase is a great library and the http://grails.org/plugin/database-migration is popular, so it's easy to get support for both. Once you get past the point in development when your schema stabilizes somewhat you should look into using the plugin.

Resources