mkst Δημοσ. 26 Απριλίου 2006 Δημοσ. 26 Απριλίου 2006 Καλησπέρα! Ψάχνω έναν τρόπο για αυτόματη εκυπωση (χωρίς την μεσολάβηση χρήστη). Αυτή είναι η διαδικασία που πρέπει να ακολουθηθεί: 1) Χρήστες εισάγουν δεδομένα σε μία βάση 2) Κάθε φορά που υπάρχει ένα καινούργιο entry στην βάση, κάποιος browser σε κάποιο μηχάνημα το απεικονίζει 3) Μόλις απεικονίσει ένα καινούργιο entry, στέλνει εντολή στον printer για εκτύπωση. Έχετε κάτι να προτείνετε τόσο σε επίπεδο αυτόματης απεικόνισης κάθε καινούργιας εισαγωγής στον πίνακα όσο και σε επίπεδο αυτόματης εκτύπωσης (πχ μπορώ με javascript ή κάπως να στείλω ένα έγγραφο προς εκτύπωση ΧΩΡΙΣ ο χρήστης να πατήσει Print ?)
zinas Δημοσ. 28 Απριλίου 2006 Δημοσ. 28 Απριλίου 2006 Αν κατάλαβα καλά, μιλάς για web εφαρμογή. Αν χρησιμοποιείς php υπάρχουν κατάλληλες συναρτήσεις για εκτύπωση. http://gr.php.net/manual/el/ref.printer.php Για να ανανεώνεται η σελίδα αυτόματα όταν εισάγωνται καινούρια δεδομένα στη βάση, δυστυχώς δεν ξέρω πως γίνεται (ή ακόμα και αν γίνεται). Σίγουρα όμως μπορείς να κάνεις refresh τη σελίδα ανά τακτά χρονικά διαστήματα, και αν δεις ότι στη βάση υπάρχουν νέα δεδομένα τότε να τυπώνεις αυτά που θες.
mkst Δημοσ. 28 Απριλίου 2006 Μέλος Δημοσ. 28 Απριλίου 2006 Σε ευχαριστώ για την απάντησή σου zinas. Οι συγκεκριμένες συναρτήσεις αφορούν περιπτώσεις που web server και printer βρίσκονται στο ίδιο μηχάνημα. Για το θέμα της εκτύπωσης βρήκα ένα vb script που ενσωματώνεται στην html και τυπώνει τα περιεχόμενα του browser χωρίς την μεσολάβηση του χρήστη. Το θέμα που με απασχολεί τώρα είναι με ποιον τρόπο να εκτυπώνω τα entries του πίνακα, χωρίς να τυπώνω το ίδιο entry δύο φορές και χωρίς να χάνω κάποιο. Αυτό που σκέφτηκα είναι: Αν έχω κάποιο table entries με πεδία: id,name,description,printed Σεναριο: 1.Εισάγονται 2 entries στον πίνακα με το default printed = NO 2.Την επόμενη φορά που κανει refresh η σελίδα δείχνει τα: SELECT * FROM entries WHERE `printed`='NO' ενώ παράλληλα κάνει: 3.UPDATE entries set `printed`='YES' where id in (1,2) 4. Στο επόμενο refresh όλα τα entries θα έχoυν printεd=YES οπότε η σελίδα δεν θα δείξει τίποτα. Δεν ξέρω κατά πόσο η λύση θα είναι αξιόπιστη περιμένω τις απόψεις σας.
Cue Δημοσ. 28 Απριλίου 2006 Δημοσ. 28 Απριλίου 2006 Το refresh που αναφέρει ο zinas does the trick και δεν μπλέκεις με πολλά πολλά. Το flag σε κάθε καταχώρηση πιστεύω ότι είναι μια σωστή προσέγγιση απλά πρόσεξε να αλλάζεις το status του εφόσον αυτό εκτυπωθεί και όχι σε κάθε select.
zinas Δημοσ. 28 Απριλίου 2006 Δημοσ. 28 Απριλίου 2006 Επίσης, αντί για ένα flag μπορείς να κρατάς ημερομηνία τελευταίας ανανέωσης (εννοώ ανανέωσης της εγγραφής, και όχι ανανέωσης της σελίδας) και ημερομηνία τελευταίας εκτύπωσης και με βάση τη σύγκριση των 2 να αποφασίζεις αν θες να το τυπώσεις ή όχι.
alkisg Δημοσ. 29 Απριλίου 2006 Δημοσ. 29 Απριλίου 2006 Εφόσον τα τυπώνεις με τη σειρά, δε χρειάζεται πεδίο printed, αρκεί ένας αύξων αριθμός για κάθε εγγραφή και μία μόνο «μεταβλητή» για όλη τη βάση, ο αριθμός της τελευταίας εγγραφής που εκτυπώθηκε. Επομένως: 1) Βάζεις στη σελίδα autorefresh ανά π.χ. 1 λεπτό 2) Κάνεις select * where id > 1234 (όπου 1234 η τελευταία εγγραφή που τυπώθηκε) 3) Τυπώνεις μέσω vb και μετά την εκτύπωση ξανακάνεις hit στον server στέλνοντας (με input type="hidden") την τελευταία γραμμή που τύπωσες 4) Ο server ανανεώνει την μεταβλητή τελευταία_εγγραφή_που_τυπώθηκε και έτσι μπορεί να ξαναγυρίσει στο βήμα 2 και να κάνει σωστά πάλι το select, και να παράγει πάλι ιστοσελίδα με τις εγγραφές που δεν έχουν τυπωθεί. Υ.Γ. τώρα διάβασα αυτό που είπε ο zinas, αυτό που λέω είναι παραπλήσιο αλλά με α/α αντί για ημερομηνία.
Cue Δημοσ. 29 Απριλίου 2006 Δημοσ. 29 Απριλίου 2006 Πως αντιμετωπίζεις ένα αναμενώμενο restart του server καθώς και την δυνατότητα να κρατάς log των entries που έχουν εκτυπωθεί με τον παραπάνω τρόπο?
Sta Δημοσ. 29 Απριλίου 2006 Δημοσ. 29 Απριλίου 2006 Πως αντιμετωπίζεις ένα αναμενώμενο restart του server καθώς και την δυνατότητα να κρατάς log των entries που έχουν εκτυπωθεί με τον παραπάνω τρόπο? Δεν το αντιμετωπίζει αλλά ούτε και η προηγούμενη λύση αντιμετωπίζει παρόμοια ενδεχόμενα. Υπάρχουν διάφορα σενάρια όπου μπορεί να αποτύχει κάποια από τις επιμέρους ενέργειες και κάποιες εγγραφές να μην τυπωθούν ποτέ.
Cue Δημοσ. 29 Απριλίου 2006 Δημοσ. 29 Απριλίου 2006 Όταν λες η προηγούμενη λύση? Εννοείς με το flag? Στην περίπτωση του flag έχεις καταχωρημένη στη βάση την πληροφορία σχετικά με το print άρα δε παίζει το παραπάνω πρόβλημα. Εκτός και αν κάπου έχουμε καταλάβει λάθος. Το restart που ανέφερα πήγαινε στο ότι με την μέθοδο της μεταβλητής κρατάς την πληροφορία στο stateless http. στέλνοντας (με input type="hidden") την τελευταία γραμμή που τύπωσες και όχι στα ενδεχόμενα προβλήματα όσον αφορά το printing αυτό καθ' αυτό.
Sta Δημοσ. 29 Απριλίου 2006 Δημοσ. 29 Απριλίου 2006 Η λύση με το flag που είναι πολύ κομψή βέβαια, περιλαμβάνει 4 βήματα (όπως την έδωσε ο mkst), έχει παραληφθεί βέβαια η εκτύπωση από τη ρουτίνα της VB. Η λύση του alkisg έχει επίσης 4 βήματα. Εσύ λες ότι, στη δεύτερη λύση, αν κάνει restart ο web server στο βήμα 3 υπάρχει πρόβλημα. Αν αντικατασταθεί το το hit στο server με ένα SQL UPDATE θα λυθεί το πρόβλημα; Νομίζω πως όχι. Εξάλλου το ίδιο πρόβλημα έχει και η πρώτη λύση, αν κάνει restart ο server πριν το βήμα 3, καταλαβαίνεις ότι κι εκεί υπάρχει ανάλογο πρόβλημα. Τώρα βέβαια θα μου πεις ποιός server, ο database ή ο web ή και οι δύο.
Cue Δημοσ. 29 Απριλίου 2006 Δημοσ. 29 Απριλίου 2006 Όντως μιλάμε για διαφορετικό πρόβλημα Αναρωτήθηκα πως το αντιμετωπίζεις γιατί μου φάνηκε ότι υπάρχει το πρόβλημα που αναφέρω. Πιο πρόβλημα? Το γεγονός ότι εφόσον δεν κρατάς perstistant το status του printed αλλά βασίζεσαι στο http request (ή έστω στο session) σε ένα ενδεχόμενο restart "χάνεις" αυτό το status κάτι το οποίο φυσικά δεν ισχύει με το να το κρατάς στη βάση. Εσύ απ'ότι κατάλαβα αναφέρεσε στο πρόβλημα της εκτύπωσης και το ότι εφόσον αυτή αποτύχει δε μπορείς να το αντιμετωπίσεις είτε με τον ένα είτε με τον άλλο τρόπο, το οποίο με βρίσκει σύμφωνο. ΥΓ. Αυτά είναι τα προβλήματα του γραπτού λόγου και ειδικά μέσα από ένα forum.
Sta Δημοσ. 29 Απριλίου 2006 Δημοσ. 29 Απριλίου 2006 Είχα υπόψη μου και την περίπτωση αποτυχίας της εκτύπωσης, που βέβαια δεν αντιμετωπίζεται, αλλά δε μιλάω για αυτό. Πολύ σωστά λες ότι εάν αποτύχει το http request, υπάρχει πρόβλημα. Αν λοιπόν, αντί για http request με ένα hidden πεδίο, έχουμε ένα πίνακα last_printed στη βάση με ένα πεδίο last_printed_id, και το ενημερώνουμε κάθε φορά με το τελευταίο entry που τυπώθηκε, τότε λύνεται το πρόβλημα, έτσι δεν είναι; Εγώ απλώς εμμένω στην ορθότητα της λύσης του alkisg ως προς το ότι κρατάει ένα μόνο αύξοντα αριθμό για όλη τη βάση, και δεν προσθέτει σε κάθε εγγραφή ένα επιπλέον πεδίο printed. Και η λύση αυτή βέβαια όπως και η προηγούμενη μπορεί να σπάσει. Αν π.χ. σταλεί κάτι για εκτύπωση και αποτύχει το SQL UPDATE τότε θα έχουμε διπλή εκτύπωση. Αυτό προκύπτει από το γεγονός ότι δεν είναι μία atomic ενέργεια αλλά γίνεται ακολουθιακά. ΥΓ: Ελπίζω να κατάλαβες τι εννοώ, είναι αλήθεια ότι δεν έχω ταλέντο στο γραπτό λόγο.
Cue Δημοσ. 29 Απριλίου 2006 Δημοσ. 29 Απριλίου 2006 Δεν είναι θέμα να αποτύχει το request, απλά είναι stateless by nature έχουμε ένα πίνακα last_printed στη βάση με ένα πεδίο last_printed_id' date=' και το ενημερώνουμε κάθε φορά με το τελευταίο entry που τυπώθηκε, τότε λύνεται το πρόβλημα, έτσι δεν είναι;[/quote'] Αυτή είναι μια λύση πολύ σωστή η οποία δεν αναφέρθηκε προτίστως Κατά τα άλλα δε διαφωνώ ότι όντως το να έχεις 1 entry δουλεύει αλγοριθμικά και είναι ίσως "πιο elegant" αλλά πιστεύω το να μην σχετίζεις το entry με το print status "one-to-one" εγκυμoνεί "headaches". Επαναλαμβάνω, όχι αλγοριθμικά. (εκτός από το πρόβλημα του atomic που πολύ σωστά επισήμανες) Καταλαβαίνω απολύτως τα όσα λες. Επίσης το δεύτερό μου ερώτημα παραμένει την δυνατότητα να κρατάς log των entries που έχουν εκτυπωθεί Πολύ εύκολα μπορεί να πει κανείς βάσει αύξοντα αριθμού αλλά πολύ φοβάμαι πως το να στηρίζεσαι στο row id δεν είναι ότι καλύτερο αν το δούμε από την σκοπιά του db management. Για να γίνω περισσότερο κατανοητός. Έστω ότι έχουμε τα παρακάτω entries > id entry 1 A 2 B 3 C με τον αύξοντα αριθμό = 2. Τότε μπορούμε πολύ εύκολα να βρούμε πως οι εκτυπωμένες εγγραφές είναι οι 1 και 2. Από την οπτική του db management όμως το να αλλάξεις id σε ένα row δεν είναι critical εφόσον δεν παραβιάζονται τα constraints. Έτσι σε μία ενδεχόμενη αλλαγή των id(s) > id entry 4 A 5 B 6 C παρουσιάζεται πρόβλημα. Θα μπορούσαμε το id να το πούμε code έτσι ώστε να αποτελεί πραγματικά χαρακτηριστικό του entry και όχι του row. Αλλά εφόσον αναγκαστούμε να προσθέσουμε ένα extra column για να δηλώσουμε το status του print γιατί να μην έχουμε ένα column type boolean που να ορίζει ακριβώς αυτό. My thoughts.
Sta Δημοσ. 29 Απριλίου 2006 Δημοσ. 29 Απριλίου 2006 Συμφωνώ σε όλα όσα λες, οπότε τελικώς ήρθαμε σε συμφωνία.
alkisg Δημοσ. 29 Απριλίου 2006 Δημοσ. 29 Απριλίου 2006 Cue δε με κατάλαβες, στο 4ο βήμα που λέω "Ο server ανανεώνει την μεταβλητή τελευταία_εγγραφή_που_τυπώθηκε" εννοώ ότι τη γράφει στη βάση. Δεν είναι stateless (http), είναι persistent database μεταβλητή. edit: ας γίνω λίγο πιο αναλυτικός. Το να υλοποιήσεις τον κύκλο ανανέωση/εκτύπωση/ενημέρωση του server σε μορφή transaction μάλλον είναι λίγο overkill για το συγκεκριμένο πρόβλημα. Αρκεί να απαλοιφθούν οι πιο συχνές περιπτώσεις ασυμφωνίας μεταξύ εκτυπωμένων εγγραφών και της μεταβλητής "τελευταία_εγγραφή_που_τυπώθηκε". Βάζοντας τον client να στέλνει επιβεβαίωση στο server για το ποιες εγγραφές εκτύπωσε, εξασφαλίζεται ότι η εκτύπωση πέτυχε, ότι ο browser ή ο Η/Υ του client δεν κρέμασε κτλ κτλ (τα λέω πολύ βιαστικά, κανονικά οι περιπτώσεις μη επιτυχούς transaction θέλουν εκτενή ανάλυση). Έτσι, ακόμα κι αν το vb script δεν καταφέρει να εκτυπώσει επειδή π.χ. "printer not found", στη συνέχεια δεν θα "πει" στον browser να στείλει επιβεβαίωση, οπότε σε οποιαδήποτε επόμενη στιγμή γίνει ανανέωση της ιστοσελίδας θα εκτυπωθούν και οι εγγραφές που δεν εκτυπώθηκαν λόγω του προβλήματος. Για την persistent μεταβλητή "τελευταία_εγγραφή_που_τυπώθηκε": μπορεί είτε να μπει στη βάση είτε σε απλό text αρχείο κτλ. Δεν είναι περίεργο, ακόμα και τα φόρουμ έχουν τέτοιες μεταβλητές, π.χ. το smf κρατάει στο settings.php μια μεταβλητή "forum_online" η οποία μηδενίζεται σε περίπτωση συντήρησης του φόρουμ. Προς αποφυγή παρεξηγήσεων, να επαναλάβω ότι η μέθοδος δεν έχει την έννοια transaction, υπάρχουν πολλά σενάρια που αν κάτι πάει στραβά (reset του client, του server κτλ) στα οποία εκτυπώνονται εγγραφές πάνω από μία φορά, αν και δεν μπορώ να σκεφτώ κάποιο σενάριο που να μην εκτυπώνεται καθόλου κάποια εγγραφή.
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.