New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multitenancy Error: ER_NO_DB_ERROR: No database selected #159
Comments
@philippefutureboy Hey Philippe! Thanks for posting this! Could you please try to set |
@paveltiunov Heya! Thanks for the quick answer :) To answer your question, both are already specified as the default environment in the docker-compose.development.yml file. |
Also, important information to add - the Cube.js instance run in production even in the docker-compose.development.yml configuration. This is to ensure that authMiddleware and other auth related functions are run. Quick question: Exactly which configuration points are skipped for development build? The message in dev doesn't say much |
@philippefutureboy Have you resolved this one? Do you think your mysql instance contains |
@paveltiunov Unfortunately I wasn't able to make much progress on my side.
beforeAll(async () => {
const result = await db.createDatabase();
databaseName = result.databaseName;
cubejsApi = cube({ databaseName });
return db.query(insertTemplate({ databaseName }));
}); Where the
function cube(payload = {}) {
return cubejs(
jwt.sign(payload, process.env.CUBEJS_API_SECRET, { expiresIn: '30d' }),
{ apiUrl: 'http://localhost:4000/cubejs-api/v1' }
);
} So the JWT contains the
const MySQLDriver = require("@cubejs-backend/mysql-driver");
module.exports = {
contextToAppId: ({ authInfo }) =>
`${process.env.CUBEJS_APP}_${authInfo.databaseName}`,
driverFactory: ({ authInfo }) =>
new MySQLDriver({
database: authInfo.databaseName
})
}; So my understanding is:
Where am I falling short of reality? |
@philippefutureboy Seems like DB isn't created before test is run or it's a permission problem. |
I tried to address the points you brought up, but no avail:
I changed the createDatabase function to include a
async function createDatabase({ namespace, databaseName } = {}) {
try {
namespace = namespace || uuidv4();
databaseName =
databaseName ||
uuidv5(
path.basename(__filename),
namespace
).replace(/-/g, '');
await query(`
CREATE DATABASE IF NOT EXISTS \`${databaseName}\`;
GRANT ALL PRIVILEGES ON \`${databaseName}\`.* TO '${process.env.CUBEJS_DB_USER}'@'localhost';
FLUSH PRIVILEGES;
USE \`${databaseName}\`;
`);
return { databaseName, namespace };
} catch (err) {
throw new Error(`Failed to create database: ${err.message}`);
}
} No change.
I created a new util function for the database fixture that checks if the database exists:
async function checkIfDatabaseExists(databaseName) {
const exists = await query(`
SELECT SCHEMA_NAME
FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = '${databaseName}';
`)
console.log(exists);
return exists !== '';
} And I call the function right before doing the
test('should return the correct totalAmounts', async () => {
await db.checkIfDatabaseExists(databaseName);
const { loadResponse: { data } } = await cubejsApi.load({ /* ... */ });
/* ... */
}); Which prints
and returns true. So the database has been created before the For this part, did you mean that the database has to be created before the cubejs instance is booted up, or before the test in the test suite is run? Cheers 🚀 |
Welp I found it. 🤦♂️
const CubejsServer = require('@cubejs-backend/server');
const cubejsOptions = require('./cubejsOptions');
console.log(cubejsOptions);
const server = cubejsOptions
- ? new CubejsServer()
- : new CubejsServer(cubejsOptions);
+ ? new CubejsServer(cubejsOptions)
+ : new CubejsServer();
server.listen().then(({ port }) => {
console.log(`🚀 Cube.js server is listening on ${port}`);
}); Found it because I tried logging some stuff from the driverFactory, and it would not print. Thanks for your help, it allowed to narrow the potential domain of issues 🚀 |
The good news is that now I have a proof of concept of how I can build the |
Versions
Node.js: ^12
npm (local): 6.9.0
npm (docker): 6.10.0
@cubejs-backend/mysql-driver: ^0.9.14
@cubejs-backend/server: ^0.9.24
@cubejs-client/core: ^0.9.12
Describe the bug
Error:
Error: ER_NO_DB_ERROR: No database selected
Trace: https://gist.github.com/philippefutureboy/9d012684f9f8008903dcfd2059e5687d
Error when attempting to use multitenancy in my test setup. I couldn't find the source of the error. Cube.js seems to forget to use the database passed to the MySQLDriver instance created in
driverFactory
(see step 4, you might find right away the error).Important details to assess the situation:
__e2e__/schemas/Orders.test.js
. It is created before doing the request, and before signing the jwt token for the client-core instance.To Reproduce
Where
CUBEJS_API_SECRET
can be generated with the following function:cubejsOptions.js
with:Expected behavior
Cube.js connects to the database specified by the JWT and executes the query.
Final Notes
Let me know if you need any extra information to reproduce the issue :)
The text was updated successfully, but these errors were encountered: