I have a php class that requires a PDO instance to be passed to it's constructor. The code would be something like this:
$pdo = new PDO($host, $username, $password);
$myclass = new myClass($pdo);
The problem I've got is integrating this with CI. CI auto loads it's database class which handles all DB connections and is accessed with
$this->db->
It would be very simple if I was able to instantiate myClass with the CI database object, but it seems to contain a lot more stuff than just the PDO instance. I've tried
$myClass = new myClass($this->db);
and it doesn't like it at all. I realise I could rewrite myClass to access the CI db object directly (i.e. without having to have a new connection passed to it), but I don't really want to start that mammoth undertaking!
So, is there a way to use the CI db class for this purpose? Would it make any difference if I just created a new PDO instance as above if the CI database library is already loaded?
There isn't an easy way to get the current PDO connection from CI's database class. However, you don't necessarily need that. You can create your own PDO connection and pass that in to your custom class. You'll have two live connections to the DB, which isn't ideal, but you could probably work that out.
Related
We are using Play 2.1.1 and its built-in JPA integration (JPA.em()
etc).
How can we dynamically change the db.pass property? Play.application().configuration() seems
to be immutable as of Play 2.1. (or we're at least not aware of the mutators)
If we are able to change db.pass, how can we reload the DB configuration so that JPA.em() returns an EntityManager using the new password?
What we are trying to avoid is having to recreate the EntityManager using
EntityManagerFactory. We want to continue to let Play manage that in
the JPA helper class.
Background
The system has a default DB configuration for running locally. When deployed to a server, the DB password is dynamically set on the running application using the following script:
#!/bin/bash
stty -echo
read -p "Password: " PASS
stty echo
curl -k https://127.0.0.1:8443/someUrl/pwd --data "password=$PASS"
The application receives this data and then recreates the Hibernate
SessionFactory. Our new Play app will be required to do something
similar.
The key is to use the ConfigFactory to create a new Config entry. This new Config contains an entry for password with the value coming from your http call to your password service.
A new Configuration is created using the new Config, which in turn falls back to the original Config from the original Configuration.
Basically the new password entry supersedes the original.
It sound long winded when you say it, but the code is pretty readable.
public class Global extends GlobalSettings {
// inject http client to make call for password
#Override
public Configuration onLoadConfig(Configuration configuration, File file, ClassLoader classLoader) {
final Config config = ConfigFactory.parseString(String.format("db.default.user=%s", callPasswordService()));
return new Configuration(config.withFallback(configuration.getWrappedConfiguration().underlying()));
}
}
To answer my own question, at first we solved the problem of updating the immutable configuration at runtime by overriding Configuration.onLoadConfig with the following:
If configuration indicates that production.level is PROD
Read the password from stdin
Create a new configuration by converting the old one to a map and building a new one with ConfigFactory.parseMap, with the new parameter as well
Return super.onLoadConfig
However, this still didn't address that the problem of reloading the DB configuration. In the end, my colleague created a Play! plugin which essentially a copy of some JPA classes with the added capability of being reloaded with a Map of configuration properties.
Update
The "hook" is the additional static method which the plugin adds to the JPA class (e.g. reloadWithProperties). This method creates a new data source which is then rebound in JNDI.
I want to make database queries in my Jersey REST webapp. The ideal situation would be to find a way where the database connection is initialised once at the first app run. Afterwards I only get the instance of DAOFactory object in my REST class and make the queries in the methods. I am using mysql connector. Is there a way to find a way to do it in Jersey? In JSF it was possible - I just used an application-scoped bean when I run the code. Moreover it would be good if I could access the ServletContext object inside this method cause I would like to use it's getResourceAsStream() method to read the database connection parameters from WEB-INF/dao.properties file. But the 'only once per app initialisation' is the crucial part here.
I have a library that I have created that depends on EF Codefirst for DB interaction. I am also using EntityMigrations Alpha 3. When I use the library in my main application (WPF) everything works fine and as expected. Another part of the system uses Excel and retrieves information using the same library via an additional COM class in between.
In the Excel scenario, as soon as it tries to connect to the database, it throws up an exception to do with "The Provider did not return a ProviderManifestToken".
I'm really not sure why I'm only getting the error when I go through Excel/COM. In both scenarios I can confirm that the same DB connection string is being used. THe method to retrieve the DB Connection string is also the same - they use a shared config file & loader class.
Any suggestions welcome.
Issue resolved.
I had also created a custom DBIntializer and part of the intialization calls upon EntityMigrations to ensure the DB is up to date. The custom migration calls the default constructor on your context. By convention this will either dynamically use it's own connection string for SQLExpress(I don't have installed) or try to look for an entry in your config file (I don't have this either for the dll - config comes from hosting apps).
This is what is causing the failure when being used from Excel(In my scenario). The Migration will be newing up an instance of the context using the default constructor. This means that a config entry for the connection string is required or it uses the default process(SQLExpress). When being used from Excel in a COM env – no config file exists.
Moving the migration out of the Initialization strategy means I no longer have a problem.
I have my Database, that have my ADO.NET Entity Data Model that have my Repository in one Application Library project
then, in the website for each Controller I start with
MyRepository db = new MyRepository();
I am expecting that this website will be accessed 50.000 a day and I was wondering... does the new MyRepository() part start a new connection to the Database?
is this safer?
public class MyController : Controller
{
public MyRepository db { get; set; }
protected override void Initialize(RequestContext requestContext)
{
if (db == null) { db = new MyRepository(); }
base.Initialize(requestContext);
}
...
How can I learn a little bit more about how does the Entity Model hooks up into the database to prevent multiple "bad" things to happen?
I have several objects that I would like to Cache it, as they are pretty complex and never change (unless someone on the ADMIN area changes it), what are my best options?
Thank you.
ADO.NET uses a connection pool which avoids creating connections to the database everytime. A pool of connections is created per application domain and per connection string and connections from this pool are reused. So when you instantiate your repository no connection is created to the database. For caching objects you might take a look at the standard techniques.
As far as your example is concerned if MyRepository is disposable it is recommended to call the Dispose method on it which could be done in the Dispose method of the controller.
Is it possible to add a new database connection to Django on the fly?
I have an application that uses multiple databases (django 1.2.1), and while running, it's allowed to create new databases. I'd need to use this new database right away (django.db.connections[db_alias]). Is it possible without server restart? Using module reload here and there?
Thank you for your time.
It is possible... but not recommended...
You can access the current connection handler...
Use something like this:
from django.db import connections
if not alias in connections.databases:
connections.databases[alias] = connections.databases['default'] # Copy 'default'
connections.databases[alias]['NAME'] = alias
Make sure you do not attempt to add a new alias to the databases dictionary while there is ANY database activity on the current thread.
An issue you need to overcome, is that this code will need to be placed somewhere were it will always be touched by the current thread before trying to access the database. I use middleware to achieve this.