U++ Forum - RDF feed
type: channel
description: Main place for discussions about U++ cross platform development framework.
items: sqlarray and sqlite
items: Re: sqlarray and sqlite

sqlarray and sqlite
type: item
description: Hi everyone, I've been looking over the example for sqlite and these forums, and basically I want to bind my table to the array... When I try to code this, I get "not defined" errors, and I am not seeing where in the example these things were defined other than the schema. I'm lost as to where to move forward here, before adding query functions etc. My schema: TABLE (tbl_customers) INT (id) NOT_NULL PRIMARY_KEY AUTO_INCREMENT STRING (name, 150) NOT_NULL STRING (email, 150) STRING (contact, 150) STRING (address, 150) STRING (city, 50) STRING (state, 20) STRING (zip, 10) INT (taxable) NOT_NULL END_TABLE My include file: sqlinclude.h: #ifndef _Invoices_sqlinclude_h_ #define _Invoices_sqlinclude_h_ #include <SqlCtrl/SqlCtrl.h> #include <plugin/sqlite3/Sqlite3.h> #define SCHEMADIALECT <plugin/sqlite3/Sqlite3Schema.h> #define MODEL "Invoices/Tables/Invoices.sch" #include <Sql/sch_header.h> #endif customers.h: #ifndef _Invoices_customers_h_ #define _Invoices_customers_h_ #include "Invoices/sqlinclude.h" struct CustomersWindow : WithCustomersWindowLayout<TopWindow> { public: CustomersWindow(); void Paint(Draw& w) { w.DrawRect(GetSize(), Color(204, 255, 255)); // <= enter your background color here } }; #endif In my layout I have ITEM(SqlArray, CustArray, LeftPosZ(436, 656).TopPosZ(28, 420)) And my cpp code: #include "Invoices.h" #include "customers.h" CustomersWindow::CustomersWindow() { CtrlLayout(*this, "Customers"); CustArray.SetTable(tbl_customers); CustArray.AddKey(id); // CustArray.Join(BOOK_ID, book); // joins id from other db to this id CustArray.AddColumn(name, "Name"); // .SetConvert(DateIntConvert()); CustArray.AddColumn(email, "Email"); // .SetConvert(DateIntConvert()); CustArray.AddColumn(contact, "Phone"); CustArray.AddColumn(address, "Address"); CustArray.AddColumn(city, "City"); CustArray.AddColumn(state, "State"); CustArray.AddColumn(zip, "Zip"); CustArray.AddColumn(taxable, "Taxable?"); CustArray.ColumnWidths("50 50 20 50 20 15 10 2"); CustArray.SetOrderBy…
creator: jimlef
date: 2020-09-18T20:49:14-00:00

Re: sqlarray and sqlite
type: item
description: Additional info: My original app has a customerstable.cs definition file (converted to c): struct customersTable { int id; String name; String email; String contact; String address; String city; String state; String zip; int taxable; }; Do I need something like this here? Thanks.
creator: jimlef
date: 2020-09-19T03:50:56-00:00

Re: sqlarray and sqlite
type: item
description: Ok - In the upper left of Upp, I right click and add packages Sql, SqlCtrl, and plugin/sqlite3... and in customers I add this line: SqlId tbl_customers("tbl_customers"), id("id"), name("name"), email("email"), contact("contact"), address("address"), city("city"), state("state"), zip("zip"), taxable("taxable"); That replaces my table structure, and the code compiles without a problem. Next up, getting the table to show up in the sql array with a query I think...
creator: jimlef
date: 2020-09-19T04:57:29-00:00

