Mengapa lsFusion dan bukan 1C?





Artikel sebelumnya "Mengapa tidak 1C?" keluar lebih dari setahun yang lalu dan membangkitkan minat yang cukup besar (hanya sedikit kurang dari 100 ribu penayangan dan 2 ribu komentar). Namun, seperti yang diharapkan, banyak pertanyaan yang masuk akal muncul: "Jika bukan dia, lalu siapa?" Tentu saja, seperti yang dipahami banyak orang, artikel itu tidak ditulis begitu saja, tetapi untuk merilis artikel lain setelahnya, di mana akan diceritakan bagaimana masalah yang dijelaskan di artikel pertama dapat dan harus diselesaikan. Namun, karena berbagai alasan, rilis artikel "tanggapan" ini ditunda untuk waktu yang sangat lama. Tapi seperti yang mereka katakan, lebih baik terlambat daripada tidak sama sekali.







, ( ) lsFusion. , : (function-level, functional), , -, (constraint) . , buzzwords, , , .







« 1?» ( ):









1 , lsFusion.







: , ..



lsFusion , ( lsFusion — ). ( ). , , — , « ». , , :







  • , (, - , ), , , - (, / , ). , , «».
  • «» ( lsFusion / ), .




Karena lsFusion mencoba memanfaatkan SQL server dan bukan server aplikasi untuk mengeksekusi logika kalkulasi (dan melakukannya dengan mengelompokkan kueri sebanyak mungkin untuk mengeksekusinya sesedikit mungkin), operasi membaca keseluruhan objek di lsFusion pada prinsipnya tidak ada. Akibatnya, masalah N + 1 dan masalah over-read di lsFusion sangat jarang terjadi. Misalnya tindakan berikut:





fillSum(Invoice i) {

    FOR invoice(InvoiceDetail id) = i DO

        sum(id) <- price(id) * quantity(id);

}





Ini akan dikompilasi dalam satu langkah:

fillSum(Invoice i) {

    sum(InvoiceDetail id) <- price(id) * quantity(id) WHERE invoice(id) = i

}





Yang selanjutnya akan dieksekusi dengan satu query, di mana hanya baris / kolom yang digunakan yang akan dibaca / ditulis.



Tabel / Tampilan: Register



lsFusion , «» 1, , , , , « » ( , ), . , lsFusion :







  • — , (, )
  • / — , , :
    • — GROUP LAST
    • , — SUM ( lsFusion , lsFusion , )


lsFusion , .







, . lsFusion , , . - :





LEDGER Sales GROUP Stock stock, Sku sku SUM NUMERIC quantity, NUMERIC sum;



//    Sales   :

// stock, sku, quantity, sum = ABSTRACT Stock, Sku, NUMERIC, NUMERIC (Sales); - 

  / 

// quantitySales, sumSales (stock, sku) -   ( =   +  )

// quantitySales, sumSales (stock, sku, DATETIME) -    

// quantitySales, sumSales (stock, sku, DATETIME, DATETIME) -     

//  ..





Dan di versi berikutnya, gula sintaksis seperti itu kemungkinan besar akan muncul. Hal lain adalah yang paling sering dalam proyek yang kompleks, register memiliki struktur yang lebih kompleks (misalnya, mereka mewarisi satu sama lain, mendenormalisasi data untuk indeks komposit, memperluas di modul yang berbeda, dan sebagainya), sehingga gula semacam itu dapat menjadi penting hanya untuk Pengembangan RAD (dan lebih tepatnya, prototyping), yang tidak lagi relevan di dunia IT modern.



Register didukung dalam kasus yang sangat khusus



Seperti disebutkan di atas, register di lsFusion bukanlah satu gabungan besar, tetapi beberapa mekanisme berbeda, yang kuncinya, mungkin, adalah mekanisme materialisasi (pencatatan dan pembaruan otomatis data yang dihitung ke dalam tabel).







1, lsFusion , . , lsFusion :







  1. , , , ( " ").
  2. / / , .
  3. , , , “” ( ).
  4. (), .




lsFusion mendukung batasan dan peristiwa secara umum, termasuk data non-material yang dihitung. Jadi, misalnya, untuk membuat batasan bahwa sisanya (yang dapat dihitung menggunakan sejumlah data / operator berbeda) harus lebih besar dari 0, cukup menulis satu baris saja:





CONSTRAINT currentBalance(sku, stock) < 0 MESSAGE '    ';





Karenanya, platform itu sendiri akan seefisien mungkin (menggunakan kalkulasi tambahan) memeriksa bahwa tidak ada perubahan (misalnya, perubahan di gudang tanda terima atau jumlah konsumsi) yang akan melanggar batasan ini.

