I have recently attempted to create an application that allows me to compare 3 separate databases for their values. The databases are 3 Oracle instances which house (essentially) the same database, but in a DEV/TEST/PROD setting.
What I want to do is create one Domain class in GRAILS 3. I then want to be able to fetch the records which that domain class maps to, but do it for all 3 environments.
From reading the Grails 3 docs, it looks like this should be possible by defining 3 datasources in application.yml (in my example here I define 4):
dataSources:
dataSource:
pooled: true
jmxExport: true
logSql: true
driverClassName: oracle.jdbc.OracleDriver
username: MYUSER
password: Password1
dbCreate: validate
url: jdbc:oracle:thin:#someserver:1521:DEV1
dataSource1:
pooled: true
jmxExport: true
logSql: true
driverClassName: oracle.jdbc.OracleDriver
username: MYUSER
password: Password1
dbCreate: validate
url: jdbc:oracle:thin:#someserver:1521:DEV1
dataSource2:
pooled: true
jmxExport: true
logSql: true
driverClassName: oracle.jdbc.OracleDriver
username: MYUSER
password: Password1
dbCreate: validate
url: jdbc:oracle:thin:#someserver:1521:TEST1
dataSource3:
pooled: true
jmxExport: true
logSql: true
driverClassName: oracle.jdbc.OracleDriver
username: MYUSER
password: Password1
dbCreate: validate
url: jdbc:oracle:thin:#someserver:1521:PROD1
and then within the domain class' mapping specifying datasources in the mapping:
package plsutils
class DmjTypes {
String code
String description
Date insertDate
String insertUser
Date modifyDate
String modifyUser
String dbEnv
static mapping = {
datasources(['dataSource1', 'dataSource2', 'dataSource3'])
version false
table name: "CDE_DMJ_TYPES", schema: "MYSCHEMA"
id generator: 'sequence' ,params:[sequence: 'DMJTY_SEQ']
columns {
id column: "DMJTY_ID"
code column: "DMJTY_CDE"
description column: "DMJTY_DESCR"
insertDate column: "INSERT_DTT"
insertUser column: "INSERT_USER"
modifyDate column: "MODIFY_DTT"
modifyUser column: "MODIFY_USER"
dbEnv formula:'( select inst.instance_name || \'-\' || inst.host_name from v$instance inst ) '
}
}
}
and then, within my controller, I should be able to do something like this:
params.max = Math.min(max ?: 10, 100)
dmjTypesListDev = DmjTypes.dataSource1.list(params)
dmjTypesListTest = DmjTypes.dataSource2.list(params)
dmjTypesListProd = DmjTypes.dataSource3.list(params)
I am getting an error upon the first call:
URI /dmjTypes/index
Class groovy.lang.MissingPropertyException
Message null
Caused by No such property: dataSource1 for class: plsutils.DmjTypes
I'm using ojdbc7.jar, connection to Oracle 11g and I'm using Grails 3.0.9.
I can't help but think I'm doing something subtly stupid somewhere. Can anyone please help me with this?
Cheers,
Allen
Basing on official documantation try dataSources keyword:
dataSources:
dataSource:
pooled: true
jmxExport: true
driverClassName: org.h2.Driver
username: sa
password:
lookup:
dialect: org.hibernate.dialect.MySQLInnoDBDialect
driverClassName: com.mysql.jdbc.Driver
username: lookup
password: secret
url: jdbc:mysql://localhost/lookup
dbCreate: update
environments:
development:
dataSources:
dataSource:
dbCreate: create-drop
url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
test:
dataSources:
dataSource:
dbCreate: update
url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
production:
dataSources:
dataSource:
dbCreate: update
url: jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
properties:
jmxEnabled: true
initialSize: 5
…
lookup:
dialect: org.hibernate.dialect.Oracle10gDialect
driverClassName: oracle.jdbc.driver.OracleDriver
username: lookup
password: secret
url: jdbc:oracle:thin:#localhost:1521:lookup
dbCreate: update
Once I corrected the version of grails referred to in the gradle.properties and performed a complete clean and rebuild, I was able to get it working. I believe all my issues were because of a version mismatch of the grails I was using to build it.
So, this is the appropriate datasource entry:
dataSources:
dataSource:
pooled: true
jmxExport: true
driverClassName: oracle.jdbc.OracleDriver
username: MYUSER
password: Password1
dbCreate: validate
url: jdbc:oracle:thin:#somelocalserver:1521:LOCAL
one:
pooled: true
jmxExport: true
driverClassName: oracle.jdbc.OracleDriver
username: MYUSER
password: Password1
dbCreate: validate
url: jdbc:oracle:thin:#somedevserver:1521:DEV1
two:
pooled: true
jmxExport: true
driverClassName: oracle.jdbc.OracleDriver
username: MYUSER
password: Password1
dbCreate: validate
url: jdbc:oracle:thin:#sometestserver:1521:TEST1
three:
pooled: true
jmxExport: true
driverClassName: oracle.jdbc.OracleDriver
username: MYUSER
password: Password1
dbCreate: validate
url: jdbc:oracle:thin:#someproductionserver:1523:PROD1
This is the working domain class:
class DmjTypes {
String code
String description
Date insertDate
String insertUser
Date modifyDate
String modifyUser
String dbEnv
static mapping = {
datasources(['one', 'two', 'three'])
version false
table name: "CDE_DMJ_TYPES", schema: "MYSCHEMA"
id generator: 'sequence' ,params:[sequence: 'DMJTY_SEQ']
columns {
id column: "DMJTY_ID"
code column: "DMJTY_CDE"
description column: "DMJTY_DESCR"
insertDate column: "INSERT_DTT"
insertUser column: "INSERT_USER"
modifyDate column: "MODIFY_DTT"
modifyUser column: "MODIFY_USER"
dbEnv formula:'( select inst.instance_name || \'-\' || inst.host_name from v$instance inst ) '
}
}
}
Try this:
dataSources:
dataSource:
pooled: true
jmxExport: true
logSql: true
driverClassName: oracle.jdbc.driver.OracleDriver
username: MYUSER
password: Password1
dbCreate: validate
autoReconnect: true
#url: jdbc:oracle:thin:#someserver:1521:DEV1(I remember in 3.0.9 this is under environments:development:dataSources:dataSource)
dataSource2:
pooled: true
jmxExport: true
logSql: true
driverClassName: oracle.jdbc.driver.OracleDriver
dialect: org.hibernate.dialect.OracleDialect
username: MYUSER
password: Password1
dbCreate: validate
url: jdbc:oracle:thin:#someserver:1521:TEST1
autoReconnect: true
dataSource3:
pooled: true
jmxExport: true
logSql: true
driverClassName: oracle.jdbc.driver.OracleDriver
dialect: org.hibernate.dialect.OracleDialect
username: MYUSER
password: Password1
dbCreate: validate
url: jdbc:oracle:thin:#someserver:1521:PROD1
autoReconnect: true
In controller:
static mapping = {
datasources(['dataSource', 'dataSource2', 'dataSource3'])
.....
}
Related
I am working on a database migration project and it requires me to use sequelize. I initialized sequelize's CLI (using npx sequelize-cli init) that added the config.json file:
config, contains config file, which tells CLI how to connect with database
The config.json file has this object:
"production": {
"username": "root",
"password": null,
"database": "database_production",
"host": "127.0.0.1",
"dialect": "mysql"
}
But I don't want to save my password in a config.json file. I want to use an environmental variable instead. What can I do?
Rename the config.json to config.js, install dotenv and use the below code
require('dotenv').config();
module.exports = {
development: {
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.DB_HOST,
dialect: process.env.DB_DRIVER
},
test: {
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.DB_HOST,
dialect: process.env.DB_DRIVER
},
production: {
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.DB_HOST,
dialect: process.env.DB_DRIVER
}
};
First you have to create a .sequelizerc file in root. Then add the following code there.
var path = require('path')
module.exports = {
'config': path.resolve('config', 'config.js'),
}
Note: Change the path as per your project.
Then you can rename the config.json file to config.js and add the below code there. (As in Tunde's answer.)
require('dotenv').config();
module.exports = {
development: {
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.DB_HOST,
dialect: process.env.DB_DRIVER
},
test: {
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.DB_HOST,
dialect: process.env.DB_DRIVER
},
production: {
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.DB_HOST,
dialect: process.env.DB_DRIVER
}
};
My goal is to move the contents of UsersArray into generateUserData() so that I can display it in a TableViewController.
[usernameList() and idList() get a response message from a URL request]
final class UsersData {
static func generateUsersData() -> Array<User>
{
return [
User(id: "111", username: "Bill#comcast.net"),
User(id: "222", username: "Oscar Peterson#yahoo.com"),
User(id: "333", username: "DaveBrubeck#gmail.com")
]
}
}
func makeUsers() {
usernameList() {
inputArray in
arrayOfUsernames = inputArray as! [String]
idList() {
inputArray in
arrayOfids = inputArray as! [String]
var counter = arrayOfids.count - 1
print(counter)
while counter > 0 {
usersArray.append(User(id: arrayOfids[counter], username: arrayOfUsernames[counter]))
counter -= 1
}
print("makeUsers() creates this array in idList() closure: \(usersArray)")
}
}
}
This is printed to the console:
makeUsers() creates this array in idList() closure: [Project1.User(id: Optional(""), username: Optional("")), Project1.User(id: Optional("62"), username: Optional("83068151#qq.com")), Project1.User(id: Optional("56"), username: Optional("830681511#qq.com")), Project1.User(id: Optional("55"), username: Optional("in#ultrices.edu")), Project1.User(id: Optional("54"), username: Optional("non.lacinia#pretiumet.com")), Project1.User(id: Optional("53"), username: Optional("pede#utodio.org")), Project1.User(id: Optional("52"), username: Optional("tincidunt#congueInscelerisque.co.uk")), Project1.User(id: Optional("51"), username: Optional("enim#liberoProin.ca")), Project1.User(id: Optional("50"), username: Optional("amet.massa#nectellus.net")), Project1.User(id: Optional("49"), username: Optional("auctor.Mauris#nibhenimgravida.edu")), Project1.User(id: Optional("48"), username: Optional("Curae.Phasellus.ornare#parturientmontes.ca")), Project1.User(id: Optional("47"), username: Optional("pede.blandit#Pellentesquehabitant.net")), Project1.User(id: Optional("46"), username: Optional("Maecenas#natoquepenatibus.ca")), Project1.User(id: Optional("45"), username: Optional("non.lobortis#nunc.edu")), Project1.User(id: Optional("44"), username: Optional("Sed#interdum.net")), Project1.User(id: Optional("43"), username: Optional("vehicula.risus#urnasuscipit.com")), Project1.User(id: Optional("42"), username: Optional("libero#dui.co.uk")), Project1.User(id: Optional("41"), username: Optional("fames#Nullatemporaugue.edu")), Project1.User(id: Optional("40"), username: Optional("eget.ipsum.Suspendisse#facilisis.ca")), Project1.User(id: Optional("39"), username: Optional("felis.Nulla.tempor#adipiscinglacusUt.net")), Project1.User(id: Optional("38"), username: Optional("erat.neque.non#in.co.uk")), Project1.User(id: Optional("37"), username: Optional("tincidunt.dui.augue#sedturpis.ca")), Project1.User(id: Optional("36"), username: Optional("ultrices.iaculis#adipiscingelitAliquam.org")), Project1.User(id: Optional("35"), username: Optional("montes.nascetur#etmagnisdis.edu")), Project1.User(id: Optional("34"), username: Optional("Phasellus.nulla.Integer#nunc.edu")), Project1.User(id: Optional("33"), username: Optional("Donec.tincidunt#Quisque.edu")), Project1.User(id: Optional("32"), username: Optional("In#afelisullamcorper.edu")), Project1.User(id: Optional("31"), username: Optional("neque.Nullam.ut#eleifend.edu")), Project1.User(id: Optional("30"), username: Optional("mus.Aenean#tellussemmollis.org")), Project1.User(id: Optional("29"), username: Optional("Donec.dignissim#Nunc.org")), Project1.User(id: Optional("28"), username: Optional("gravida.molestie#habitant.edu")), Project1.User(id: Optional("27"), username: Optional("egestas#sedtortor.org")), Project1.User(id: Optional("26"), username: Optional("non.enim#semut.com")), Project1.User(id: Optional("25"), username: Optional("nec#tinciduntvehicula.ca")), Project1.User(id: Optional("24"), username: Optional("nec.ante.blandit#consequatdolor.ca")), Project1.User(id: Optional("23"), username: Optional("sit.amet.metus#Pellentesquetincidunttempus.org")), Project1.User(id: Optional("22"), username: Optional("convallis.dolor.Quisque#natoquepenatibuset.edu")), Project1.User(id: Optional("21"), username: Optional("lacus#molestietellus.com")), Project1.User(id: Optional("20"), username: Optional("dui#NullaaliquetProin.edu")), Project1.User(id: Optional("19"), username: Optional("ullamcorper.velit#necmalesuadaut.com")), Project1.User(id: Optional("18"), username: Optional("risus#nibh.ca")), Project1.User(id: Optional("17"), username: Optional("scelerisque.lorem#dolorsit.net")), Project1.User(id: Optional("16"), username: Optional("Nulla.interdum#parturientmontesnascetur.net")), Project1.User(id: Optional("15"), username: Optional("ipsum.non#erat.co.uk")), Project1.User(id: Optional("14"), username: Optional("commodo.tincidunt#molestiesodales.com")), Project1.User(id: Optional("13"), username: Optional("cursus.Integer.mollis#eleifendnon.net")), Project1.User(id: Optional("12"), username: Optional("eleifend.vitae#etmagnisdis.co.uk")), Project1.User(id: Optional("11"), username: Optional("et.lacinia.vitae#inconsequatenim.net")), Project1.User(id: Optional("10"), username: Optional("dictum.magna#auctorullamcorpernisl.com")), Project1.User(id: Optional("9"), username: Optional("tempus.mauris.erat#ametfaucibus.net")), Project1.User(id: Optional("8"), username: Optional("iaculis.odio.Nam#ligulatortor.org")), Project1.User(id: Optional("7"), username: Optional("enim.condimentum#elementum.org")), Project1.User(id: Optional("6"), username: Optional("parturient#Aeneanmassa.com")), Project1.User(id: Optional("5"), username: Optional("")), Project1.User(id: Optional("4"), username: Optional("testguy#aol.com"))]
Is it possible to use connection class as provide like here?
import { Connection, createConnection } from 'typeorm';
export const databaseProviders = [{
provide: Connection,
useFactory: async () => await createConnection({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'postgres',
database: 'testo',
entities: [
__dirname + '/../**/*.entity{.ts,.js}',
],
logging: true,
synchronize: true,
}),
}];
To make imports work like:
constructor(
private connection: Connection,
) {
this.repository = connection.getRepository(Project);
}
In that case nestjs can't find dependency. I guess the problem is in typeorm, it is compiled to plain es5 function. But maybe there a solution for this?
repository to reproduce
UPDATE:
I found acceptable solution nestjs typeorm module, but don't understand why my Connection class is not worked, but it works well with strings. Hope #kamil-myśliwiec will help to understand.
modules: [
TypeOrmModule.forRoot(
[
Build,
Project,
],
{
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'postgres',
database: 'testo',
entities: [
Build,
],
logging: true,
synchronize: true,
}),
],
// And the n inject like this by entity name
#InjectRepository(Build) private repository: Repository<Build>,
I am using Grails 3.0.9
application.yml:
hibernate:
cache:
queries: false
use_second_level_cache: true
use_query_cache: false
region.factory_class: 'org.hibernate.cache.ehcache.EhCacheRegionFactory'
endpoints:
jmx:
unique-names: true
dataSource:
pooled: true
jmxExport: true
driverClassName: com.mysql.jdbc.Driver
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
username: root
password: 123
environments:
development:
dataSource:
dbCreate: update
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/blereview?useUnicode=true&characterEncoding=UTF-8
on grails run-app no errors on console but no table is created in the database.
Domain class I am using
DataRequest {
String token;
static constraints = { }
}
On windows,one of my friend is also facing same issue.He fixed it by setting GRAILS-HOME using cygwin(grails run-app from cygwin) and it works for him.
Hope it helps you.
I use symfony 1.4.11 with Doctrine
I have sfGuardUser module in backend. I have sfGuardUserProfile table.
sfGuardUserProfile:
connection: doctrine
tableName: sf_guard_user_profile
columns:
id: { type: integer(4), primary: true, autoincrement: true }
user_id: { type: integer(4), notnull: true }
salutation: { type: string(10), notnull: true }
first_name: { type: string(30), notnull: true }
last_name: { type: string(30), notnull: true }
country: { type: string(255), notnull: true }
postcode: { type: string(10) , notnull: true }
city: { type: string(255), notnull: true }
address: { type: string() , notnull: true }
phone: { type: string(50) }
email: { type: string(255), notnull: true }
validate: { type: string(17) }
banned: { type: boolean, default: 0 }
payed_until: { type: datetime, notnull: true}
relations:
User:
class: sfGuardUser
foreign: id
local: user_id
type: one
onDelete: cascade
onUpdate: cascade
foreignType: one
foreignAlias: Profile
indexes:
user_id_unique:
fields: [user_id]
type: unique
SfGuardUser table:
GuardUser:
actAs: [Timestampable]
columns:
id:
type: integer(4)
primary: true
autoincrement: true
username:
type: string(128)
notnull: true
unique: true
algorithm:
type: string(128)
default: sha1
notnull: true
salt: string(128)
password: string(128)
is_active:
type: boolean
default: 1
is_super_admin:
type: boolean
default: false
last_login:
type: timestamp
indexes:
is_active_idx:
fields: [is_active]
relations:
groups:
class: sfGuardGroup
local: user_id
foreign: group_id
refClass: sfGuardUserGroup
foreignAlias: Users
permissions:
class: sfGuardPermission
local: user_id
foreign: permission_id
refClass: sfGuardUserPermission
foreignAlias: Users
I have next sfGuardUserForm:
public function configure()
{
parent::configure();
$profileForm = new sfGuardUserProfileForm($this->object->Profile);
unset($profileForm['user_id'],$profileForm['banned'],$profileForm['validate'],$profileForm['payed_until']);
$profileForm->widgetSchema['salutation'] = new weWidgetSalutationI18n();
$profileForm->widgetSchema['country'] = new sfWidgetFormI18nChoiceCountry();
$profileForm->setDefault('country', 'DE');
$this->embedForm('Profile', $profileForm);
}
So, when I add new user from backend, in my sfGuardUserProfile table user_id = 0 ...
Try if this works for you:
public function configure()
{
parent::configure();
$profile = new sfGuardUserProfile();
$profile->setUserId($this->getObject()->id);
$profileForm = new sfGuardUserProfileForm($profile);
$this->embedForm('Profile', $profileForm);
}
I'm not really sure, but form the top of my head it's because you unset the user_id value.
Somethings that first came to mind are:
Read this (to define a primary key, the keyword is primaryKey: true not primary: true and they dont need to be defined as autoincremental, ORM can guess it for himself)
Dont unset the user_id or any ids of forms , they are hidden by default so that should not be a problem.
Check those poitns and see if he problem persist, if so i cuold be something not properly updated when changing the schema (remember always clearing cache and building all classes every time you modify your schema)
Hope this helps!