Linux

Q:

I have a licence for Linux Cloud server and APaaS Windows.
I have installed the product on Ubuntu 16.4 server, but when I tried to start the lianjad service, nothing happened.
I tried to find lianjad in /etc/lianja.d/, but I finded only lianja.com.

A:

lianjad is in /etc/init.d

The lianja service can also be started using the lianja-admin command. For full details, see here:

https://www.lianja.com/doc/index.php…nager_on_Linux


instructions on installing the new Lianja module for Apache on Linux.


GNOME on Fedora 25 and above uses Wayland instead of X11. Part of the Wayland design is to prevent graphical applications from running with root privileges.

If you are running with GNOME and have Wayland enabled (the default), the Lianja installers will run in text mode.

To run the installer in graphical mode, you will need to log in using the ‘GNOME on Xorg’ option in the session login screen.

Note that this also means the Lianja App Builder and the Lianja App Center cannot be run as root / with sudo when Wayland is enabled.

For more information on Wayland in GNOME on Fedora please see here Fedora 26: Common F26 bugs: Wayland issues.


 

 

Advertisements

Licencing

Q:

concurrent user based licensing

Does Lianja have any mechanism for controlling the total number of concurrent users?

Does Lianja provide any mechanism to prevent multiple logins on the same user account?

A:

One of the advantages of the ISV program is that you can request licenses limited by connections. A single user uses up to 6 async connections from the browser.

A single user can login and have 6 connections active on the same account.

There is no mechanism for preventing a named user from logging in multiple times and in fact the tabbed UI of browsers would be less useful if that was the case.

So, as an ISV you have unlimited Cloud Server distribution as part of your annual subscription. When you want to deploy to a customer site you can request a license and specify customer license information and max concurrent connections. We then monitor the number of active connections and refuse the connection if it exceeds the # licensed.

I should also add that there are undocumented functions that provide the ability to handle licensing; Activate, Deactivate, get license fields including # concurrent connections and type of license. These are provided to ISVs.


Q:

How would the ISV license apply to a single tenanted server set-up?

A:

Each Cloud Server that runs needs to be licensed. There is only one license activated, so if that has connection limits those limits will be applied.

As an ISV, you would request a license with all the details and you will be emailed a license key.

Licensing is handled in the cloud and ISVs use the same licensing system as we do. This is included in the ISV program.

Q:

I bought the Lianja APaaS Developer for Windows, May I install APaaS in server and install only Lianja App Builder in another computer that use the same activation code?

A:

The cloud server included with APaaS developer is only licensed for local development. You need to purchase a Cloud Server to install on another server.

 

Library

Q:

I have a file in the library called convert2.dbo
I am trying to call the file like so:

Code:
c:\lianja\bin\lianjaruntime.exe lib:/convert2dbo.dbo  --args "'TEST5_1_000001.jpg','TEST5_1_025001.jpg',50,'R:\test5\test5_ROLL2',2,'test5'"

I have also tried

Code:
lib:\

But not luck.

When I change it back to a file in the application it runs fine.

A:

Lianjaruntime.exe has no idea, on its own, where lib: is. Even if you are calling it with a run or spawn from inside Lianja. It’s in its own process.

You can specify –runtimedir to tell it where these files dirs are: this would (perhaps: I have a memory of it not doing so) make the LIB files automatically available.

You can specify –dir to set the default directory (the equivalent of having selected an app).

I have code that predates these switches where I use left(sys(16),3) in the .dbo I’m calling to get the current drive and then figure everything out from there. Only works in Windows.  I should change it to set(“dire”) which is also in Lianja now. That would make it OS independent. That particular SET(“directory”) command never got documented in VFP, although it was brought to their attention. It was very handy in VFP and is even handier here.


 

Lianja files

Q:

in App Builder this work..
but in App Center, this command:

Code:
select 0
SELECT * FROM syscolumnconstraints where lower(table_schem) = lower(dbname) into cursor cur_columnconstraints

not work..

error message: File ‘syscolumnconstraints.dbf’ does not exist.

I think this is not a real table..

A:

Correct: it is not a table. It is effectively (don’t know what it really is) a stored procedure that reads the information for you. You can’t write to it

System tables do not exist in the system database, they are pseudo tables that are created dynamically.



Editing the .lianja file for an app is discouraged and unsupported.


Q:

while reviewing the example_jqueryui app.

I opened the app and went to the Page:Navigation Panelata Source and it showed lib:/treeview.rsp?ondblclick=page1_navtreeselection&key =address%2Bcity%2Bcountry.

I clicked on the ellipse and it brought up treeview.rsp in the script editor but it was blank. On clsing the script and returning to the page work space Data Source was showing

app:/lib:/treeview.rsp?ondblclick=page1_navtreeselection&key =address%2Bcity%2Bcountry

and the treeview wasn’t working. Removing the app:/ prefix got everything working again but the editor still brings up a blank script and adds the app:/ prefix. This occurs from the app inspector as well as from the page attributes panel. In the end, in order to view/edit the treeview script I have to open it from the library work space.

A:

yes, that’s an editor infelicity. Same thing happens when debugging and you get the “Do you want to fix” dialog: the debugger thinks the file is always in the app directory. Click on “Yes” (you want to edit) and it creates a blank one in the app directory.


 

JSON and OData

Q:

The app has to be an executable, so electron looks perfect.
It is a disconnected app that has no database and needs to be installed all over the globe as just an executable and some support files.
All of the data is coming from already existing web services. So I am decoding json data with getUrl and json_decode.

I will try a temp table/cursor on init