Re: sqlarray and sqlite
type: item
description: Last post of the evening, I promise I now have my table populated with values, not sure if this is the best way (I'm a newb at this after all) but here's the working code: #include "Invoices.h" #include "customers.h" #define SCHEMADIALECT <plugin/sqlite3/Sqlite3Schema.h> #include "Sql/sch_source.h" CustomersWindow::CustomersWindow() { String DBFile; String configfile = ConfigFile(); CtrlLayout(*this, "Customers"); if(FileExists(configfile)) { VectorMap<String, String> cfg = LoadIniFile(configfile); DBFile = cfg.Get("DBFile", Null); } else { Exclamation("Can't find DB"); } SQL; Sqlite3Session sqlite3; if(!sqlite3.Open(DBFile)) { Exclamation("Can't create or open database file\n"); return; } SQL = sqlite3; SqlId tbl_customers("tbl_customers"), id("id"), name("name"), email("email"), contact("contact"), address("address"), city("city"), state("state"), zip("zip"), taxable("taxable"); CustArray.SetTable(tbl_customers); CustArray.AddKey(id); // CustArray.Join(BOOK_ID, book); // joins id from other db to this id CustArray.AddColumn(name, "Name"); // .SetConvert(DateIntConvert()); CustArray.AddColumn(email, "Email"); // .SetConvert(DateIntConvert()); CustArray.AddColumn(contact, "Phone"); CustArray.AddColumn(address, "Address"); CustArray.AddColumn(city, "City"); CustArray.AddColumn(state, "State"); CustArray.AddColumn(zip, "Zip"); CustArray.AddColumn(taxable, "Taxable?"); CustArray.ColumnWidths("40 40 20 50 20 15 10 5"); CustArray.SetOrderBy(id); Sql sql(sqlite3); sql.Execute("select * from tbl_customers"); while(sql.Fetch()) CustArray.Add(sql); // CustArray.WhenBar = THISBACK(BorrowMenu); // CustArray.WhenLeftDouble = THISBACK(EditBorrow); CustArray.GoEndPostQuery(); } Good night all ...
creator: jimlef
date: 2020-09-19T06:04:03-00:00

Re: sqlarray and sqlite
type: item
description: If you add '_' to .sch definition TABLE_ (tbl_customers) INT_ (id) NOT_NULL PRIMARY_KEY AUTO_INCREMENT STRING_ (name, 150) NOT_NULL it will make it produce SqlId constants that you are defining in the constructor. However, populating global namespace with such variables would not be a good idea, that is why standard in U++ is upppercase for sql constants to minimize name clashes. Also struct customersTable is in fact produced by .sch mechanism as S_customersTable too and you can fetch it from the table, insert it etc... It is not needed, but sometimes handy.
creator: mirek
date: 2020-09-21T06:19:18-00:00

Re: sqlarray and sqlite
type: item
description: Hello Mirek, And thank you - both for this very helpful information, and for this amazing effort!
creator: jimlef
date: 2020-09-21T20:54:35-00:00

Re: sqlarray and sqlite
type: item
description: Ok, I've modded the files per Mirek's suggestions, but I keep hitting a wall here I get the error: /home/james/upp/MyApps/Invoices/UI/customers.cpp (33): error: use of undeclared identifier 'CUSTOMERS'; did you mean 'CUSTOMERID'? So, I change: CustArray.SetTable(CUSTOMERS, CUST_ID); CustArray.SetTable(S_CUSTOMERS, CUST_ID); And I get: /home/james/upp/MyApps/Invoices/UI/customers.cpp (33): error: 'S_CUSTOMERS' does not refer to a value My header info: #ifndef _Invoices_customers_h_ #define _Invoices_customers_h_ #include <Invoices/UI/sqlincludes.h> struct CustomersWindow : WithCustomersWindowLayout<TopWindow> { String DBFile; String configfile = ConfigFile(); String cfg; FileSel selectdbwin; public: CustomersWindow(); virtual void Paint(Draw& w) { w.DrawRect(GetSize(), Color(204, 255, 255)); // <= enter your background color here } void btnAddCustomerClick(); void btnUpdateCustomerClick(); void btnSearchCustomerClick(); void EditRow(); String SelectDB(); void FakeStub(); }; #endif AND #ifndef _Invoices_sqlincludes_h_ #define _Invoices_sqlincludes_h_ #include <SqlCtrl/SqlCtrl.h> #include <plugin/sqlite3/Sqlite3.h> using namespace Upp; #define LAYOUTFILE <Invoices/UI/Invoices.lay> #include <CtrlCore/lay.h> #define SCHEMADIALECT <plugin/sqlite3/Sqlite3Schema.h> // <-- Mirek informed needed in header for sql schema use #define MODEL "Invoices/Tables/Invoices.sch" #include <Sql/sch_header.h> #undef MODEL #endif CPP File: #include "customers.h" #define MODEL <Invoices/Tables/Invoices.sch> #include <Sql/sch_source.h> #undef MODEL CustomersWindow::CustomersWindow() { CtrlLayout(*this, "Customers"); btnAddCustomer << [=] { btnAddCustomerClick(); }; // THISBACK is not needed in c++11 world and could be replaced with lambda. btnSearchCustomer << [=] { btnSearchCustomerClick(); }; // assisted by forum user Klugier btnUpdateCustomer << [=] { btnUpdateCustomerClick(); }; btnFake << [=] { FakeStub(); }; if(FileExists(configfile)) { VectorMap<String, String> cfg = LoadIniFile(config…
creator: jimlef
date: 2020-09-22T01:05:37-00:00

Re: sqlarray and sqlite
type: item
description: Your .sch creates SqlId CUSTOMERS("CUSTOMERS"); struct S_CUSTOMER { ..... }; SetTable obviously needs CUSTOMERS as parameter.... Additional suggestion: CustArray is SqlArray, right? In that case it is better to leave fetching the data to CustArray.Query(); You can also add where condition e.g.: CustArray.Query(EMAIL == "smith@email.com"); Sql sql(sqlite3); You do need to specify the session here, as you have assigned a global default session by SQL = sqlite3; And it is better to avoid text SQL commands with SqlExp: sql.Execute("select * from CUSTOMERS"); sql * SelectAll().From(CUSTOMERS); see https://www.ultimatepp.org/src$Sql$SqlExp_en-us.html This way your commands get at least partially checked by C++ compiler and more importantly it avoids SQL injection problem. Mirek
creator: mirek
date: 2020-09-22T07:08:00-00:00

Re: sqlarray and sqlite
type: item
description: mirek wrote on Tue, 22 September 2020 03:08 Your .sch creates SqlId CUSTOMERS("CUSTOMERS"); struct S_CUSTOMER { ..... }; SetTable obviously needs CUSTOMERS as parameter.... Yes, I caught that and had corrected it, thank you... Quote: Additional suggestion: CustArray is SqlArray, right? In that case it is better to leave fetching the data to CustArray.Query(); You can also add where condition e.g.: CustArray.Query(EMAIL == "smith@email.com"); Sql sql(sqlite3); You do need to specify the session here, as you have assigned a global default session by SQL = sqlite3; And it is better to avoid text SQL commands with SqlExp: sql.Execute("select * from CUSTOMERS"); sql * SelectAll().From(CUSTOMERS); see https://www.ultimatepp.org/src$Sql$SqlExp_en-us.html This way your commands get at least partially checked by C++ compiler and more importantly it avoids SQL injection problem. Mirek That URL is perfect - I missed that in my searches obviously... I was wondering how to do more as in my c#: public bool Delete(customersTable dc) { ... //SQL Query to Delete Data from database string sql = "DELETE FROM CUSTOMERS WHERE CUST_ID=@id"; //SQL command to pass the value SQLiteCommand cmd = new SQLiteCommand(sql, conn); //Passing the value cmd.Parameters.AddWithValue("@id", dc.CUST_ID); //Open DB Connection conn.Open(); //integer variable int rows = cmd.ExecuteNonQuery(); if(rows>0) //Success { ... Thank you again
creator: jimlef
date: 2020-09-22T15:43:23-00:00

Re: sqlarray and sqlite
type: item
description: public bool Delete(customersTable dc) { ... //SQL Query to Delete Data from database string sql = "DELETE FROM CUSTOMERS WHERE CUST_ID=@id"; //SQL command to pass the value SQLiteCommand cmd = new SQLiteCommand(sql, conn); //Passing the value cmd.Parameters.AddWithValue("@id", dc.CUST_ID); //Open DB Connection conn.Open(); //integer variable int rows = cmd.ExecuteNonQuery(); if(rows>0) //Success { Yeah, thats crazy, compared to SQL * Delete(CUSTOMERS).Where(CUST_ID == id); Mirek
creator: mirek
date: 2020-09-22T15:54:55-00:00

Re: sqlarray and sqlite
type: item
description: I see that now LOL but I keep getting an xmessage fatal error, invalid memory access when I change sql.Execute("select * from CUSTOMERS"); to sql * SelectAll().From(CUSTOMERS); And then run the program...
creator: jimlef
date: 2020-09-22T16:07:57-00:00

Re: sqlarray and sqlite
type: item
description: Not enough context to figure that out. However, in case of crashes, usually the fastest route is to run it in debugger (just press F5), then investigate backtrace. You can even copy it (in Debug/Copy backtrace of all threads) and send here. Mirek
creator: mirek
date: 2020-09-22T16:47:53-00:00

Re: sqlarray and sqlite
type: item
description: ---------------------------------- Thread: 1 ---------------------------------- Thread: 2 ../sysdeps/unix/sysv/linux/poll.c:29 /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 g_main_context_iteration () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 start_thread (arg=<optimized out>) at pthread_create.c:477 clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95 ---------------------------------- Thread: 3 ../sysdeps/unix/sysv/linux/poll.c:29 /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 g_main_loop_run () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0 /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 start_thread (arg=<optimized out>) at pthread_create.c:477 clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95 ---------------------------------- Thread: 4 futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0xe82d60 <Upp::CoWork::GetPool()::pool+114848>) at ../sysdeps/nptl/futex-internal.h:183 pthread_cond_wait.c:508 pthread_cond_wait.c:638 Upp::ConditionVariable::Wait (this=0xe82d38 <Upp::CoWork::GetPool()::pool+114808>, m=..., timeout_ms=-1) at Mt.cpp:624 Upp::CoWork::Pool::ThreadRun (tno=0) at CoWork.cpp:155 Upp::CoWork::Pool::InitThreads(int)::$_21::operator()() const (this=0x7ffff4de58ec) at CoWork.cpp:31 Upp::Function<void ()>::Wrapper<Upp::CoWork::Pool::InitThreads(int)::$_21>::Execute() (this=0x7ffff4de58e0) at Function.h:17 Upp::Function<void ()>::operator()() const (this=0x7ffff4de5920) at /home/james/upp/uppsrc/Core/Function.h:76 Upp::sThreadRoutine (arg=0x7ffff4de5920) at Mt.cpp:91 start_thread (arg=<optimized out>) at pthread_create.c:477 clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95 ---------------------------------- Thread: 5 futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0xe82d60 <Upp::CoWork::GetPool()::pool+114848>) at ../sysdeps/nptl/futex-internal.h:183 pthread_cond_wait.c:508…
creator: jimlef
date: 2020-09-22T18:41:03-00:00

