We are trying to build an web application that allows users to select appropriate columns for given database table.
I wonder if there is any API for these - I've googled it a while in vain. Otherwise, if you can give some clues (patterns or sample codes) how to build such a component, that will be great and appreciated.
You could base your application on INFORMATION_SCHEMA views/table. This is documentation for SQL Server, but you can easily find it for other databases too:
http://msdn.microsoft.com/en-us/library/ms186778.aspx
Sample SQLs:
select * from INFORMATION_SCHEMA.TABLES
select * from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'users'
if you want to use this solution with many databases, to separate your application from db engine, you can create about defining IMetadataProvider interface and create implementations for different databases:
interface IMetadataProvider {
...GetTables();
...GetTableColumns();
...GetTableRelations();
//Other functions required by your project
}
You can also create your own query builder interface:
interface IQueryBuilder {
...From(string tableName);
...Top(int numberOfRows); //TOP for SQL SERVER, LIMIT for MySQL
}
Related
I have an Ionic App using SQLite. I don't have any problems with implementation.
The issue is that I need to import an SQL file using SQLitePorter to populate the database with configuration info.
But also, on the same database I have user info, so my question is:
Everytime I start the app, it will import the sql file, fill the database and probably overwrite my user data too? Since it is all on the same base?
I assume that you can always init your table using string queries inside your code. The problem is not that you are importing a .sql file. Right?
According to https://www.sqlitetutorial.net/sqlite-create-table/ it is obvious that you always create a table with [IF NOT EXISTS] switch. Writing a query like :
CREATE TABLE [IF NOT EXISTS] [schema_name].table_name (
column_1 data_type PRIMARY KEY);
you let sqlite to decide if it's going to create a table with the risk to overwrite an existing table. It is supposed that you can trust that sqlite is smart enough, not to overwrite any information especially if you use 'BEGIN TRANSACTION' - 'COMMIT' procedure.
I give my answer assuming that you have imported data and user data in distinct tables, so you can manipulate what you populate and what you don't. Is that right?
What I usually do, is to have a sql file like this:
DROP TABLE configutation_a;
DROP TABLE configutation_b;
CREATE TABLE configutation_a;
INSERT INTO configutation_a (...);
CREATE TABLE configutation_b;
INSERT INTO configutation_b (...);
CREATE TABLE IF NOT EXIST user_data (...);
This means that every time the app starts, I am updating with the configuration data I have at that time (that's is why we use http.get to get any configuration file from a remote repo in the future) and create user data only if user_data table is not there (hopefully initial start).
Conclusion: It's always a good practice, in my opinion, to trust a database product 100% and abstractly let it do any transaction that might give you some risk if you implemented your self in your code; since it gives a tool for that.For example, the keyword [if not exists], is always safer than implementing a table checker your self.
I hope that helps.
PS: In case you refer in create database procedure, SQLite, connects to a database file and it doesn't exist, it creates it. For someone comfortable in sqlite command line, when you type
sqlite3 /home/user/db/configuration.db will connect you with this db and if the file is not there, it will create it.
In my test project I register a connection using ":memory" connection string and SqliteDialect.Provider as provider. When trying to run tests that execute arbitrary sql (I have a complex join statement so I cannot use a typed query) I get an error that the table do not exist. In my query I print "SELECT * FROM xxx.Table1" but when looking at the code generated from a typed query I can see that it is "SELECT * FROM xxx_Table1". I need to use schemas for the production code, so is there a way to force ORMLite for Sqlite to generate schemas and not just name prefixes when using the attribute [Schema("xxx")] on my domain models?
SQLite doesn't have schemas so they're simulated by prefixing the schema name before the table name. However this should be a transparent implementation detail for SQLite :memory: DBs as the same table name will be used when creating or querying the table.
If you're creating Custom SQL you should use the tableName returned from:
var modelDef = typeof(Table1).GetModelMetadata();
var tableName = db.GetDialectProvider().GetTableName(modelDef);
var sql = $"SELECT * FROM {tableName}";
My application creates tables like this:
public DataAccess()
{
dbcon = DependencyService.Get<ISQLite>().GetConnection();
// create the tables
dbcon.CreateTable<Category>();
dbcon.CreateTable<Settings>();
What I would like to do is to have two databases. One that holds all the user data and one that is refreshed when the application is updated.
As part of the update process I would like to add data from the new database to the existing user database.
Is it possible to open two connections to different databases and also how can I get data from one database and add it to the other? Could I for example do a SQL Select that sp[ans two databases?
The DependencyService is a simple IOC Container. It only supports getting either a new or a global instance for one interface.
One options here are to have different interfaces for your UpdateDatabase and your UserDatabase, so you could retrieve them (it could be an inherited inferface, or your db-class just implements them both):
var db1 = DependencyService.Get<ISQLite>().GetConnection();
var db2 = DependencyService.Get<ISQLiteUpdateDb>().GetConnection();
To copy over, you still have retrieve all data an then just insert into the second one:
var data = db1.Table<YourModel>().ToList();
db2.InsertAll(data);
(Assuming, you are using sqlite-net-pcl.)
I'm using SQLite.Swift and I'd like to know how to do to verify that the db still has the same schema when the application starts because on updtate, it's possible that the new application add columns in the table in which case I'm unable to use the existing db on the device.
I'll have to migrate/recreate the table.
How to do that please?
For tracking the database version, you can use the built in user-version variable that sqlite provides (sqlite does nothing with this variable, you are free to use it however you please). It starts at 0, and you can get/set this variable with the following sqlite statements:
> PRAGMA user_version;
> PRAGMA user_version = 1;
See this answer which discuss your requirement including making schema changes after update
I have a Message table and a User table. Both are in separate databases. There is a userID in the Message table that is used to join to the User table to find things like userName.
How can I create this in LINQ to SQL? I can't seem to do a cross database join.
Should I create a View in the database and use that instead? Will that work? What will happen to CRUD against it? E.g. if I delete a message - surely it won't delete the user? I'd imagine it would throw an error.
What to do? I can't move the tables into the same database!
A view will work, if you have granted access to both database to the configured user. You'll need to use the 2-dot notation. This will only work BTW if both databases are on the same server.
create view vwUserMessages as
select * from db1.dbo.Users as users
inner join db2.dbo.Messages as msg on msg.UserID = users.id
For CRUD: a view is (usualy) only for reading: do updates etc directly to the related tables, or use a stored procedure:
create proc pdeleteUserMessages (#UserID int) as
begin trans
delete db2.dbo.Messages where userid = #UserID
delete db1.dbo.Users where id = #UserID
commit trans
go