Tic-Tac-Toe Angular PWA alkalmazás reprodukálása videó alapján
Címkék: PWA Angular Frontend Javascrip
2023.11.29. 12:23
Egy ideje látom, hogy nyitnom kell frontend irányba.
Az Angulart választottam a koherenssége miatt. Tudom mások pont ezt hozzák ellenérvként.
Képbe került olyan feladat, hogy hordozható készülékről kell intézni a fixen telepített számítógépes rendszer funkcióinak egy részét. Így kerül képbe a Progressive Web Application (PWA).
Kinéztem egy
A videó 20 perces, gondoltam egy nap alatt “megeszem”. Hát nem! Úgy öt nap lett belőle.
A videó négy éve készült azóta verziók változtak, plugin alakult át, inkompatibilitások keletkeztek. Persze az is közrejátszott, hogy Angular téren is kezdő vagyok.
Telepítettem, amit kellett Node Package Manager-t (NPM), Angular command-line interface-t (NG CLI). Visual Studio Code ide már volt.
Win10-en az NG futtatását engedélyezni kellett.
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Ez viszonylag megengedő. Aki paranoiás beállíthat szigorúbbat.
A videó által javasolt `Angular console` már nem létezik átalakult `Nx console`-á. Persze a kezelése is lényegesen eltér a videóban láthatótól.
A `square` komponens ugyan létrejött, de a `app.component.html`-ben a vscode nem ajánlotta fel és a fordítás is sikertelen volt. Biztos nálam van a hiba, figyelmetlen voltam, vagy a megváltozott NX konzolban rosszul paramétereztem. Jó pár kísérlet után rákerestem a Google-ben.
Az Angular 17-es verziója bugos (lehet szándékos a változás?). Minden esetre 2023 november közepén a létrehozott projektben nem keletkezett az `app.module.ts` állományt. Ami a például a komponenseket is láthatóvá teszi a sablonokban (template HTML).
Sajnos nem jegyzeteltem mindent. Így nem emlékszem pontosan, hogy `Nebular` kontroll készlet inkompatibilitása hogyan bukott ki. Minden esetre a Nebular fejlesztése egy ideje megszűnt, csak régebbi Angular verzióval használható.
Nos, itt adtam fel a videó szó szerinti követését előröl kezdtem a projektet NX console és Nebular nélkül. Kontroll készlet gyanánt a `@angular/material`-t használtam. Ami közel sem olyan látványos, viszont kompatibilis és működik.
A videó lépéseit, logikáját követtem, de az alábbi parancsokkal operáltam.
ng new Tic-Tac-Toe --no-standalone
cd .\Tic-Tac-Toe
ng serve //(1)
ng build --configuration=production
ng g c square -t -s
ng g c board
ng add @angular/material
ng add @angular/pwa
ng build --configuration=production --aot=true
ng serve --configuration=production
npm i inquirer-autocomplete-prompt@2 //(2)
npm install -g firebase-tools
firebase login
ng add @angular/fire
firebase experiments:enable webframeworks
firebase deploy --only hosting:tic-tac-toe-6b23b
(1) a vsCodeban a Tic-Tac-Toe folderben kiadva
(2) a friss verzió nem volt kompatibilis a firebase-hez
Mint látható, a Firebase telepítése sem volt zökkenő mentes, elakadt hibával. A telepítés paramétereinek beolvasását intéző plugin “túl friss” volt. A `inquirer-autocomplete-promp`-ból régebbi verzióra volt szükség.
A `firebase login` persze feltételezi, hogy legyen Firebase fiók. Mintha a projektet is létre kellet volna hozni a login előtt.
Az eredményt egy ideig elérhető lesz
. Mivel PWA, telepíthető is. Windows alatt Chrome böngészőből. Androidon szintén Chrome-t használtam. Ismerős telepítette iPhone-ra, szintén Chrome-t használva. Iphone-on a jobb szélső gombok kilógnak a játékmezőből. Ez némi css munkát igényelne, de itt a telepíthetőség volt az elsődleges szempont.A forrás elérhető a
.Azért piszkált a dolog. Megigazítottam, hogy iPhonon is "rendesen" nézzen ki.
A mat-disabled-button lógott ki a grid-template-columns-al definiált 3x3-as játéktér celláiból. Ennek okára nem jöttem rá. Nem értek ehhez a kontroll készlethez. Mint korábban említettem az elfogadható kinézet mellet a "kvázi" alkalmazásként való telepíthetőség volt a cél.
Megkérdezem barátomat...
Címkék: artificial intelligence mesterséges értelem Google AI Chat GPT
2023.03.28. 09:38
Eddig akkor kezdtem így mondandómat, ha a Google keresőt kívántam használni informálódásra.
Kedves ismerősöm lelkesen ecsetelte a Chat GPT használatával szerzett tapasztalatait. Eddig elriasztott, hogy a kipróbáláshoz is fiókot kell létrehozni. Most akadt egy téma, amit úgy is gondoltam "megkutatni". Hát legyen...
Gyakran programtechnikai kérdéseimre keresem a választ a neteten.
Most is ebbe az irányba indultam.
Első menetben olyat kérdeztem Java / Hibernate témában, amire ismertem a választ. Elsőre nem voltam elég pontos, ezért általánosabb választ kaptam. A kapott kódot átnézve azt szakmailag megfelelőnek találtam. Pontosítás után azt a példakódot kaptam, amit vártam.
Másodszorra feltettem valós, "withe label" eszköz okosotthon-rendszerhez illesztésre vonatkozó kérdésemet. A kapott válasz az addig ismertekbe illeszkedett, de kissé általános volt, kódot nem tartalmazott. "Szemtelenül" megkérdeztem, kaphatok-e példaprogramot. Persze volt a válasz és jött a kód. A megoldás jónak tűnik, de csak része a teljes feladatnak. Ez a projekt az információ gyűjtés állapotában van, ezért a kód gyakorlati értékét csak a felhasználás során fogom megtudni.
Úgy látom, új "barátra" tetem szert. Használni is fogom. Jelentős időmegtakarítás lenne, ha a Google találatok közül nem kellene szemezgetnem. Amennyiben a Chat GPT-től kapott válasz nem fog tetszeni, még mindig ott a "régi barátom".
Go OOP?
Címkék: oop go procedural golang procedúrális objektum orientált object oriented
2023.03.10. 11:43
A Go egy procedurális nyelv, nem objektum orientált.
És még is találtam több az alábbihoz hasonló megoldást.
package main
import (
"io"
"os"
"strings"
)type rot13Reader struct {
r io.Reader
}func (rd *rot13Reader) Read(b []byte) (n int, e error) {
n, e = rd.r.Read(b)
for i := 0; i < len(b); i++ {
c := b[i]
if (c >= 'a' && c <= 'm') || (c >= 'A' && c <= 'M') {
b[i] += 13
} else if (c >= 'n' && c <= 'z') || (c >= 'N' && c <= 'Z') {
b[i] -= 13
}
}
return
}func main() {
s := strings.NewReader("Lbh penpxrq gur pbqr!")
r := rot13Reader{s}
io.Copy(os.Stdout, &r)
}
Gyakran alkalmaznak ehhez hasonló megoldást a egység-tesztek során.
A Go-ban létezik a funkció
func function_name(Parameter-list)(Return_type){
// function body.....
}
és a metódus.
func (reciver_name Type) method_name(parameter_list)(return_type){
// method boby
}
Látható a különbség a reciver a fogadó. Azt olvasom itt: "A method in Golang is like a function that needs a receiver to get invoked. In simple words, a method is a function that is defined on struct types." Vagy is a funkció a reciver entitáson kerül végrehajtásra.
Hogy is van ez, a metódus a fogadó objektumon van értelmezve?
Nézzük a fenti példát. A rot13Reader struktúra rendelkezik az r egy az io:reader interfészt kielégítő objektum memeberrel. (Egy procedurális nyelvben valami kielégít egy interfészt?) A definált Read metodus fogadója egy rot13Reader típusú objektum. A metódus első tevékenysége, hogy meghívja az r field(?) Read (figyelem) metódusát. Majd a kapott eredményt átdolgozza.
Az én értelmezésemben ez az io.Reader read metódusának felülbírálása (override).
Akkor a Go használható objektum orientált szemléletben?
A Java is használható procedurálisan, static metódusok main metódusból való hívogatásával. A Java esetén érzem, hogy ez erőltetett. Nem is nagyon található ilyen érdemi példa. Míg a Go esetén lépten-nyomon látok az objektum orientáltságra hajazó megoldást.
Go tesztelés; Ginkgo — Gomega páros
Címkék: kód programozás fejlesztés go Ginkgo TDD golang Gomega BDD
2023.02.07. 10:40
Go teszt-lefedettség vizsgálat
Címkék: go lefedettség coverage Visual Studio Code golang VSCode teszt-lefedettség test coverage
2023.01.12. 13:50
A Go-ban elmélyedve persze keresem a TDD lehetőségeket.
A Go rendelkezik beépített unit teszt lehetőséggel. A JAVA-ban megszokott JUnit csomaghoz képest nehézkesnek érzem. Persze a JUnit plugin. A Go esetén is megtaláltam a Testify csomagot. Amelytől kezd a dolog hasonlítani a megszokotthoz. A Testify-ről még nem tudok eleget. Gondolom egy későbbi posztban előkerül.
Amit már kitapasztaltam, hogy az alap teszt készlet már tartalmazza a teszt-lefedettség vizsgálatot.
A `go test -cover` parancsot kiadva a tesztek végrehajtásán túl a teszt-lefedettség százaléka is megjelenítésre kerül.
Részletes információ két lépésben állítható elő. Először a
`go test -v -coverprofile cover.out ./YOUR_CODE_FOLDER/.` paranccsal egy leíró fájlt kell előállítani.
A `go tool cover -html cover.out -o cover.html` paranccsal a böngészőben jelenik meg a forrás "kiszínezve". Így sor pontossággal látható mire kell még teszt írni.
A Visual Studio Code (VSCode) képes elvégezni a lefedettség vizsgálatot és megjeleníteni eredményét. Bekapcsolni a `Ctrl+Shift+p` kombináció hatására megjelenő választékból a `Go: Toggle Test Coverage in Current Package` lehetőséget kiválasztva lehet.
A kód érintett sorait erőteljesen aláfesti zölddel illetve pirossal. Szerintem rontja a kód olvashatóságát. Úgy tűnik más is így van ezzel mert találtam olyan beállítást amely a sorszámok mellett függőleges, színes sávokat használ a jelöléshez.
A Beállításhoz be kell lépni a paraméter beállításba és beilleszteni a szükséges paramétereket.
`Ctrl+Shift+p` után `Prefferences: Open User Settings (JSON)` kiválasztva jutunk a JSON szintaktikájú paraméter szerkesztőbe. Ide kell a záró kapcsos zárójel elé beilleszteni az alábbit:
"go.coverOnSave": true,
"go.coverageDecorator": {
"type": "gutter",
"coveredHighlightColor": "rgba(64,128,128,0.5)",
"uncoveredHighlightColor": "rgba(128,64,64,0.25)",
"coveredGutterStyle": "blockgreen",
"uncoveredGutterStyle": "blockred"
},
"go.coverOnSingleTest": true
A beillesztés előtt, a zárójelet korábban megelőző, sor végére vessző kerül.
A beállítás leírása
Go modul struktúra és a VSCode; a Go work szolgáltatás használata
Címkék: programozás go golang go work VSCode
2023.01.12. 11:13
Felmerült, hogy Go nyelven fejlesszek. Ezért tanulmányozni kezdtem a nyelvet.
Amit feltétlenül tudni érdemes a Go nyelvről, hogy szigorúan típusos, procedurális, fordított nyelv. Sajátos tömör szintaktikával rendelkezik. Az előálló futtatható állomány környezet specifikus és "önjáró". Vagyis a Windows környezetben készült eredmény egy exe és minden függő modul ebben van benne.
Valamikor a pályafutásom elején sokat használtam a Clipper nyelvet. Mily érdekes a hasonlóság. Mennyire szerettem volna ha a Clipper típusos.
A webes keresésekkor ajánlatos a Go helyett Golang kifejezéssel keresni.
Alábbi megállapításaim a még nem kellő mélységű ismereteimen, de gyakorlati megfigyeléseimen alapulnak.
A Go alapegysége a modul. Én ezt szeretném projektként értelmezni, hogy be tudjam illeszteni eddigi ismereteimbe.
A modul alapértelmezetten a felhasználói mappában "lakik" a saját mappájában. De ez nem kötelező. A Go workspace tetszőleges helyen lehet, csak a ` ` környezeti változónak oda kell mutatni. Amennyire meg tudom állapítani, a mappa nevének a modul nevét kell viselnie. A modul mappájának van ajánlott szerkezete, bene ajánlott almappákkal. Az eddig látott példákban ennek használatát nem tatasztalom. A gyakorlat szerint a csomagoknak (package) van saját almappája.
A modul mappájában meg kell hogy legyen a `go.mod` állomány, amelyet az inicializáló parancs hoz létre. Szokásos még a `main.go` állomány ami a belépési pontot tartalmazza. Tapasztalatom szerint az állomány neve nem kötelező, de kötelezően a `main` csomagban kell legyen és definiálnia kell a `main` funkciót.
Fejlesztői környezetből nem látszik nagy választék. A Go oldalán a Jet Brains féle InteliJ változat, a Visual Studio Code (VSCode) és kissé meglepő módon a Vim található. A webes példákban gyakran a VSCode-t használják.
Mivel nálam a VSCode telepítve van és ha nem is túl gyakran, de használom. Ezt választottam.
Maga a Go "eltűri", hogy egy gyűjtő (workspace) mappában több, a fenti szerinti, modul (projekt) mappa legyen. Viszont a VSCode nem szereti ha a workspace mappában több `go.mod` állományt tartalmazó almappa van. Nem találja meg a másik package-ben található funkciókat és más hasonló "nyűgjei" vannak.
Szerencsére az verziótól lehetőség van a `go work` használatára.
A workspace mappában állva kell a parancsokat kiadni. Először inicializálni kell a szolgáltatást a ` ` paranccsal. Ezt követően lehet `
“Refactoring - Kódjavítás újratervezéssel"
Címkék: kód programozás fejlesztés refactoring Java TDD code kata refaktor többalakúság refaktorálás kódjavítás újratervezéssel
2022.12.29. 11:40
Szívesen nézek magyar nyelvű előadásokat érdekes témákról. Mégis a magyarom a legerősebb. Az alapozó előadásokat jobban megértem magyarul.Így futottam bele a refaktorálásról szólóba:
A könyv szerkezete szokatlan. Az alapozó ismeretek bemutatása helyett egy példával kezdődik. Ugyan ez a példa, nem definiáltam kata, de a lépésenkénti magyarázatok és a beillesztett kódok miatt követhető, végrehajtható úgy ahogyan az a katáknál szokásos.Végig is csináltam.
Gilded Rose kata
Címkék: fejlesztés gyakorlat Java polymorphism code kata gildedrose többalakúság Gilded Rose
2022.12.21. 16:10
Replace Conditional with Polymorphism refaktorálás
Címkék: fejlesztés gyakorlat refactoring TDD polymorphism többalakúság refaktorálás
2022.12.21. 14:57
“Lift up conditional” refaktorálás
Címkék: programozás fejlesztés Eclipse code kata gildedrose refaktor refactor
2022.12.20. 11:45
A
Egy teszt eset futtatása, debuggolása Eclipse-ben
Címkék: debug programozás fejlesztés hibakeresés futtatás Eclipse TDD
2022.12.15. 14:26
Mint láthatjátok mostanában sokat foglalkozom TDD-vel.
Kezdetben minden ellenőrzéskor lefuttattam az összes tesztet. A kódolási gyakorlatokról készült videókban azt látom, hogy amíg az aktuálisan fejlesztett teszteset nem lesz elfogadott (zöld) addig nem futtatják az összes tesztet, csak utána. Az IntelliJ esetén a margón van erre ikon. Eclipse-ben nem találtam ehhez plugint sem. Ellenben találtam hot-key-t.
Lift kata
Címkék: kód programozás fejlesztés gyakorlat Java TDD code kata Lift kata
2022.12.15. 14:03
Fizz Buzz kata
Címkék: programozás fejlesztés gyakorlat Java TDD code kata fizz buzz
2022.12.08. 16:06
Ez egy rövidke kata.
Christmass Lights kata
Címkék: kód programozás fejlesztés gyakorlat Java TDD code kata christmass lights
2022.12.08. 10:14
Az Eclipse-ben mint a legtöbb IDE-ben van lehetőség fejlesztést könnyítő kód minták (templates) gyors beillesztésére.
Mint tapasztalhatjátok, mostanában sok tesztet írok. A neten fellelhető tanácsok hatására rászoktam az AssertJ könyvtár használatára. Számomra sokkal olvashatóbb ez a szintaxis. A mit, mivel hasonlítunk össze szemléletesebb.
Az Eclipse-ben van template a JUnit V5-höz, de az AssertJ-t nem ismeri.
Tehát nálam a teszt eset template így néz ki:
@${testType:newType(org.junit.jupiter.api.Test)}
public void test${name}() throws Exception {
${staticImport:importStatic('org.assertj.core.api.Assertions.*')}
assertThat().isEqualTo();
}
Az AssertJ is tud egy teszt esetben több elvárást kiértékelni, de ezeket össze kell fogni egy SoftAssertions-ba. Ekkor a template ilyen:
@${testType:newType(org.junit.jupiter.api.Test)}
public void test${name}() throws Exception {
${Import:import('org.assertj.core.api.SoftAssertions')}
SoftAssertions assertions = new SoftAssertions();
assertions.assertThat().isEqualTo();
assertions.assertThat().isNotEqualTo();
assertions.assertAll();
}
AssertThat ellenőrzésből is lehet több egy tesztesetben, de az első hibánál leáll a folyamat és a többi feltétel nem értékelődik ki.
SoftAssertions használatakor az összes feltétel kiértékelődik. Ciklusban használva vigyázni kell, mert 10-20 kiértékelési lépés után jelentősen lassul.
Roman Numerals Kata
Címkék: kód programozás fejlesztés gyakorlat Java TDD code kata Roman Numerals
2022.12.07. 10:13
Bowling game code kata
Címkék: kód programozás fejlesztés gyakorlat Java TDD code kata Bowling game
2022.12.06. 13:36
Mint ígértem tegnapi élményeim...
JSON numerikus felsorolás perzisztálása
Címkék: Java SQL Hibernate JPA Numerikus lista
2022.11.14. 11:45
A JAVA fejlesztés terén egyre nagyobb szerepet kapnak a támogató eszközök. Többek között az ORM.. JAVA esetén leginkább a JPA, a Hibernate, és a Spring Data bűvös neveket lehet hallani. Persze ezek részben átfedésben vannak.
Évekkel ezelőtt tanácsot kértünk kollégánk, akkor már egy neves cégnél dolgozó gyermekétől, hogy adattárolás (perzisztencia) terén milyen irányba induljunk tovább. Felvetettük a Hibernate használatát. Azt a választ kaptuk, hogy egyes esetekben nehézkes a használata. Nehezen lehet elérni, hogy a Hibernate megértse mit szeretnénk tőle. Sajnos akkor nem tudakoltuk meg mibe is futottak bele.
Most magam is belefutottam olyan problémába, amely eszembe juttatta az esetet. Bizonyára az elmúlt idő is hozott fejlődést, de az elsőre problémás feladatot is sikerült megoldani.
A feladat a következő. JSON struktúrát kell feldolgozni. A struktúra tartalmaz egy numerikus adatok felsorolását tartalmazó nodot. Másként fogalmazva numerikus adatok tömbjét tartalmazza. Kikötés. hogy ezen lista sorrendjét meg kell tartani.
Magától értetődőnek tűnt, hogy master - details (one to many) megközelítést alkalmazzak. A master entitásban létrehoztam egy List<Long> típusú membert. Erre helyeztem el a megfelelő annotációkat.Persze a megfelelő details entitást is létrehoztam. Az autó konfiguráció kiakadt nem tudta felépíteni a konstrukciót. Nem értettem meg a probléma okát. Néztem a neten, látszólag jól csináltam. Persze nem, de erről kicsit később.
Megnéztem, volna e más megoldás. Akad az @ElementCollection használata. Az @ElementCollection által létrehozott details tábla, alapesetben, csak a master idegenkulcsát és az értéket tartalmazza, sorrendi információt nem. Mint tudható SQL esetén a rendezetlen select sorrendje esetleges.
Két módon hidalható át a probléma. A JSON parselolását meg kell támogatni map-á alakítással, és a master struktúrában Map<Integer, Long> membert kell használni.
@JsonDeserialize(using = ListToHashtableDeserializer.class)
@ElementCollection
@CollectionTable(name = "SERIES_DATA", joinColumns = @JoinColumn(name = "SERIES_ID"))
@MapKeyColumn(name = "DATA_ID")
@Column(name = "VALUE")
Map<Integer, Long> series;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;public class ListToHashtableDeserializer extends JsonDeserializer<LinkedHashMap<Integer, Long>> {
@Override
public LinkedHashMap<Integer, Long> deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException, JacksonException {
ObjectCodec codec = parser.getCodec();
JsonNode node = codec.readTree(parser);
Iterator<JsonNode> subNodesIterator = node.elements();
LinkedHashMap<Integer, Long> result = new LinkedHashMap<>();
int index = 0;
while (subNodesIterator.hasNext()) {
JsonNode innerNode = subNodesIterator.next();
Long data = innerNode.asLong();
result.put(index, data);
index += 1;
}
return result;
}
}
Vagy a List<Long> megtartása mellett a @OrderColumn használatával. Na ez elegáns és a kívánt eredményre vezet.
@ElementCollection
@CollectionTable(name = "SERIES_DATA", joinColumns = @JoinColumn(name = "SERIES_ID"))
@OrderColumn
List<Long> series;
Persze az élet nem áll meg. Kiderült, hogy az adattételekhez kapcsoltan további információ tárolására lesz szükség, ezért vissza kellett térni a one to many megoldásra.
Feltűnt, hogy az összes példa saját objektumot használ listaelemként. Így már gyanús lett és meg is találtam a kulcs mondatot. A details entitás osztálynak rendelkeznie kell paraméter nélküli konstruktorral.
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name="series_id", nullable = false)
TimeSeries timeSeries;
...
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "data_id")
private Long id;@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name="series_id", nullable = false)
TimeSeries timeSeries;
...
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.reg.time_series.entity.SeriesData;public class ListToSeriesDataDeserializer extends JsonDeserializer<List<SeriesData>> {
@Override
public List<SeriesData> deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException, JacksonException {
ObjectCodec codec = parser.getCodec();
JsonNode node = codec.readTree(parser);
Iterator<JsonNode> subNodesIterator = node.elements();
List<SeriesData> result = new ArrayList<>();
int index = 0;
while (subNodesIterator.hasNext()) {
JsonNode innerNode = subNodesIterator.next();
Long data = innerNode.asLong();
SeriesData SeriesData = new SeriesData(index, data);
result.add(SeriesData);
index += 1;
}
return result;
}
}
SQL; minden azonosítóhoz a legfrissebb bejegyzés lekérdezése
Címkék: legfrissebb query SQL
2018.09.18. 10:47
Mostanában gyakrabban kell SQL lekérdezést gyártanom.
A feladat: a táblából szükségem lenne olyan listára amelyben minden ID-hoz csak a legfrissebb sor szerepel. Jó lenne nem használni olyan kifejezést, ami a hordozhatóságot korlátozza.
Hosszas kísérletezés a distinct, group by, join kombinációkkal. közben goolizás...
Nem igaz, hogy ez senki másnak nem kell! Végre sikerül jól feltenni a kérdést.
A https://stackoverflow.com/questions/3491329/group-by-with-maxdate oldalon olyan választ találtam ami iránymutató volt.
Íme a query:
SELECT k1.*
FROM kezeles_fej k1
LEFT JOIN kezeles_fej k2 ON (k1.vendeg_id = k2.vendeg_id AND k1.datum < k2.datum)
WHERE k2.datum IS null
GROUP BY k1.VENDEG_ID ORDER BY k1.VENDEG_ID;
Szükségem volt a Win 8.1 oprendszerű gépem MAC címére.
Némi googlizás után az alábbi konzol paranccsal megszerezhető:
getmac /v /fo list
Például hiba kereséssel!
Egy régóta üzemelő Yii2 keretrendszerben fejlesztett honlap néhány hónapja átköltözött új szolgáltatóhoz. Akkor be is lőttük. A mindennapos funkciók hamar tesztelődtek. Azóta nem kellett hozzányúlni.
Most érkezett jelzés, a jegyzőkönyv feltöltés egy ideje üzenettel elutasításra kerül.
Mire is emlékszem...
A hírekre előadásokra teljes szöveges (full-text) keresés lehetséges. Talán az utasítja el a feltöltést.
Fejlesztéskor kellet foglalkozni azzal, hogy nem minden forrásból származó pdf-et "evett meg" a parserolás+indexelés. Biztosan az üzen.
Hol is van a programban az üzenet. Ja, addig el se jut. Valójában a mime-type ellenőrzésen hasal meg. Az üzenetben ennyire részletesen nem szerepel.
A Yii2 model osztályaiban kellemesen paraméterezhető, hogy az adott tagváltozót a milyen szabály(ok) szerint kell ellenőrizni. Persze a file típusú feltöltött állomány például mime-type egyezésre:
['file', 'file', 'mimeTypes' => ['application/pdf','application/msword','application/vnd.openxmlformats-officedocument.wordprocessingml.template']]
Lehetne kiterjesztésre is, de azt ugye a csúnya, rossz hacker átírhatja.
Akkor logoljunk kint, debugoljunk itthon...
Itthon persze Windows, a hoston meg Linux. A feltöltéskor az állomány átmeneti mappába kerül. Windows esetén kiterjesztést is kap, a Linuxon meg nem.
Na itt a kutya elásva. Ha nem áll rendelkezésre a PHP fileinfo modul, akkor a filesystemtől a nem létező kiterjesztés miatt null érték lesz a mime-type, ami nincs benne az engedélyezett listában.
A kód olyan mélyen van a hívási láncon, hogy ebbe belenyúlni nem kellene.
Akkor legyen a kiterjesztés szerinti ellenőrzés... Az meg panaszkodik, hogy kell neki a fileinfo...
Ja, tényleg úgy másfél évvel ez előtt, fejlesztés során mintha előkerült volna ez. De nem emlékszem, hogy az első telepítés során ezzel kellet volna foglalkozni. Na persze az másik szolgáltató, lehet ott alapértelmezett?
Legyen hát bekapcsolom. De jó, ez a cPanel megengedi. És tényleg működik is a feltöltés.
Itt kap értelmet a pár sorral fentebb leírt "ha nem áll rendelkezésre a PHP fileinfo modul", Na ügye...
Próbáljuk ki újra a mime-type feltételt. Hát persze az is működik már.
Persze utólag összeáll a kép, de ehhez kellet pár óra.
Annak is vannak előnyei, ha az ember fia kopasz...
...amelyek igénylik a magyar ékezetes beállítást.
Persze csak 32 bites környezetet futtatni képes Windows esetén van értelme.
Az alábbi szerkesztéseket kell végrehajtani, kizárólag text edítor eszközzel.
A C:\Windows\System32\config.nt állomány végére bekerül az alábbi sor:
country=036,852,c:\windows\system32\keyboard.sys
A C:\Windows\System32\autoexec.nt állomány végére bekerül az alábbi sor:
C:\windows\system32\kb16 HU,852,c:\windows\system32\keyboard.sys
A gépet nem csak az alkalmazást kell újraindítani.
A "cvs history -u uuuuuuu -c -D yyy-mm-dd" parancs megjeleníti a megadott felhasználó "uuuuuuu", megadott "yyy-mm-dd" időpont után kommitálásait.
Kiegészíthető egy grep/findstr szűréssel findstr "2017-01-12", ekkor csak az adott napi kommitokat fogjuk látni.
Persze mind ez állományba is irányítható "> d:\tmp\cvs.txt"
A teljes parancs:
cvs history -u uuuuuu -c -D 2017-01-12 | findstr "2017-01-12" > d:\tmp\cvs.txt