SQLite on iOS...alter table IF? [duplicate] - ios

This question already has answers here:
ALTER TABLE ADD COLUMN IF NOT EXISTS in SQLite
(15 answers)
Closed 7 years ago.
I have inherited an existing iOS app codebase and have been told to alter a sqlite table but not use versioning (as in not just store a constant somewhere in the app that dictates how/whether to update the table). Is there a way to check whether a column exists and add that column if it doesn't exist without versioning?

Use SQLite's pragma table_info() to get a result set that includes one row per table. For example:
create table foo (bar text, baz text)
and
pragma table_info('foo')
That returns a two row result set:
[cid: 0, pk: 0, notnull: 0, name: bar, type: text, dflt_value: <null>]
[cid: 1, pk: 0, notnull: 0, name: baz, type: text, dflt_value: <null>]
So, perform pragma table_info('table') and then iterate through the rows returned and see if a row with a name value equal to the column you're looking for exists.

Related

inserting a row having no values for Primary Key columns fails

For the following table:
I run the following stored procedure:
I'm redirected to "Results" tab and seeing nothing. Then if I click on "refresh" icon (below Results tab), then I get the dialog saying:
SQLCODE = -625 validation error for column ID, value "* null *"
And of course, nothing is added...
As far as I understand, firebird expects somevalue for RC_ID (which is my PK and should principally automatically incremented). If I give value also for RC_ID, it is working well.
So, what should I do to make a clear "insert" without these errors?
The problem is that you are not setting a value for the primary key. Contrary to your expectation, primary keys are not automatically incremented. This is the case in any database I'm aware of. You always need to mark it as an identity, auto increment or generated, or something else to get that behavior, although some tools (table builders) may already apply this for you by default.
If you are using Firebird 3, you can define your column as GENERATED BY DEFAULT AS IDENTITY (see Identity Column Type in the Firebird 3 release notes). For earlier Firebird versions the best way is to define a sequence (also known as generator) with a before insert trigger that populates the primary key column.
For more details on how to define an identity column (or define the trigger), see my answer on this question: Easiest way to create an auto increment field in Firebird database.
In firebird, the autoincrement was not working like in MySQL. Thus, sending a value for RC_ID was a must...
I found some working examples based on idea:
create a generator
assign it to column (PK)
call GEN_ID with that generator like this:
:
begin
insert into RESERVATIONCATEGORY (RC_ID, RC_NAAM)
values (
GEN_ID(GEN_RESERVATIONCATEGORY _ID,1), 'selam'
);
suspend;
end

Odoo 8 - Compute Field with "store=True" can't store in database

I'm using Odoo 8 and I have a problem with compute field with type is Many2One.
Here, I declared department_id:
department_id = fields.Text(
string="Department", store=True,
comodel_name="hr.department",
compute="_get_department_id"
)
And fuction of this compute field:
#api.depends('employee_id')
def _get_department_id(self):
if self.employee_id.department_id:
self.department_id = self.employee_id.department_id.name
It seems to work right now, but it's not. In view, I can see the value of department_id. But in the database, the table has no column department_id and has no value of this column.
My question is: how can I store the department_id in database?
Notes:
In the declaration of department_id, I set store=True, but it did NOT store the value of this field in database.
I did a test. I add compute_field with type Text, It works, I don't know why compute field doesn't work with type Many2One.
#api.depends('employee_id')
def _get_compute_field(self):
if self.employee_id.department_id:
self.compute_field = self.employee_id.department_id.name
compute_field = fields.Text(
string="Compute Field", store=True,
compute="_get_compute_field"
)
The store=True works.
It may be that you added the computation to the field after it was created on the database. In this case the initial computation is not triggered.
A work around is to drop the column from the table and then upgrade your module. When the field is recreated the initial values should be computed.

What is the value of an empty cell in a SQLite DB in iOS

Given a SQLite database with records consisting of multiple text columns, what is the value of an empty cell (i.e., a cell that has never been updated)? Would it be nil, 0, or possibly empty string?
For example, consider the following table where A, B, and C are text columns:
id A B C
_ _ _ _
1 d e f
2 g h
3 i
What would be the value of cells 2C, 3B, and 3C?
If I were to update this table one record at a time, using the following query
update table set A=? B=? C=? where id=?
What would be the bind value of '?' when updating a record with an empty cell? I'm working with iOS if that matters.
Since only some cells are empty, the other option would be to update the table one cell at a time instead of one record at a time. That feels inefficient, however.
According to the SQLite documentation[1], a new value is either the default value defined when the table was created/last modified or NULL, which is different than nil in iOS.
Assuming you have control of the database in question, you can define a default value in that table that will suit your needs. If that is not the case, your code will need to test the value to make sure it is handled appropriately.
[1] https://www.sqlite.org/lang_insert.html

Confusion about the use of unique key in mongoid db indexing

Let's say I'm indexing my user collection's email field as below:
index({ email: 1 }, { unique: true })
The question is, what does unique: true specifies in above code.
its a variable to specify that the index specified is unique accross documents in a specific db
http://mongoid.org/en/mongoid/docs/indexing.html
from mongo docs
MongoDB allows you to specify a unique constraint on an index. These
constraints prevent applications from inserting documents that have
duplicate values for the inserted fields. Additionally, if you want to
create an index on a collection that has existing data that might have
duplicate values for the indexed field, you may chose combine unique
enforcement with duplicate dropping.
http://docs.mongodb.org/manual/tutorial/create-a-unique-index/
The unique : true statement here means that the index is Unique Index
By default, unique is false on MongoDB indexes.
Check the link for more details : http://docs.mongodb.org/manual/core/index-unique/

SQL Query: Using IF statement in defining new field

I have a table with many fields and additionally several boolean fields (ex: BField1, BField2, BField3 etc.).
I need to make a Select Query, which will select all fields except for boolean ones, and a new virtual field (ex: FirstTrueBool) whose value will equal to the name of the first TRUE Boolean Field.
For ex: Say I have BField1 = False, BField2 = True, BField3 = true, BField4=false, in that case SQL Query should set [FirstTrueBool] to "BField2". Is that possible?
Thank you in advance.
P.S. I use Microsoft Access (MDB) Database and Jet Engine.
If you want to keep the current architecture (mixed 'x' non-null status and 'y' non-status fields) you have (AFAIS now) only the option to use IIF:
Select MyNonStatusField1, /* other non-status fields here */
IIF([BField1], "BField1",
IIF([BField2], "BField2",
...
IIF([BFieldLast], "BFieldLast", "#No Flag#")
))))) -- put as many parenthesis as it needs to close the imbricated IIFs
From
MyTable
Of course you can add any Where clause you like.
EDIT:
Alternatively you can use the following trick:
Set the fields to null when the flag is false and put the order number (iow, "1" for BField1, "2" for BField2 etc.) when the flag is true. Be sure that the status fields are strings (ie. Varchar(2) or, better, Char(2) in SQL terminology)
Then you can use the COALESCE function in order to return the first non-value from the status fields which will be the index number as string. Then you can add in front of this string any text you like (for example "BField"). Then you will end with something like:
Select "BField" || Coalesce(BField1, BField2, BField3, BField4) /*etc. (add as many fields you like) */
From MyTable
Much clearer IMHO.
HTH
You would be better using a single 'int' column as a bitset (provided you have up to 32 columns) to represent the columns.
e.g. see SQL Server: Updating Integer Status Columns (it's sql server, but the same technique applies equally well to MS Access)

Resources