Grails: Use new Multiple Datasources for sharding? - grails

I want to be able to put an object into one of several shards based on a value of a field. In milestone 2.0 I see examples like
def zipCode = ZipCode.auditing.get(42)
zipCode.auditing.save()
But how would I dynamically choose the data source. I want something more like
ZipCode.datasource(1).get(42) // where 1 is calculated based on some other value.
Is there anyway to do that?

See http://grails.org/plugin/sharding which uses the Datasources plugin. The new multiple-datasources support in Grails is the result of moving the Datasources plugin into core, so it should be straightforward to either update the plugin or borrow its code and adapt it.

Related

grails 2 Add new column to f:table

I would like to add a new column with some static values like buttons and links to an existing tag in a view.
Is this possible? In the documentation, I can only find how to add or removes attributes that are part of the domain class. There doesn't seem to be a way to add a column with custom values. Ex: a button with a link to the "show" view and so on.
Looks like (unfortunately) there isn't a standard Grails way to do this.
I did manage to do this by using tables and loops ... to run the loop and then displaying the values using Grails variables. It would be great though if there was a standard Grails way to do this as it seems to be waste to first use a framework and then discard the scaffolding to write your own custom table!

GORM read only columns

Most of our tables have one or more columns which are set by the database, either by a trigger, or we want to use the database default value (which requires not sending the field at all in the insert or update)
This includes transaction dates set in the dB (so all the times are times stamped very accurately by a single source, not relying on the accuracy of the time on an arbitrary server or pc.)
The second VERY common use case is say if a customer record has his address and a last logged in field. the last logged in field (and number of failed logins) is set by another part of the system (e.g. by a web site server). The current overly simplistic CRUD system which GORM provides would overwrite such a field when an operator or customer edits their address for example. This is because GORM includes in its update and insert statements every field, even if it's null, or if it has not been changed.
We need a way to scrub the field from inserts and updates, but still have it used in the read calls.
I.e. a true "read only" attribute.
We tried this:
failedLogins editable: false, attributes: [readonly:true]
Which has no effect on the SQL generated (and doesn't even affect the scaffolded UIs - its still editable in create and edit, in grails 2.4.4 at least, but thats another story)
When we do want to explicitly write one of these fields, such as number of failed logins, we would resort to using embedded SQL.
I saw this post: Read-Only columns
Which asks exactly the same question, but only gives one solution, which is this plugin:
extended GORM mappings
Unfortunately, this plugin has not been updated since 2010, and only works with 1.3. We need something which works with 2.4.4.
Any grails app which has multiple systems which edits independent fields needs something like this, or to do extensive locking (Which is usually out of the question).
E.g. an operator opens the customer details for editing, edits something editable (e.g. address), then the operator fails a login on the website (a different grails or non-grails app), then the operator saves the player details. If the saving included the numberOfFailedLogins field, the system would fail. If opening the player details for editing locked the player, then the player would not be able to login, as updating the "lastLoggedIn" or "numFailedLogins" would fail to be able to write due to the lock. The solution is VERY simple - read only columns. Another way would be to put each read only type field in their own tables, but this would be untenable (and result in hundreds of one field tables)
Or we go back to using MyBatis, which has no such issues, and full control. Sadly, there is no good mybatis plugin for grails.
You can use derived properties for string and number properties:
class Batch {
String name
Integer timesRun
static mapping = {
timesRun formula: 'times_run' //times_run is a column in the "batch" table
}
}
In the code above, timesRun would be read in from the database but ignored in inserts and updates as Hibernate considers the column a calculated one.
Updated the example because the original one may have been misleading
This probably doesn't specifically answer your question, but you can use dynamicUpdates to tell GORM to only update the properties of the domain object that have changed during the current session. So as long as you don't change the "read-only" property in your code it won't be set in the SQL update statement generated by Grails. For added safety you could override (and noop) the setter so that your code can never change that property.
https://grails.github.io/grails-doc/latest/ref/Database%20Mapping/dynamicUpdate.html
One of the downsides of dynamicUpdates is that it might make the Hibernate query cache less useful. However, it seems that some Grails/Hibernate experts recommend that you disable the query cache anyway (at least in older versions of Grails). Not sure if that's true of Grails 2.4+
http://grails.github.io/grails-howtos/en/performanceTuning.html
http://www.anyware.co.uk/2005/2012/11/12/the-false-optimism-of-gorm-and-hibernate/
http://tech.puredanger.com/2009/07/10/hibernate-query-cache/

Fetch data from more than two tables using grails domain

I have 3 table like v_ims_circuits , v_ims_productcodes and v_ims_domainmain and i want to fetch data from this table using grails domain.
Internally query should be build like below query using grails domain.
select cir.circuitname, cir.status, cir.oldname, cir.speed, null "Count of Subs",cir.productcode, cir.ordernr,
cir.createuser, cir.createdate, cir.acquisitiondate,dom.domainname
from v_ims_circuits cir, v_ims_productcodes pc, v_ims_domainmain dom
where cir.productcode = pc.product
and pc.domainid = dom.id
and cir.circuitname = ?
Can any one help me on this.
GORM (and Hibernate) require a different mindset than SQL. The first step is to create domain classes for your three tables; circuits, productcodes, and domainmain. Chapter 7 of the Grails reference guide Object Relational Mapping (GORM) is a good place to start.
Once your domain objects are built section 7.4 Querying with GORM describes several ways you can fetch your data. I also find the Domain Classes Quick Reference to be helpful.

Auto generated values in Grails domain class

Is there a way to add my own auto generated field to domain like id and version , If yes the please guide me . provide me URL form where i can read and under stand the core concept of Grails and Domain specific language .
use install-template in the app to get all default templates:
grails install-template
after which you would be able to see /src/templates (newly created)
Modify DomainClass.groovy under /src/templates/artifacts as below:
#artifact.package#class #artifact.name# {
//according to your need
Long myId
Integer myVersion
static constraints = {
}
}
Done!!!!
Henceforth, when create-domain-class command is used to create a domain class, those fields will be auto populated.
I am not sure I am understanding your question correctly but here is the link to the web features of Grails documentation. The "Link Generation API" may be something you are asking after.
If you would like to manage ID and version than using Spring Security (plugin or full docs) or SQL features may be the direction you want to read more about.
EDIT: Try this Stackoverflow question and answer on using inheritance. Seems to be very similar to what you are asking.
You would need to write an AST transform to inject the fields you want to add automatically. The one that injects ‘id’ and ‘version’ can be found here as an example:
https://github.com/grails/grails-core/blob/master/grails-core/src/main/groovy/org/codehaus/groovy/grails/compiler/injection/DefaultGrailsDomainClassInjector.java
You would then need to write a GORM event listener to automatically update the values of these properties. See
https://github.com/grails/grails-data-mapping/blob/master/grails-datastore-gorm/src/main/groovy/org/grails/datastore/gorm/events/AutoTimestampEventListener.java
For an example of the one that updates the dateCreated/lastUpdated properties.
These can both be written in a separate Gradle/Maven project which you then reference in the dependencies of your BuildConfig.groovy file.

How to get data from another data base in runtime

I need an optimal way to change Database in run-time, whether from hibernate or from JNDI or another. I need to change the database when a user clicks on a specific button (Change dependencies on events).
If you are running Grails 1.3.x you can to use the Burt Beckwith's Datasources plugin, in Grails 2.x that feature has been added to core.
Then you can to use a parameter to pass database connection name
def database = params.database
if(!database) database = "default"
and to use Groovy dynamic method invocation to call it
def zipCode = ZipCode.'${database}'.get(42)
…
zipCode.'${database}'.save()

Resources