What is the recommended way to create table with PetaPoco (and NPoco)? - create-table

Say I need a table that looks like this:
CREATE TABLE Record (
Id INT IDENTITY(1, 1) PRIMARY KEY CLUSTERED,
Guid UNIQUEIDENTIFIER UNIQUE NONCLUSTERED,
Version ROWVERSION,
DateOfBirth DATETIME2,
Name VARCHAR(64) NOT NULL
)
What's the recommended way of creating the table above using PetaPoco and NPoco?

PetaPoco is all about using SQL for what SQL does best. Therefore, the correct way to create a table with PetaPoco is to create it with SQL. We've had a few requests to add schema generation from POCOs, but every supported DB has their own take on DDL, and thus to add it (properly) would be a big undertaking.
It may be added some day, but right now development time is better spent on other features.
That said, PetaPoco is open source, so a PR, if done properly, for schema generation would be happily accepted ;)
Finally, although I don't follow NPoco all the closely, I don't think it has support for schema generation from POCOs, and at a guess, it would be due to the same reason listed above.

I use a migration tool (DbUp) to keep up with the changes in the schema.

Related

MySQL 8: Create Collections via DDL

I’d like to be able to create MySQL Document Store Collections via simple SQL DDL statements rather than using the X-Protocol clients.
Is there any way to do so?
Edit: I’ll try and clarify the question.
Collections are tables using JSON datatypes and functions. That much is clear.
I would like know how I can create a Collection without using the X-Protocol calls and make sure that the aforementioned collection is picked up as an actual Collection.
Judging from MySQL workbench, collection tables have a _id blob PK with an expression, a doc JSON column and a few other elements I do not recall at the moment (might be indexes, etc).
I have no means to tell via the Workbench whatever additional schema/metadata information is required for a table to be considered a Document Store Collection, or if the mere presence of an _id and doc columns are enough.
I hope this clears things up.
All "x-api" instructions are directly mapped to sql syntax. When you e.g. run db.createCollection('my_collection'), MySQL will literally just execute
CREATE TABLE `my_collection` (
`doc` json DEFAULT NULL,
`_id` varbinary(32) GENERATED ALWAYS AS
(json_unquote(json_extract(`doc`,_utf8mb4'$._id'))) STORED NOT NULL,
`_json_schema` json GENERATED ALWAYS AS (_utf8mb4'{"type":"object"}') VIRTUAL,
PRIMARY KEY (`_id`),
CONSTRAINT `$val_strict` CHECK (json_schema_valid(`_json_schema`,`doc`))
NOT ENFORCED
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
You can run the corresponding sql statements yourself if you follow that format.
The doc and _id (with their type and the given expression) are required, the _json_schema is optional, the check too (and only added since MySQL 8.0.17). Since MySQL 8, no additional columns are allowed, except generated columns that use JSON_EXTRACT on doc and which are supposed to be used in an index, see below (although they don't actually have to be used in an index).
Any table that looks like that - doc and _id with their correct type/expression and no other columns except an optional _json_schema and generated JSON_EXTRACT(doc,-columns - will be found with getCollections().
To add an index, the corresponding syntax for
my_collection.createIndex("age", {fields: [{field: "$.age", type: "int"}]})
would be
ALTER TABLE `test`.`my_collection` ADD COLUMN `$ix_i_somename` int
GENERATED ALWAYS AS (JSON_EXTRACT(doc, '$.age')) VIRTUAL,
ADD INDEX `age` (`$ix_i_somename`)
Obviously,
db.dropCollection('my_collection')
simply translates to
DROP TABLE `my_collection`
Similarly, all CRUD operations on documents have a corresponding sql DML syntax (that will actually be executed when you use them via x-api).

Differences regarding neo4j and mySQL

I have to develop a project for college regarding databases. I have to basically develop the same project in a relational database like mySQL and in a non-relational database like neo4j. I'm pretty versed in mySQL but there is something in node4j that i don't understand.
While in mySQL i can just write this:
CREATE_TABLE 'A' (
'idA' INT not NULL
)
and this will create a table that has a column named idA and i may add rows to the table for specific values.
From what i've understood so far, in neo4j i can't really create something ambiguous like this? Every node or label that i create, has to have specific values for the properties i assigned to it. Is this correct? or am I missing something?
Thank you in advance.
The analogue to your empty table example is literally a label (e.g. A) for which there are no nodes.
If you wanted to ensure that the attribute idA existed on every A table node that is created in your database you could create a constraint on the label A something like this.
CREATE CONSTRAINT ON (a:A) ASSERT exists(a.idA)

Adding a time dimension to MySQL cells

Is there a way to keep a timestamped record of every change to every column of every row in a MySQL table? This way I would never lose any data and keep a history of the transitions. Row deletion could be just setting a "deleted" column to true, but would be recoverable.
I was looking at HyperTable, an open source implementation of Google's BigTable, and this feature really wet my mouth. It would be great if could have it in MySQL, because my apps don't handle the huge amount of data that would justify deploying HyperTable. More details about how this works can be seen here.
Is there any configuration, plugin, fork or whatever that would add just this one functionality to MySQL?
I've implemented this in the past in a php model similar to what chaos described.
If you're using mysql 5, you could also accomplish this with a stored procedure that hooks into the on update and on delete events of your table.
http://dev.mysql.com/doc/refman/5.0/en/stored-routines.html
I do this in a custom framework. Each table definition also generates a Log table related many-to-one with the main table, and when the framework does any update to a row in the main table, it inserts the current state of the row into the Log table. So I have a full audit trail on the state of the table. (I have time records because all my tables have LoggedAt columns.)
No plugin, I'm afraid, more a method of doing things that needs to be baked into your whole database interaction methodology.
Create a table that stores the following info...
CREATE TABLE MyData (
ID INT IDENTITY,
DataID INT )
CREATE TABLE Data (
ID INT IDENTITY,
MyID INT,
Name VARCHAR(50),
Timestamp DATETIME DEFAULT CURRENT_TIMESTAMP)
Now create a sproc that does this...
INSERT Data (MyID, Name)
VALUES(#MyID,#Name)
UPDATE MyData SET DataID = ##IDENTITY
WHERE ID = #MyID
In general, the MyData table is just a key table. You then point it to the record in the Data table that is the most current. Whenever you need to change data, you simply call the sproc which Inserts the new data into the Data table, then updates the MyData to point to the most recent record. All if the other tables in the system would key themselves off of the MyData.ID for foreign key purposes.
This arrangement sidesteps the need for a second log table(and keeping them in sync when the schema changes), but at the cost of an extra join and some overhead when creating new records.
Do you need it to remain queryable, or will this just be for recovering from bad edits? If the latter, you could just set up a cron job to back up the actual files where MySQL stores the data and send it to a version control server.

Why is it necessary to assign atleast one column in a table (in MySQL) as PRIMARY KEY for the table to accept UPDATE and INSERT statements via JDBC?

Also; can I add a negative INT inside a PRIMARY KEY column inside a table via JDBC?
There should be no reason why you can't have a negative number in a primary key field, unless you are using an unsigned integer as its data type.
When you don't have a primary key defined (or a unique index for that matter), the database server has no way of knowing that the rows are unique. Being able to tell one row from another is pretty fundamental when it comes to databases, and I think maybe the designers of MySQL probably are forcing this on you -- I don't know, since I don't use MySQL all that much... It's a problem that I've never ran into, to be honest, because pretty much every table that I ever create has a PK!
Why is it necessary to assign atleast one column in a table (in MySQL) as PRIMARY KEY for the table to accept UPDATE and INSERT statements via JDBC?
This is not a JDBC limitation. This is a database limitation. Consult DB-specific docs for answers.
Also; can I add a negative INT inside a PRIMARY KEY column inside a table via JDBC?
This is not a JDBC limitation. This is a database limitation. Consult DB-specific docs for answers.
To make things clear: JDBC is here just a simple tool to give you the ability to execute the SQL language using the Java language. If you get exceptions of java.sql package, then the problem more lies in the faulty SQL syntax used, or a limitation in the database in question, or in rare cases a bug in the DB-supplied JDBC driver, but it certainly isn't caused by the JDBC API in general as you seem to think.

ms access replication id as foreign key

I am currently "forced" to create a database in ms access 2007.
Due to replication issues i have decided to use autonumber as ReplicationID for my Users table.
On my venues table i would like to use this id as the user created.
I have tried to use the userID in textboxes accross the main form, but it outputs
{guid {BF40D0A0-A1F3-4C98-A9B6-D9D075F0BBA3}}
and when using this value to insert into my Venues table, it generates a new ReplicationID.
Am i missing some setting where it will use the GUID provided, or do you have any other suggestion.
Regards.
I don't pretend to understand replication in Access. However the two best resources are
Subject: INFO: Replication and
GUIDs, the Good, the Bad, and the
Ugly Basically don't use GUID as
a primary key.
Jet Replication Wiki David Fenton has stated it would
be fine if those without experience
created sections for issues they
wanted explained.
OK i found it. What happened was that you cannot insert a guid string in ms access, you have to use the actual object. Then all was fine.
dont use StringFromGUID/GUIDFromString, just insert the object as is and all is well.
Any questions and i will gladly explain X-)
Don't expose autonumber values to users, especially of the GUID flavour!