I am developing an Odoo 8 (OpenERP) application. That application use postgresql database. In backend of Odoo 8, there is add sale order button. So, I want to know, how to know the changing data in the last 5 seconds? My need is I want to insert data from mobile apps. What tables that that changing? Any query for do that? Or another suggest.
the database has 314 tables. Is there application of part3 like MONYog may be?
Any help is very appreciate.
For this kind of situation, there is one best way to manage as
Use always two columns in each table as "CreatedOn" and "LastUpdatedOn", and insert proepr values in it as on create time add current time in both then on every update just change last updated on by current time so you will easily get data as per your requirement.
You could also add a function like this:
create or replace function notify_table_change() RETURNS TRIGGER
LANGUAGE PLPGSQL AS
$$
NOTIFY all_writes TG_RELNAME;
IF TG_OP = 'DELETE' THEN RETURN OLD; ELSE RETURN NEW; END OF;
$$;
Then you could add the trigger for all inserts, updates, and deletes (but not truncate since I didn't handle that).
Then te client can:
LISTEN all_writes;
And will get live notifications of which tables are updated in real time.
Monitoring database feels a bit strange approach to the problem. Writing custom modules for odoo (and OpenERP) is very simple and staightforward. I'd create module which triggers whatever you want to do.
Here is a brief example of simplest OpenERP / odoo module:
from osv import osv
class my_custom_module(osv.osv):
_inherit = 'sale.order'
_name = 'sale.order'
def create(self, cr, uid, vals, ctx={}):
<your code here, whatever you want to do when new sale.order obejcet is created >
return super(my_custom_module, self).create(cr, uid, vals, ctx)
my_custom_module()
Does this help?
In a live commercial app. The method I use is a creation and update date/time stamp column.
Example
create table foo (
foo_id serial not null unique,
created_timestamp timestamp not null default current_timestamp,
updated_timestamp timestamp not null default current_timestamp
) with oids;
The trigger to do the work
CREATE TRIGGER check_table_to_do_update
--What i want to do
The trigger on the table
CREATE TRIGGER check_update_foo
AFTER UPDATE ON foo
FOR EACH ROW
WHEN (OLD.updated_timestamp IS DISTINCT FROM NEW.updated_timestamp)
EXECUTE PROCEDURE check_table__to_do_update();
Anything else can put an unnecessary overhead on the system.
All the best
Related
One problem I have them is 'like system' such as facebook like system.
I making the program using foreign hosting site having myisam mysql.
as you know the myisam mysql has not transaction system.
so it can not set key like foreign key to present relation or to set reference integrity
I think 'like system' what I making is important that how present and how set the reference integrity.
For instance, I made the A content and it has 3 'Likes'. if the contents delected, Like which already has also has to delected.
but int myisam mysql system it is impossible. because the isam mysql cannot set reference integrity system to tables
for these reason I regret the choice that I selected myisam mysql system at first step.
Even though I have know inno DB can these problems, I spend a lot of time to this project.
So how can I set reference integrity system to my project (Like system) or any other method to solve this situation?
If you can't change Database engine to Innodb and want to continue with MyISAM, triggers will be useful for you.
Syntax
CREATE TRIGGER trigger_name
BEFORE DELETE
ON table_name FOR EACH ROW
BEGIN
-- variable declarations
-- trigger code
END;
Example
DELIMITER //
CREATE TRIGGER delete_likes
BEFORE DELETE
ON tbl_content FOR EACH ROW
BEGIN
DELETE FROM tbl_likes WHERE content_id = OLD.id;
END; //
DELIMITER ;
Lets say you have 2 tables named tbl_content and tbl_likes.
Column content_id in tbl_likes is a reference to id column in tbl_content.
The sample trigger named delete_likes will get triggered before deleting a row in tbl_content and will delete related rows from tbl_likes.
I am currently building a database recording events on the phone, but as I don't want to make this a huge database, 100 events are more than enough.
This will keep my database light en efficient.
Unfortunately, I don't see a way to limit the number of rows other than
String sql = "DELETE FROM myTable WHERE _id <= "+limitId;
and I could run this code when the user launch/leaver the app, but I am expecting a better way to achieve this
Is there a more convenient way to achieve this?
If you are using a ContentProvider, you can implement your DELETE in onInsert, deleting a single row on every insert of a single row:
String sql = "DELETE FROM myTable WHERE _id IN (SELECT min(_id) FROM myTable)";
I guess you mean limit to the 100 newest events ?
if so, there is no better way to do it as you did: checking for entries on every insert and delete old entries if necessary.
It's just a matter of taste how or where you do your check, as flx mentioned you could do it in the ContentProvider or as you probably did in the BroadcastReceiver or Service where you actually add the new row. You could also set up a Trigger on your table, but the main idea remains the same. Here a link if you're interested in triggers:
http://www.tutorialspoint.com/sqlite/sqlite_triggers.htm
I've got two SQLite databases, each with a table that I need to keep synchronized by merging rows that have the same key. The tables are laid out like this:
CREATE TABLE titles ( name TEXT PRIMARY KEY,
chapter TEXT ,
page INTEGER DEFAULT 1 ,
updated INTEGER DEFAULT 0 );
I want to be able to run the same commands on each of the two tables, with the result that for pairs of rows with the same name, whichever row has the greater value in updated will overwrite the other row completely, and rows which do not have a match are copied across, so both tables are identical when finished.
This is for an Android app, so I could feasibly do the comparisons in Java, but I'd prefer an SQLite solution if possible. I'm not very experienced with SQL, so the more explanation you can give, the more it'll help.
EDIT
To clarify: I need something I can execute at an arbitrary time, to be invoked by other code. One of the two databases is not always present, and may not be completely intact when operations on the other occur, so I don't think a trigger will work.
Assuming that you have attached the other database to your main database:
ATTACH '/some/where/.../the/other/db-file' AS other;
you can first delete all records that are to be overwritten because their updated field is smaller than the corresponding updated field in the other table:
DELETE FROM main.titles
WHERE updated < (SELECT updated
FROM other.titles
WHERE other.titles.name = main.titles.name);
and then copy all newer and missing records:
INSERT INTO main.titles
SELECT * FROM other.titles
WHERE name NOT IN (SELECT name
FROM main.titles);
To update in the other direction, exchange the main/other database names.
For this, you can use a trigger.
i.e.
CREATE TRIGGER sync_trigger
AFTER INSERT OR UPDATE OF updated ON titles
REFERENCING NEW AS n
FOR EACH ROW
DECLARE updated_match;
DECLARE prime_name;
DECLARE max_updated;
BEGIN
SET prime_name = n.name;
ATTACH database2name AS db2;
SELECT updated
INTO updated_match
FROM db2.titles t
WHERE t.name=prime_name)
IF updated_match is not null THEN
IF n.updated > updated_match THEN
SET max_updated=n.updated;
ELSE
SET max_updated=updated_match;
END IF;
UPDATE titles
SET updated=max_updated
WHERE name=prime_name;
UPDATE db2.titles
SET updated=max_updated
WHERE name=prime_name;
END IF;
END sync_trigger;
The syntax may be a little off. I don't use triggers all that often and this is a fairly complex one, but it should give you an idea of where to start at least. You will need to assign this to one database, exchanging "database2name" for the other database's name and then assign it again to the other database, swapping the "database2name" out for the other database.
Hope this helps.
So my fundamentals of creating and manipulating databases are a bit messed up. My aim here is that whenever the app is launched, the user is allowed to specify a table name, and whatever data is then collected is put into that table.
However, I'm confused as to how to do this. Do I simply pass the value of a user entered variable as the table name in my contentprovider class and execute sqlite statements to create it?
I've read/reading the documentation already, so if anyone has any insight or clarity, or even better, code snippets, it would be great.
Why not simply use one table, and create a value that stands for the current app-session, and insert that value with each row. This would make your code simpler, and would still allow you to segregate/filter out the values from a particular app-session. If you want to give the user the ability to enter the value (as you are giving them the ability to choose the table name) you'd just want to check to see if that value had already been used, just as you would have to see if the table-name had already been used.
I have a widget that currently takes a random string from an array and sets it to text view on update. The issue here is that the same item can be re-used multiple times in a row due to the string being 'random'
In order to solve this I was going to create a table that held String text, and int viewednum and increment the viewed number each time 'get text' was called. (on update in the widget).
My Question: If I put the insert statements in the widget, won't the data be inserted every time 'on update' is called?
Would it be better for it to go in the DBadapter class somewhere? I'm just unsure about the best way to make sure I don't enter duplicate data. If there is a better alternative like saving a csv file somewhere and using that I'm open to it, it seemed like a sqlite database was the way to go.
Thank you for your time.
That depends on what your onUpdate method does. If each time onUpdate is called it gets a random String from the database, then that would be the place to put it. However, if you are not getting the String during onUpdate, then you should put it in the method where you are accessing your database. I think your confusion is about the purpose of onUpdate. onUpdate doesn't get called every time the user scrolls by the homepage and sees your widget; it gets called regularly on a timescale you specify, and the whole purpose of it is, in a case like yours, to get a new String from the database.
As for your second question, yes, SQlite databases are the way to do it :) I haven't tried saving a csv file or something like that, but I imagine that would be a lot more complex than just using a database.
Declare your database with a UNIQUE constraint on the columns you want to keep unique, then set the desired behaviour via ON CONFLICT in the INSERT statement. ON CONFLICT REPLACE... means the most recent INSERT overwrites. ON CONFLICT IGNORE... keeps the older version.