In my application there are a few places where I want to use pure SQL. When I hard code the connection details in Sql.newInstance it works fine. For obvious reasons I would prefer to not hard code the connection details.
When I use the dataSource variable it comes up as null. My code in the controller is:
import groovy.sql.Sql
def dataSource
def sql = Sql.newInstance(dataSource)
sql.executeInsert("insert into....")
My code in the datasource config file is:
environments {
development {
dataSource {
dbCreate = "create-drop"
url = "jdbc:postgresql:mydev"
username = "xxx"
password = "xxx"
As you can see I'm using PostgreSQL. I've also tried it using the default grails database with the same results.
Any ideas would be appreciated.
You need to define dataSource outside of your controller action. Otherwise spring cannot do the required dependency injection for you:
class YouController {
def dataSource
def yourAction() {
def sql = new Sql(dataSource)
[..]
}
}
Related
I'm using jetbrains' exposed library to create and populate a database.
The database does not exist, and I am creating it. However I could not find a simple way to connect to the SQL engine, create a database and connect to that database without multiple connections.
That sounds a little clunky. Is there a better way to do it maybe?
Here is a small example :
var db = Database.connect("jdbc:mysql://localhost:3308", driver = "com.mysql.jdbc.Driver", user = "root", password = "aRootPassword")
transaction(db) { SchemaUtils.createDatabase("imdb") }
// avoid reconnect?
db = Database.connect("jdbc:mysql://localhost:3308/imdb", driver = "com.mysql.jdbc.Driver", user = "root", password = "aRootPassword")
transaction(db) { SchemaUtils.create (TitleRatings) }
You need a connection pool, e.g. HikariCP. It pools database connections and reuses them. This gives you a huge performance boost compared to individually opened connections.
I usually wrap it in a simple class like this:
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import javax.sql.DataSource
public object DB {
var db: DataSource = connect();
public fun connect(): DataSource {
val config = HikariConfig()
config.jdbcUrl = "jdbc:mysql://localhost:3308"
config.username = "com.mysql.jdbc.Driver"
config.password = "aRootPassword"
config.driverClassName = "com.mysql.jdbc.Driver"
return HikariDataSource(config)
}
}
My transactions then look like this one:
transaction(Database.connect(DB.db)) {
SchemaUtils.createDatabase("imdb")
}
I just got into testing my flask application with pytest, and it mostly works as expected. Unfortunately the test uses the live DB instead a mock one. I'm quite sure this has to do with the fact, that flask-security is using peewee's database_wrapper instead of an "straightforward" database.
Here's some code. This is from the test:
#pytest.fixture
def client():
db_fd, belavoco_server.app.config['DATABASE'] = { 'name': 'userLogin_TEST.db',
'engine': 'peewee.SqliteDatabase' } }
belavoco_server.app.config['TESTING'] = True
client = belavoco_server.app.test_client()
#this seems not to help at all
with belavoco_server.app.app_context():
belavoco_server.users.user_managment.db_wrapper.init_app(belavoco_server.app)
yield client
os.close(db_fd)
os.unlink(belavoco_server.app.config['DATABASE'])
This is some code from my bv_user_model.py
app.config['DATABASE'] = {
'name': 'userLogin.db',
'engine': 'peewee.SqliteDatabase',
}
app.config['SECURITY_URL_PREFIX'] = "/users"
# Create a database instance that will manage the connection and
# execute queries
db_wrapper = FlaskDB(app)
class Role(db_wrapper.Model, RoleMixin):
name = CharField(unique=True, default="standard")
description = TextField(null=True)
def __repr__(self):
return self.name
When preforming the test, Flask is using the userLogin.db instead of userLogin_TEST.db. I suppose this is because of the db_wrapper in bv_user_model.py - but I did not find a way to change this behaviour. Any help would be greatly appreciated!
The root of the issue seems to be this in bv_user_model:
app.config['DATABASE'] = {
'name': 'userLogin.db',
'engine': 'peewee.SqliteDatabase',
}
Since you are using FlaskDB with the app that has the production credentials, it seems like the db_wrapper will "remember" that and not be overridden by your tests.
The most straightforward answer would be to not use your app to create the FlaskDB instance directly
db = FlaskDB()
And then later on initialize it on your app
from models import db
def create_app():
app = ...
app.config["DATABASE"] = ...
db.init_app(app)
...
return app
Which would let you have a separate function like this which you can use for testing.
def create_test_app():
app = ...
app.config["DATABASE"] = ...test credentials...
db.init_app(app)
...
return app
and when you create your models, use the FlaskDB instance just the same as you were already.
db = FlaskDB()
class Role(db.Model, RoleMixin):
...
How to set attributes (PDO::ATTR_ERRMODE) on the PDO database handle in Codeigniter?
I think a better option is to use a MY_Model (which you then extend and this is available then across the application) and define something like this in the construct:
$this->db->conn_id->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
Note conn_id allows you to access the main PDO object.
There are two ways:
1. The lazy (hacky) way
Add to the following code into system/core/database/drivers/pdo/pdo_driver.php (in CI 3):
public function db_connect($persistent = FALSE)
{
$this->options[PDO::ATTR_PERSISTENT] = $persistent;
// Added code start
$this->options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
// Added code end
try
{
return new PDO($this->dsn, $this->username, $this->password, $this->options);
...
}
2. The right way
Extend Database Driver and add the same line
Note: If you will set PDO::ERRMODE_EXCEPTION in Codeigniter it will show exception errors even in Production environment.
I am running into an issue when trying the following in my Serivce:
class SendingMailService {
def dataSource // the Spring-Bean "dataSource" is auto-injected
def sendXLSMail() {
def db = new Sql(dataSource)
//additional code such as query, execution follows
}
}
When I execute this code I get the error: "Must specify a non-null Connection". From what I have read I believe the code above should work (this is not a Unit Test)...so clearly I am missing something with respect to Grails Services?
Thank you for any help here,
Ok months later I had some time to look into this one.
I tried a couple of things to get the dataSource to autoinject into a service but I kept getting a null connection. Ultimately I landed on passing the datasource from the controller which is not very elegant but at least it works. I hope this helps someone else out as I have seen some similar issues out there. Still would like to know why the autoinject does not work but I think I would have to dig deeper into Grails to understand that.
class MyController {
def dataSource
def someControllerMethod() {
MyService myService = new MyService()
myService.serviceMethodQuery(dataSource)
}
}
//////////////////////
class MyService {
def serviceMethodQuery(Object dataSource){
//use your datasource as you normally would
}
}
i want to use zend_db standalone cos zend framework is too much for my project but i'm new with it,
is it correct to do this:
$pdoParams = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES
UTF8;');
$params = array(
'host' => 'localhost',
'username' => 'ss_fraat',
'password' => 'jos10',
'dbname' => '_a2hDB',
'driver_options' => $pdoParams
);
try {
$db = Zend_Db::factory('PDO_MYSQL', $params);
//set default adapter
Zend_Db_Table_Abstract::setDefaultAdapter($db);
} catch (Exception $e) {
exit($e->getMessage());
}
//save Db in registry for later use
Zend_Registry::set('dbAdapter', $db);
then in any class do this:
$db = Zend_Registry::get('db');
/** quote to avoid sql injection */
$date = $db->quote('1980-01-01');
$sql = 'SELECT * FROM product WHERE name = ' . $date;
$result = $db->query($sql);
$db->query(); //run a query
i really need to do this
Zend_Db_Table_Abstract::setDefaultAdapter($db);
i get this code from a website,
is it necessary to use Zend_Db_Table_Abstract if i'm not using the full zend framework,
or it is better for example to use this:
$db = Zend_Db::factory( ...options... );
$select = new Zend_Db_Select($db);
what i want is to setup a pdo/mysql connexion in my bootstrap php page and be able to get that db instance in any class without starting a new connexion to execute queries but i'm not sure how to do that use Zend_Db_Table_Abstract or Zend_Db_Select use the registry Zend_Registry::set('dbAdapter', $db) or not
thanks a lot
The purpose of Zend_Db_Table_Abstract is so you can create your own model classes based around the Table Data Gateway design pattern. The idea of that pattern is that you have a class that encapsulates all the sql you would need for interfacing with a table. So the assumption is that you will be creating model classes that extend Zend_Db_Table_Abstract for each table. If you are going to do that, then you will want to call Zend_Db_Table_Abstract::setDefaultAdapter($db) in your setup/bootstrap. Recent versions of ZF provide as an alternative a quick way of getting basic functionality without having to create a custom class definition by just instantiating Zend_Db_Table:
$userTable = new Zend_Db_Table('users');
In summary, none of this particularly has to do with the MVC part of the framework, although some people choose to use Zend_db as the basis for db connections and models, instead of using a more fully featured ORM like Doctrine or Propel.
The other code you provided simply illustrates that you do not need to use Zend_Db_Table_Abstract either -- you can simply setup an instance of a Zend_Db_Adapter and use that instance to call query() or its other methods.