Previous article "Why not 1C?" came out more than a year ago and aroused quite a keen interest (just a little short of 100k views and 2k comments). However, as expected, many a reasonable question arose: "If not him, then who?" Of course, as many have understood, that article was not written just like that, but in order to release another one after it, where it would be told how the problems described in the first article can and should be solved. However, for various reasons, the release of this "response" article was delayed for a very long time. But as they say, better late than never.
, ( ) lsFusion. , : (function-level, functional), , -, (constraint) . , buzzwords, , , .
« 1?» ( ):
1 , lsFusion.
: , ..
lsFusion , ( lsFusion — ). ( ). , , — , « ». , , :
Since lsFusion tries to make the most of the SQL server and not the application server to execute the calculation logic (and it does this by grouping queries as much as possible to execute them as little as possible), the operation of reading an entire object in lsFusion does not exist in principle. As a consequence, both the N + 1 problem and the over-read problem in lsFusion are extremely rare. For example the following action:
fillSum(Invoice i) {
|
fillSum(Invoice i) {
|
Tables / Views: Registers
lsFusion , «» 1, , , , , « » ( , ), . , lsFusion :
, . lsFusion , , . - :
LEDGER Sales GROUP Stock stock, Sku sku SUM NUMERIC quantity, NUMERIC sum;
|
Registers are supported in very special cases
As mentioned above, registers in lsFusion are not one big combine, but several different mechanisms, the key of which, perhaps, is the materialization mechanism (recording and automatic updating of calculated data into tables).
1, lsFusion , . , lsFusion :
- , , , ( " ").
- / / , .
- , , , “” ( ).
- (), .
lsFusion supports constraints and events in general, including computed non-materialized data. So, for example, to create a constraint that the remainder (which can be calculated using any number of different data / operators) must be greater than 0, it is enough to write just one line:
CONSTRAINT currentBalance(sku, stock) < 0 MESSAGE ' ';
|
Also, in the same way, you can create, for example, notifications about changes of any, including calculated, data:
WHEN SET(currentBalance(Sku sku, Stock stock) < 0) // 0
|
Only constants can be used in virtual table parameters
- lsFusion . , , , , . , , , lsFusion . :
EXPORT FROM price(Sku sku), balance(date(sku), sku) WHERE name(sku) = '';
|
Inquiries
, lsFusion SQL ( ), , . , , .
lsFusion, :
- IDE — , , , ..
- IDE ( ), , .
, / (IF, SHOWIF ..), (EVAL), lsFusion.
LsFusion has a very powerful query optimization engine internally, in many cases performing optimizations that even expensive commercial DBMSs (let alone PostgreSQL) cannot do. So, all the performance problems described in the article "Why not SQL" , lsFusion is able to solve independently without any additional actions on the part of the developer, who, accordingly, can concentrate on solving business problems, and not think about how to write a query correctly and / or in which temporary table to put its result.
So an example from an article about 1C in lsFusion will look like this:
.,
.
..
..(,
(
..
= &))
. = .
. = &
(. < .
. NULL)
currentBalance(InvoiceDetail id) = currentBalance(sku(id));
|
SQL
SQL-92, ( SQL — ), lsFusion :
- / ( SQL — )
- ( SQL — CTE)
- ( SQL — )
lsFusion - ( GROUP BY ).
ERP- ORM , , - , ERP- SQL- .
However, in the same 1C queries are supported only for data read operations; for writing, you still have to use ORM mechanisms, the performance of which leaves much to be desired. In lsFusion, there is no such problem, and all operations, including the creation of objects, can be performed on the database server, and with one request. For instance:
generateCards() {
|
Ultimately, it will be compiled into one request (or several, but their number will not depend on the amount of data) and will be executed very quickly, and all events / constraints / aggregations will also be executed / checked / recalculated by a limited number of requests (again, independent on the amount of data).
The same applies to the mechanism for changing / deleting a large amount of data / objects:
FOR sum(DiscountCard d) > 10000 DO
|
sum(DiscountCard d) ← TRUE WHERE sum(d) > 10000;
|
( ) 1, . :
- ( MS SQL).
- Repeatable Read Serializable.
- , .
- .
lsFusion. , 1 ( ) lsFusion:
- , ( , ),
- , , « ».
lsFusion — , / .
:
Unlike 1C in lsFusion, the execution flow is the same for both the server and the client. This unity greatly simplifies the interaction with the user / client device in terms of the development process. So, the example in the article about 1C is written in the lsFusion language, and, accordingly, looks like this:
f() <- someData(); // myForm
|
, lsFusion ( /). , lsFusion CLIENT INTERNAL, . Java, - — JavaScript. “ ” , .
- ( ) “” ( , , ). (, ), , , 1 ( , async / await, ).
lsFusion , , , , .
WYSIWYG:
, 1 , ( ), 2 :
- - , / ().
- .
1 . lsFusion , , , «Excel-style» , , , , , . ( lsFusion) « » — / . , .
/
In lsFusion, when setting properties, filters and other elements on a form, you can access all objects at once, even if they appear in different lists (or other views). At the same time, the platform itself monitors changes in objects (as well as changes in data) and automatically updates form data using these objects. For example, if you create the following form:
FORM balance
|
Redundant levels of abstraction
The main principle when creating lsFusion was and remains the principle - the purity and completeness of all created abstractions. So:
- lsFusion . — . , .
- ( ) , , , ( ).
:
, lsFusion 1. 1 lsFusion:
- /
lsFusion ( ) . , ( , ..) , «» ( ).
- /
, 1 - lsFusion ( , ).
- /
lsFusion , . - « » lsFusion . , . - , , ( ). lsFusion .
- / / (BI)
. , / lsFusion ( ). , ( , ) lsFusion :
- — , JasperReports, Java. pixel-perfect , .
- — , , , .
- — «» , , « » ( ).
- — , ( ) JSON, XML, XLSX, DBF .
lsFusion — . , , . , , / .
lsFusion , lsFusion , / ( 1). lsFusion — , . , , , ( ). - .
:
- ( BI).
- (, )
- .
PS: « » ( ) « 1?» , , , , . , , .
As mentioned in the previous section, the mapping of data logic in lsFusion to a relational database is transparent and can be completely controlled by the developer. Together with materializations in general and indexes, a developer (and even an administrator) can achieve almost any performance, even on huge amounts of data. Moreover, since the platform itself monitors changes in the physical model and updates the database structure without any additional migrations, the performance optimization process can (and should) be performed on a running database when the statistics and options for using this database are known. So let's say we have a simple example:
date = DATA DATE (DocumentDetail)
|
- JOIN with the product table, the barcode in the SKU table matches the specified one;
- counting the number of document lines for all dates greater than the specified one.
In this case, the SQL server will have two options: either run by the index by dates in the table of rows, or run by the index by barcodes in the table of goods, find goods, and then run by the index by Sku in the table of rows. In both cases, the performance will leave much to be desired (if there are a lot of movements of one product and a lot of products). In lsFusion, to solve this problem, it is enough to change / add the following lines:
barcode(DocumentDetail dd) = barcode(sku(d)) MATERIALIZED; // ,
|
Closed sources and licenses
- . Microsoft, , .Net, Linux.
lsFusion LGPL v3 , , ( ), . GitHub. Maven-, Maven: compile, install, package .. , , GitHub Projects. , .
. lsFusion . , ( ), ( ).
( ), , ( ).
lsFusion , tutorial, , .
lsFusion . ( ), . , ( ) .
, , , , , . :
invoice (InvoiceDetail id) = DATA Invoice;
|
, , - , custom-made . , , . , / «», .
lsFusion . :
- ( , — ) — - . , , , , / .
- — . - - (, ).
- — , ( ). , - ( «» / , ).
- , ( ). , this, , lsFusion , - «».
- — , , - ( )
, , , lsFusion ( ), lsFusion / , .
, «» lsFusion — ( ) , , . ( , ), ( ).
, , Everything as code . lsFusion.
, , lsFusion . , , ( ). lsFusion IDEA : , , , .. -, , .
, , , — 1, ERP-. , , , :
- .
- , , , .
lsFusion : - , - . - , .
. “ - ”. Java . , 1, lsFusion . , , , . , . . , .
, lsFusion — lsFusion ANTLR, IDEA Grammar-Kit (), JFlex ().
UI. - Java SE (Swing, Web Start), , . , , -, - .
- lsFusion :
BI — “” lsFusion “ ”. :
- pivot-table, subtotal — BI, ( ),
- plotly — ,
- tableToExcel — Excel ( , collapsible ..).
, ( , ), open-source, - — .
. lsFusion — JasperReports.
. 1 , , , , :
) , , , 4 ;
) “”, pixel-perfect .
lsFusion : ( renderer’, , . .), . BI ( , . .), ( ).
- IDE. IDE, IDEA (Eclipse ), IDEA . , , IDEA , . IDEA ( IntelliJ Platform) IDE, , lsFusion ( , lsFusion ). stub index’, chameleon element' lsFusion (, , ).
- . Everything as code , , , Git. , Subversion (, , ).
/ . EaC / Java, Maven ( lsFusion repo.lsfusion.org).
Maven- pom.xml :
<repositories> <repository> <id>lsfusion</id> <name>lsFusion Public Repository</name> <url>http://repo.lsfusion.org</url> </repository> </repositories>
, Maven Java . , , Maven , pom.xml.
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-math3</artifactId> <version>3.2</version> </dependency>
IDE, .
. JDBC, / . Postgres ( Docker, yum ..)
Java Spring, .
, lsFusion LGPL v3.0, , , , lsFusion . , lsFusion , , . , lsFusion , , , , / , . -? , «-» , , , — , -. , ( , , «as is», «to be»). , , , «», , :
- — , , . «», — .
- — ,
, lsFusion (- / lsFusion, ), (, , ).
. , ( - ), ( / ). ( IT) , , , ( ). MyCompany. , , , , , , .
, , - — . , . , , , :
- - ( ), , / . .
- , , , ( , , ). , , , , . , 30 3000 , - .
, , . , lsFusion , 1 ERP-.
, « 1», — - 1 lsFusion ( , ). , 1- , .