Re: sqlarray and sqlite
type: item
description: I do not see apparent reason in the code posted. One suspicios line is SQL; which should normally do nothing, but would crash if you have assigned a session prior to constructor and that session was meanwhile destroyed. If you can .zip the whole package and post here, I am glad to investigate further. BTW, you do not need to do that SelectAll query here if you are using SqlArray::Query (that one does its own select). Mirek
creator: mirek
date: 2020-09-23T14:32:19-00:00

Re: sqlarray and sqlite
type: item
description: Thank you for looking at this and for all your help, Mirek... I've stripped things down to the main and one (customers) module, with a few support files, and everything is compiling and running without error now. For curiosity's sake, I'm putting the current zip here. And again, I wish I'd found this site a long time ago!
creator: jimlef
date: 2020-09-23T15:14:13-00:00

Re: sqlarray and sqlite
type: item
description: I realize that I've been going about this all wrong... I've been trying to do a 1 - 1 conversion from my c# code to the c++ and U++... That's wrong thinking. I need to embrace the U++, so I went back to the examples, and am using the book borrowing app. I've come up with the following code: #include "customers.h" #define MODEL <Invoices/Tables/Invoices.sch> #include <Sql/sch_source.h> #undef MODEL class AddCustomer : public WithCustomerAddLayout<TopWindow> { public: SqlCtrls ctrls; typedef AddCustomer CLASSNAME; AddCustomer(); }; /* ITEM(Option, chkTaxable, SetLabel(t_("Taxable?")).SetFont(SansSerifZ(16)).LeftPosZ(228, 108).TopPosZ(36, 16)) ITEM(EditString, txtCustSearch, SetFont(SansSerifZ(16)).SetFrame(FieldFrame()).LeftPosZ(136, 256).TopPosZ(404, 19)) ITEM(EditString, txtCustName, SetFont(SansSerifZ(16)).SetFrame(FieldFrame()).LeftPosZ(136, 256).TopPosZ(76, 19)) ITEM(EditString, txtCustEmail, SetFont(SansSerifZ(16)).SetFrame(FieldFrame()).LeftPosZ(136, 256).TopPosZ(116, 19)) ITEM(EditString, txtCustPhone, SetFont(SansSerifZ(16)).SetFrame(FieldFrame()).LeftPosZ(136, 256).TopPosZ(156, 19)) ITEM(EditString, txtCustAddress, SetFont(SansSerifZ(16)).SetFrame(FieldFrame()).LeftPosZ(136, 256).TopPosZ(196, 19)) ITEM(EditString, txtCustCity, SetFont(SansSerifZ(16)).SetFrame(FieldFrame()).LeftPosZ(136, 256).TopPosZ(232, 19)) ITEM(EditString, txtCustState, SetFont(SansSerifZ(16)).SetFrame(FieldFrame()).LeftPosZ(136, 256).TopPosZ(272, 19)) ITEM(EditString, txtCustZip, MaxChars(10).SetFont(SansSerifZ(16)).SetFrame(FieldFrame()).LeftPosZ(136, 64).TopPosZ(308, 19)) STRING_ (CUSTNAME, 150) NOT_NULL STRING_ (EMAIL, 150) STRING_ (CONTACT, 150) STRING_ (ADDRESS, 150) STRING_ (CITY, 50) STRING_ (STATE, 20) STRING_ (ZIP, 10) INT_ (TAXABLE) NOT_NULL */ AddCustomer::AddCustomer() { CtrlLayoutOKCancel(*this, "Add Customer"); ctrls (CUSTNAME, txtCustName) (EMAIL, txtCustEmail) (CONTACT, txtCustPhone) (ADDRESS, txtCustAddress) (CITY, txtCustCity) (STATE, txtCustState) (ZIP, txtCustZip) // …
creator: jimlef
date: 2020-09-23T17:57:01-00:00