A:

until we get disconnected data (it’s in the roadmap, currently for 4.1), that will not work. The cursor never exists on the mobile client: JSON record(s) are sent from the server, and updates are sent back by JSON.


Q:

In a canvas section, there are input textbox, combobox and checkbox. These input items table fields (character/numeric/logical) have data source bind to them.

When I use getJson() to pass all the item values to backend.prg, all the data types decode from the Json parameter seems to be character or logical .f. if nothing enter into the textbox.

Is this the correct behaviour?

A:

JSON format is text only

When exchanging data between a browser and a server, the data can only be text.

Logical .f. is not correct JSON format and you should provide some value if nothing is entered in textbox.

A2:

I would also recommend that you use the base64_encode() function to encode the JSON if you are passing it as parameter. In your server side proc you would then use use base64_decode() to decode it.

This prevents any issues with special characters being transferred.


Lianja Cloud Server supports OData-compatible data access.

The Server handles ODBC connections as well as HTTP requests using OData URIs. In the following article I will show you how to use Lianja Cloud Server with OData URIs that will allow you to perform CRUD (Create, Read, Update and Delete) operations on your data.

Making OData requests from jQuery and/or the Lianja HTML5 Client in a Web App is extremely straightforward and simple.

Unlike other OData implementations, Lianja Cloud Server OData services does not require any server-side configuration of web services.

http://www.lianja.com/resources/blog…-cloud-server-

You can use Lianja cloud server odata calls to perform CRUD operations on virtual tables too so this functionality is not limited to native Lianja data; MSSQL, MySQL, PostgreSQL, Oracle and others are all supported.

Let me just emphasize again. Unlike other OData implementations, Lianja Cloud Server OData services does not require any server-side configuration of web services.


Using OData to query MSSQL is working fine for me.

Name:  Screen Shot 2017-01-31 at 9.07.51 AM.jpg Views: 45 Size:  170.7 KB

The example shows how to use it with Lianja SQL Server.

wwwroot should be set to C:\lianja\cloudserver\tenants\public\wwwroot\

Remember also that you have the

odata_create(),

odata_read(),

odata_update() and

odata_delete()

functions that can be used in both programs and rsp pages. These functions provide an OData abstraction above the target database SQL syntax. e.g. you can fetch MSSQL data using $limit (see below).

Name:  Screen Shot 2017-01-31 at 10.01.45 AM.jpg Views: 46 Size:  92.5 KB


$format=img, if you select an image field from a table then it will be output as an IMG tag with embedded data encoding so that you can insert this into the DOM to fetch and display an image.

Name:  Screen Shot 2017-01-31 at 10.13.25 AM.jpg Views: 45 Size:  112.4 KB

By specifying memo fields you can also perform CRUD operations on JSON data.


Q:

Is it also possible to use the Lianja oData interface to call a server side function which then returns JSON data?

to allow our non-Lianja clients access to our server side functions.

by including and utilising the LianjaCloudDataServceis.js in our non-lianja clients

A:

Yes. You have several choices.

1. OData calls
2. result = Lianja.evaluate(‘your_proc( args )’); calls on the client with your_proc residing on the server. ( you can also map client-side JavaScript functions by describing them in exports,conf )
3. Retrieve results of a dynamic .rsp page located in the server.


You can also write full rsp pages that return json results fast super fast.


Q:

If I have a stored procedure named sp_testfunction.prg in my SouthWind database, which returns the customers table in json format, how would I call the function using OData?

A:

Normally you would use Lianja.evaluate() from an open app, but to evaluate code from the OData URI with no app open you need to create an app that will be used to contain all of your stored procs for fetching JSON encoded data and execute like this.

Code:
http://localhost:8001/odata?$eval=fetchcustomer()&$app=yourapp

In order to call server side stored procedures in a database I have now recognized databasename! when using $eval in the 3.3 final release (next build):

Code:
// sp_fetchcustomer.prg stored procedure in southwind database
//
// usage: 
//
//    http://localhost:8001/odata?$eval=southwind!sp_fetchcustomer()
//    or
//    http://localhost:8001/odata?$eval=sp_fetchcustomer()&$database=southwind
//
parameter p_custid
if parameters() = 0
    // fetch all customer records
    select * from southwind!customers into cursor mycur
else
    // fetch a specfic customer record
    select * from southwind!customers where customerid = "&p_custid" into cursor mycur
endif
copy to arrayofobjects myobj
// return JSON encoded data to the client
return json_encode(myobj)

Remember that you can test all your stored procs in the “Console” workspace:

Code:
odata_read("/odata?$eval=southwind!sp_fetchcustomer('ALFKI')")

If your data handling procs are in a library you can also make calls like this:

Code:
odata_read("/odata?$eval=mylibrary::fetchcustomer('ALFKI')")

Q:

I created myLibrary.prg containing your fetchCustomer procedure.

When I run odata_read(“/odata?$eval=mylibrary::fetchcustomer(‘ALFKI’)”) from console it works as expected.

However, if I send


http://localhost:8001/odata?$eval=myLibrary::fetchCustomer(%27ALFKI%27)

from a browser I get a 404 error:
The requested URL /odata?$eval=myLibrary::fetchCustomer(%27ALFKI%27) was not found on this server.
A:
Any odata API calls from the browser will reference a deployed library as opposed to the development version. You need to deploy it first.
For performance reasons, the library is opened up only once and kept open which is why you are seeing this behavior. On a heavily loaded system with many concurrent requests occurring this is required so that the library is not opened and parsed for each odata API call.