Selain itu, dengan cara yang sama, Anda dapat membuat, misalnya, pemberitahuan tentang perubahan apa pun, termasuk data yang dihitung:





WHEN SET(currentBalance(Sku sku, Stock stock) < 0//     0

    EMAIL SUBJECT '   ' + address(stock) + '   ' + name(sku) + 

'   0' TO responsibleEmail(group(sku));





Hanya konstanta yang dapat digunakan dalam parameter tabel virtual



- lsFusion . , , , , . , , , lsFusion . :





EXPORT FROM price(Sku sku), balance(date(sku), sku) WHERE name(sku) = '';





Platform akan secara otomatis mendorong kondisi nama pembatas (dan sebagai konsekuensi dari tanggal sisa akan dihitung) ke dalam subkueri (dan semua subkueri di dalam subkueri ini), sehingga melakukan pengoptimalan dorong ke bawah predikat . Selain itu, tidak seperti SQL yang sama, platform mampu melakukan pengoptimalan ini tidak hanya untuk pengelompokan, tetapi juga untuk partisi dan bahkan untuk rekursi. Namun, ini adalah topik untuk artikel terpisah, kami tidak akan membahasnya secara mendetail di sini.



Pertanyaan



, lsFusion SQL ( ), , . , , .









lsFusion, :







  • IDE — , , , ..
  • IDE ( ), , .


, / (IF, SHOWIF ..), (EVAL), lsFusion.









LsFusion memiliki mesin pengoptimalan kueri yang sangat kuat secara internal, dalam banyak kasus melakukan pengoptimalan yang bahkan tidak dapat dilakukan oleh DBMS komersial yang mahal (apalagi PostgreSQL). Jadi, semua masalah kinerja yang dijelaskan dalam artikel "Mengapa bukan SQL" , lsFusion dapat diselesaikan secara mandiri tanpa tindakan tambahan dari pengembang, yang, karenanya, dapat berkonsentrasi pada pemecahan masalah bisnis, dan tidak memikirkan bagaimana caranya tulis kueri dengan benar dan / atau di mana tabel sementara akan meletakkan hasilnya.







Jadi contoh dari artikel tentang 1C di lsFusion akan terlihat seperti ini:







Contoh dari artikel

    .,
    .

    ..  
          ..(,
                               (
                                    
                                    ..
                                     = &))  
         . = .

    . = & 
    (. < . 
        .  NULL)
      
      



currentBalance(InvoiceDetail id) = currentBalance(sku(id));



export(Invoice i) {

    EXPORT FROM sku(InvoiceDetail id), currentBalance(id) WHERE invoice(id) = i AND 

currentBalance(id) < quantity(id) OR NOT currentBalance(id);

}





Karenanya, tidak ada "Nomenclature IN (SELECT Nomenclature FROM Document.Invoice.Content WHERE Reference = & Document)" di lsFusion tidak perlu ditulis.



SQL



SQL-92, ( SQL — ), lsFusion :







  • / ( SQL — )
  • ( SQL — CTE)
  • ( SQL — )


lsFusion - ( GROUP BY ).









ERP- ORM , , - , ERP- SQL- .







Namun, dalam 1C yang sama, kueri hanya didukung untuk operasi pembacaan data; untuk menulis, Anda masih harus menggunakan mekanisme ORM, yang performanya masih banyak yang diinginkan. Dalam lsFusion, tidak ada masalah seperti itu, dan semua operasi, termasuk pembuatan objek, dapat dilakukan di server database, dan dengan satu permintaan. Contohnya:





generateCards() {

    FOR iterate(i,1,10000NEW d = DiscountCard DO

            number(d) ← ‘Card:’+i;

}







Pada akhirnya, itu akan dikompilasi menjadi satu permintaan (atau beberapa, tetapi jumlahnya tidak akan bergantung pada jumlah data) dan akan dieksekusi dengan sangat cepat, dan semua peristiwa / kendala / agregasi juga akan dieksekusi / diperiksa / dihitung ulang oleh terbatas jumlah permintaan (sekali lagi, tergantung pada jumlah data).

Hal yang sama berlaku untuk mekanisme mengubah / menghapus sejumlah besar data / objek:





FOR sum(DiscountCard d) > 10000 DO

    vip (d) ← TRUE;

FOR sum(DiscountCard d) > 10000 DO

    DELETE d;





Akan dikompilasi ke:

sum(DiscountCard d) ← TRUE  WHERE sum(d) > 10000;

DELETE DiscountCard d WHERE sum(d) > 10000;





Dan lagi, itu akan dieksekusi dalam satu permintaan.





( ) 1, . :







  1. ( MS SQL).
  2. Repeatable Read Serializable.
  3. , .
  4. .


lsFusion. , 1 ( ) lsFusion:







  • , ( , ),
  • , , « ».




lsFusion — , / .







:



Tidak seperti 1C di lsFusion, aliran eksekusi sama untuk server dan klien. Kesatuan ini sangat menyederhanakan interaksi dengan perangkat pengguna / klien dalam hal proses pengembangan. Jadi, contoh di artikel tentang 1C ditulis dalam bahasa lsFusion, dan karenanya, terlihat seperti ini:





f() <- someData(); //       myForm

DIALOG myForm OBJECTS a INPUT DO // , 

 - 

     IF isSomething(a) DO //          - 

 

         DIALOG otherForm OBJECTS b = a DO { // ,  

       b

             g(b) <- someInput(b); //    b

             APPLY//    

         }





Sampai batas tertentu, lsFusion menggunakan pendekatan bentuk konvensional dalam 1C, hanya saja ini membuatnya lebih dapat diskalakan dan produktif. Faktanya, semua keajaiban asynchrony tetap ada di bawah tenda, dan pengembang dapat berkonsentrasi secara ketat pada penyelesaian masalah bisnis, dan tidak memikirkan di mana dan bagaimana kode yang dia tulis harus dijalankan.

, lsFusion ( /). , lsFusion CLIENT INTERNAL, . Java, - — JavaScript. “ ” , .









- ( ) “” ( , , ). (, ), , , 1 ( , async / await, ).







lsFusion , , , , .







WYSIWYG:



, 1 , ( ), 2 :







  • - , / ().
  • .


1 . lsFusion , , , «Excel-style» , , , , , . ( lsFusion) « » — / . , .







/



Di lsFusion, saat mengatur properti, filter, dan elemen lain pada formulir, Anda bisa mengakses semua objek sekaligus, meskipun objek tersebut muncul di daftar yang berbeda (atau tampilan lain). Pada saat yang sama, platform itu sendiri memantau perubahan dalam objek (serta perubahan data) dan secara otomatis memperbarui data formulir menggunakan objek ini. Misalnya, jika Anda membuat formulir berikut ini:





FORM balance

    OBJECTS st = Stock, sk = Sku

    PROPERTIES (st) name

    PROPERTIES name(sk), currentBalance(st, sk)

    FILTERS currentBalance(st, sk)

;





Saat Anda memindahkan rekaman saat ini di daftar atas (gudang), daftar bawah (produk yang ada di gudang yang dipilih) akan diperbarui secara otomatis.



Tingkat abstraksi yang berlebihan



Prinsip utama saat membuat lsFusion adalah dan tetap menjadi prinsip - kemurnian dan kelengkapan semua abstraksi yang dibuat. Begitu:







  • 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 — , . , , , ( ). - .







:







  1. ( BI).
  2. (, )
  3. .




PS: « » ( ) « 1?» , , , , . , , .







Seperti yang disebutkan di bagian sebelumnya, pemetaan logika data di lsFusion ke database relasional transparan dan dapat dikontrol sepenuhnya oleh pengembang. Bersama dengan perwujudan secara umum dan indeks, pengembang (dan bahkan administrator) dapat mencapai hampir semua kinerja, bahkan pada data dalam jumlah besar. Selain itu, karena platform itu sendiri memantau perubahan dalam model fisik dan memperbarui struktur database tanpa migrasi tambahan, proses pengoptimalan kinerja dapat (dan harus) dilakukan pada database yang sedang berjalan ketika statistik dan opsi untuk menggunakan database ini diketahui. Jadi katakanlah kita memiliki contoh sederhana:





date = DATA DATE (DocumentDetail)

barcode = DATA STRING (Sku);

sku = DATA Sku (DocumentDetail); 



barcode(DocumentDetail dd) = barcode(sku(dd));

count (STRING bc, DATE d) = GROUP SUM 1 IF date(DocumentDetail dd) > d AND barcode(dd) = bc;

FORM x

        OBJECTS bc = STRING PANEL, d = DATE PANEL

        PROPERTIES count(bc, d), VALUE (bc), VALUE(d)

;





Saat menjalankan formulir ini, permintaan akan dibuat di mana itu akan menjadi:

  1. GABUNG dengan tabel produk, barcode di tabel SKU cocok dengan yang ditentukan;
  2. menghitung jumlah baris dokumen untuk semua tanggal yang lebih besar dari yang ditentukan.


Dalam hal ini, server SQL akan memiliki dua opsi: dijalankan oleh indeks berdasarkan tanggal di tabel baris, atau dengan indeks dengan kode batang di tabel barang, temukan barang, dan kemudian dijalankan oleh indeks oleh Sku di tabel baris. Dalam kedua kasus tersebut, kinerja akan meninggalkan banyak hal yang diinginkan (jika ada banyak pergerakan dari satu produk dan banyak produk). Di lsFusion, untuk mengatasi masalah ini, cukup dengan mengubah / menambahkan baris berikut:





barcode(DocumentDetail dd) = barcode(sku(d)) MATERIALIZED// ,  

   

INDEX barcode(DocumentDetail dd), date(dd);//   





Setelah pengoptimalan tersebut, server SQL akan dapat mulai menggunakan indeks komposit yang dibangun dan kinerjanya akan maksimal.



Sumber dan lisensi tertutup



- . Microsoft, , .Net, Linux.







, , — ERP-, , : — . , .







lsFusion LGPL v3 , , ( ), . GitHub. Maven-, Maven: compile, install, package .. , , GitHub Projects. , .









. lsFusion . , ( ), ( ).







( ), , ( ).







lsFusion , tutorial, , .









lsFusion . ( ), . , ( ) .







, , , , , . :





invoice (InvoiceDetail id) = DATA Invoice;

sum = GROUP SUM sum(InvoiceDetail id) BY invoice(id) //  sum   

  Invoice (    invoce,    - Invoice)



FORM myForm

    OBJECTS myObject = MyClass

;

filtered = FILTER myForm.myObject ; //  filtered      

MyClass (    myObject  myForm)









, , - , custom-made . , , . , / «», .







lsFusion . :







  1. ( , — ) — - . , , , , / .
  2. — . - - (, ).
  3. — , ( ). , - ( «» / , ).
  4. , ( ). , this, , lsFusion , - «».
  5. — , , - ( )


, , , lsFusion ( ), lsFusion / , .







, «» lsFusion — ( ) , , . ( , ), ( ).









, , Everything as code . lsFusion.







, , lsFusion . , , ( ). lsFusion IDEA : , , , .. -, , .









, , , — 1, ERP-. , , , :







  1. .
  2. , , , .


lsFusion : - , - . - , .







, lsFusion:
  1. . “ - ”. Java . , 1, lsFusion . , , , . , . . , .







    , lsFusion — lsFusion ANTLR, IDEA Grammar-Kit (), JFlex ().





  2. UI. - Java SE (Swing, Web Start), , . , , -, - .







    - lsFusion :





    • GWT — Java (), . , , , , GWT , . GWT JavaScript, JavaScript







      , GWT , TypeScript . :







      ) - TypeScript - ;







      ) lsFusion GWT , , .







      - TypeScript, , .





    • Full Calendar, Leaflet — “” ( ).
    • Spring Security, MVC, DI — , , (, ).
  3. BI — “” lsFusion “ ”. :





    • pivot-table, subtotal — BI, ( ),
    • plotly — ,
    • tableToExcel — Excel ( , collapsible ..).


    , ( , ), open-source, - — .





  4. . lsFusion — JasperReports.







    . 1 , , , , :







    ) , , , 4 ;







    ) “”, pixel-perfect .







    lsFusion : ( renderer’, , . .), . BI ( , . .), ( ).





  5. IDE. IDE, IDEA (Eclipse ), IDEA . , , IDEA , . IDEA ( IntelliJ Platform) IDE, , lsFusion ( , lsFusion ). stub index’, chameleon element' lsFusion (, , ).
  6. . Everything as code , , , Git. , Subversion (, , ).
  7. / . 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, .





  8. . JDBC, / . Postgres ( Docker, yum ..)







    Java Spring, .











, lsFusion LGPL v3.0, , , , lsFusion . , lsFusion , , . , lsFusion , , , , / , . -? , «-» , , , — , -. , ( , , «as is», «to be»). , , , «», , :







  • — , , . «», — .
  • ,


, lsFusion (- / lsFusion, ), (, , ).







, , . , , / , , , .







. , ( - ), ( / ). ( IT) , , , ( ). MyCompany. , , , , , , .









, , - — . , . , , , :







  1. - ( ), , / . .
  2. , , , ( , , ). , , , , . , 30 3000 , - .


, , . , lsFusion , 1 ERP-.







, :

«» ( )



( , ) , / .









( ), , , - . . . .







( Google docs)



, ( , , , ).









, ( ). , .









1, , . ( ), , , , , ( ). , :







  1. , .
  2. , , , « » ( , ).


/



:







  • — , drag-drop .
  • — WYSIWYG , - ( ).
  • — > ( -> , ).
  • , — ( )


, ( -).







/



1 :







  • — , (, , Odoo lsFusion)
  • — renderer, / , , , «» js- ( , ).


( )



, :







  • ( )
  • ( / )
  • ..


1 «-» , 1 / , , .









, « 1», — - 1 lsFusion ( , ). , 1- , .










All Articles