Re: sqlarray and sqlite
type: item
description: I may have fixed my own problem, and found my mistake... in my code, I was using sql statements to generate the global SQL in the customers module. I needed to move those to the main line. So here's tne new code for anyone looking: #main.cpp #include "Invoices.h" #define MODEL "Invoices/Tables/Invoices.sch" #include <Sql/sch_schema.h> #undef MODEL void Invoices::MainMenu(Bar& bar) { bar.Add(t_("Customers"), [=]{ if(!cwin.IsOpen()) cwin.Open(this); }); // bar.Add(t_("Products"), [=]{ if(!prodwin.IsOpen()) prodwin.Open(this); }); // bar.Sub(t_("Transactions"), THISFN(TransactionsMenu)); // bar.Sub(t_("Reports"), THISFN(ReportsMenu)); bar.Sub(t_("Management"), THISFN(ManagementMenu)); bar.Add(t_("Exit"), THISFN(Close)); } /* void Invoices::TransactionsMenu(Bar& bar) { bar.Add(t_("Create Invoice"), [=]{ if(!createinvoicewin.IsOpen()) createinvoicewin.Open(this); }); bar.Add(t_("List Invoices"), [=]{ if(!listinvoiceswin.IsOpen()) listinvoiceswin.Open(this); }); bar.Add(t_("List Line Items"), [=]{ if(!listlineitemswin.IsOpen()) listlineitemswin.Open(this); }); } void Invoices::ReportsMenu(Bar& bar) { bar.Add(t_("Income / Sales Tax"), [=]{ if(!taxreportwin.IsOpen()) taxreportwin.Open(this); }); bar.Add(t_("Income / Sales Tax by Customer"), [=]{ if(!taxbycustomerwin.IsOpen()) taxbycustomerwin.Open(this); }); bar.Add(t_("Income by Customer"), [=]{ if(!incomewin.IsOpen()) incomewin.Open(this); }); bar.Add(t_("Profit / Loss"), [=]{ if(!profitwin.IsOpen()) profitwin.Open(this); }); } */ void Invoices::ManagementMenu(Bar& bar) { bar.Add(t_("Select Database File"), [=]{myConfig.DBFile = myConfig.SelectDB(); }); bar.Add(t_("Show Current Database File"), [=]{PromptOK(DeQtf("Current Database file is: \n" + myConfig.DBFile));}); // bar.Add(t_("Set Company Info"), [=]{if(!setcompanywin.IsOpen()) setcompanywin.Open(this); }); bar.Add(t_("Select Output Directory"), [=]{ myConfig.OutputDirectory = myConfig.GetOutputDirectory(); }); } Invoices::Invoices() { CtrlLayout(*this, "Invoices"); …
creator: jimlef
date: 2020-09-24T04:08:03-00:00

Re: sqlarray and sqlite
type: item
description: jimlef wrote on Thu, 24 September 2020 06:08 Now I should make much more rapid progress until I get to the printing/reporting stage... In advance: https://www.ultimatepp.org/srcdoc$RichText$QTF$en-us.html https://www.ultimatepp.org/reference$Reports$en-us.html Mirek
creator: mirek
date: 2020-09-24T11:46:29-00:00

Re: sqlarray and sqlite
type: item
description: mirek wrote on Thu, 24 September 2020 07:46 jimlef wrote on Thu, 24 September 2020 06:08 Now I should make much more rapid progress until I get to the printing/reporting stage... In advance: https://www.ultimatepp.org/srcdoc$RichText$QTF$en-us.html https://www.ultimatepp.org/reference$Reports$en-us.html Mirek Bookmarked - and Thanks again
creator: jimlef
date: 2020-09-24T14:40:09-00:00

Re: sqlarray and sqlite
type: item
description: And for your amuse... er info, here's the c# code I'm converting:
creator: jimlef
date: 2020-09-24T17:28:02-00:00

Re: sqlarray and sqlite
type: item
description: I have looked through the code and I am impressed, you got it almost all right in really record time! Some tidbits: SQL * Select(dlg.ctrls).From(LINEITEMS).Where(LINEITEM_ID == idNum); Using SQL for Select with Fetch loop is possible but not quite recommended (mostly on past experience, I have shoot my leg several times here . The problem is that very often your Fetch loop will call some routine and that routine will use SQL for something else (e.g. Update or another Select) and that will erase the current resultset... Better declare Sql sql and fetch from this. Note that usage like SQL % Select ... (selecting single value from single line, no fetching) is still fine. Value ConvLineItemCls::Scan ( const Value &q ) const I see that you have not used it afterwards, but anyway... Scan is supposed to convert from "display" format - usually text - to Value. Your usage seems exactly opposite. I guess it should have been Format here (format from Value to usually text). SQL & ::Insert(LINEITEMS) Sql::operator& is deprecated. It makes the statment throw exception, but that approach was not quite as useful as it seemed. Use * and test for error aftewards... Mirek
creator: mirek
date: 2020-10-02T09:40:01-00:00

Re: sqlarray and sqlite
type: item
description: Thank you again - the help I've been getting from you and the others on this forum have made this all possible I have some time this afternoon to do some more work so I will take these pointers to heart.
creator: jimlef
date: 2020-10-02T13:13:50-00:00

Re: sqlarray and sqlite
type: item
description: I have eliminated the need for the line item convert functions, and cleaned up more code in lineitems & createinvoice Thank you! I'm keeping github updated, https://github.com/phoenixjim/Invoices - easy access for all.
creator: jimlef
date: 2020-10-02T22:17:31-00:00

Re: sqlarray and sqlite
type: item
description: I think you should get your Values right.... StrDbl(arrayLineItems.GetColumn(i,2).ToString()) This is really not how we meant it In general, GetColumn returns Value and if you have put double into ArrayCtrl or SqlArray, it will return double Value back. So normally above should be something like (double)arrayLineItems.GetColumn(i,2); Also SQL * Select(CUST_ID, CUSTNAME).From(CUSTOMERS); while (SQL.Fetch()) { cbCustomers.Add(~SQL[CUST_ID], ~SQL[CUSTNAME]); } operator~ in this context converts perfectly good typed Value into String. Probably not something I would do to CUST_ID. if (txtPrice.GetData().IsNull()) return; You can just write IsNull(txtPrice). Instead of GetData, consider using operator~ (that in U++ has general meaning something like "other value representation"). arrayLineItems.AddColumn("Description", 80); .... (DESCRIPTION, arrayLineItems.GetColumn(i,1).ToString()) Sometimes it is worth providing IDs even if you are not directly dealing with SQL, leads to cleaner code arrayLineItems.AddColumn(DESCRIPTION, "Description", 80); .... (DESCRIPTION, arrayLineItems.GetColumn(i,DESCRIPTION)) (ToString here is not needed as well as AFAIK it is already String). SQL * Select(TAXABLE).From(CUSTOMERS).Where(CUST_ID == idNum); SQL.Fetch(); optCustTaxable.Set(SQL[0]); As this is pretty common code, there is a shortcut: optCustTaxable.Set(SQL % Select(TAXABLE).From(CUSTOMERS).Where(CUST_ID == idNum)); Mirek
creator: mirek
date: 2020-10-04T08:05:35-00:00

Re: sqlarray and sqlite
type: item
description: Again, Thank you Mirek! Quote: Sometimes it is worth providing IDs even if you are not directly dealing with SQL, leads to cleaner code arrayLineItems.AddColumn(DESCRIPTION, "Description", 80); .... (DESCRIPTION, arrayLineItems.GetColumn(i,DESCRIPTION)) Only one issue when I implement these, I keep getting: 102 if (optCustTaxable.Get() == true && arrayLineItems.GetColumn(i, ISTAXABLE) == 1) { 103 taxable = round((double)arrayLineItems.GetColumn(i, PRICE) * (double)arrayLineItems.GetColumn(i, QTY), 2); /home/james/upp/MyApps/Invoices/UI/CreateInvoice.cpp (102): error: no viable conversion from 'Upp::SqlId' to 'int' /home/james/upp/MyApps/Invoices/UI/CreateInvoice.cpp (103): error: no viable conversion from 'Upp::SqlId' to 'int' ... /home/james/upp/MyApps/Invoices/UI/CreateInvoice.cpp (171): error: no viable conversion from 'Upp::SqlId' to 'int' Every GetColumn call in the code generates this error? Jim
creator: jimlef
date: 2020-10-04T15:27:52-00:00

Re: sqlarray and sqlite
type: item
description: Sorry, you need to call Get(i, DESCRIPTION). Mirek
creator: mirek
date: 2020-10-04T17:56:53-00:00

Re: sqlarray and sqlite
type: item
description: Ahh, that's the ticket Thanks!
creator: jimlef
date: 2020-10-04T18:37:25-00:00