[Database] Lesson 7 – Some Other Procedures & View Concepts

Tram Ho

Before talking about the new concept, as expected from the end of the previous article, we will do the procedure retrieving the article records by category-id and the basic procedure belonging to the group. procedure/article. However for basic procedures like insert, select-by-id, update, delete-by-id, most of the time we can copy/paste the processing code from the procedure/category group and made some minor tweaks. So here I think we just need to finish the example of the select-by-category-id operation of the procedure/article group. 😀 ## A little performance note The select-by-category-id procedure here has general processing logic that we will filter out article records with category-id match the supplied parameter. Even though it’s just a simple procedure, the way we go about it will have some points worth thinking about. To filter out the matching records as said, we can proceed in two ways – – Read all the article records and convert to an array containing object data in the software environment; Then iterate through this array to filter out the records that match the provided category-id. – Read a first article record and convert it to an object data in the software environment; Then immediately check category-id to see if it matches. If appropriate, add to the results array; And so on repeat the same process with all remaining records. It is clear here that in the first case there will be at least some moment where computer memory will have to allocate to store 1001 object data describing article records. The storage will be maintained until the filtering of matching posts is done and the procedure is finished, then the memory that holds the objects' that do not match will be released. Whereas for the second method, when an object of data describing an article is deemed unsuitable for the search results, it is immediately released from the computer's memory. This is a small but important note when we are writing code to work with database, because when the number of records in database is large enough, we will see the difference is noticeable. . procedure/article/select-by-category-id–async-throw.js const readAllRecordIds = require(“./sub-procedure/read-all-record-ids–async-throw”); const selectArticleById = require(“../article/select-by-id–async-throw”); const Article = require(“../../type/Article”); module.exports = async ( in_categoryId = “Infinity”, out_matchedArticles = [] ) => { var allRecordIds = []; await readAllRecordIds(allRecordIds); /* one-by-one select and check */ for (var recordId of allRecordIds) { var selected = new Article(); await selectArticleById(recordId, selected); /* collect the record if matched */ var selectedArticleIsMatched = (selected.get(“category-id”) == in_categoryId); if (selectedArticleIsMatched) out_matchedArticles.push(selected); else /* do nothing */; } // for }; As in the example code above, we have done the job of collecting all article-ids from the directory names of 1001 article records. We then loop through and retrieve each article record to check the category-id, and decide whether to save the result array or drop the object article right away. express-blog/test.js const Article = require(“./database/type/Article”); const Category = require(“./database/type/Category”); const databaseManager = require(“./database/manager”); const view = require(“./database/view/article-left-join-category–all-join-name–async-throw”); const ArticleJoinCategory = require(“./database/type/ArticleJoinCategory/all-join-name”); void async function() { var procedureName, id, selected; await databaseManager.execute( procedureName = “select-articles-by-category-id”, id = “01”, selected = [] ); console.log(selected); }(); // void CMD | Terminal npm test [ Article(7) [Map] { ‘@id’ => ‘0001’, ‘title’ => ‘How To Create A Web Page?’, ‘short-title’ = > ‘Introduction’, ‘keywords’ => [ ‘basic tutorial’, ‘web programming’, ‘html’, ‘introduction’ ], ‘edited-datetime’ => ‘Sat, 16 Apr 2022 10:13:22 GMT’, ‘category-id’ => ’01’, ‘markdown’ => ‘Content of first article…’ }, Article(7) [Map] { ‘@id’ => ‘0002’, ‘title’ => ‘How to Insert Pictures & Links’, ‘short-title’ => ‘Images & Links’, ‘keywords’ => [ ‘basic tutorial’, ‘setup’ web program’, ‘html’, ‘photo’, ‘link’ ], ‘edited-datetime’ => ‘Sat, 16 Apr 2022 19:13:22 GMT’, ‘category-id’ => ’01’, ‘markdown’ => ‘Content of the second post…’ } ] ## Manipulating the combinatorial query select-top Actually, in the previous post, I suggested creating the procedure/article/select-by-category-id procedure is meant to check before deleting a category but is essentially for an example of a slightly more complex query operation and is build on material is the underlying query operation procedure/article/select-by-id. In terms of application, this procedure is not a good solution, because if we have a lot of articles it will be very laborious to iterate through all the article records. Instead we should just loop until the first post with a matching category-id. Thus we can consider writing another procedure to check the valid category deletion. For example procedure to select some of the latest article records in that category (if any) - procedure/article/select-top-by-category-id–async-throw. js const readAllRecordIds = require(“./sub-procedure/read-all-record-ids–async-throw”); const selectArticleById = require(“./select-by-id–async-throw”); const Article = require(“../../type/Article”); module.exports = async ( in_options = { numberOfRecords: 0, reverseOrder: false }, in_categoryId = “Infinity”, out_selected = [] ) => { /* prepare list of all record ids */ var allRecordIds = []; await readAllRecordIds(allRecordIds); if (in_options.reverseOrder == false) /* do nothing */; else allRecordIds = allRecordIds.reverse(); /* select each record to check */ for (var recordId of allRecordIds) { var selected = new Article(); await selectArticleById(recordId, selected); /* collect the record if matched */ if (selected.get(“category-id”) != in_categoryId) /* not matched */; else out_selected.push(selected); /* stop if found enough records */ if (out_selected.length < in_options.numberOfRecords) /* continue collecting */; else break; } // for }; // module.exports With this procedure we loop from the largest id value of the article records back to the first article record. As soon as a matching record is encountered, the iteration is break to end procedure right there. Thus the number of operations that the computer has to perform is likely to be much lower than using procedure first. And the category deletion procedure code can be modified like this. procedure/category/delete-by-id—async-throw.js const selectTopArticleByCategoryId = require(“../article/select-top-by-category-id–async-throw”); const removeRecordFromDatabase = require(“./sub-procedure/remove-record-from-database–async-throw”); const Category = require(“../../type/Category”); module.exports = async ( in_recordId = “Infinity”, out_deleted = new Category() ) => { try { var selectedArticles = []; await selectTopArticleByCategoryId( { numberOfRecords: 1, reverseOrder: true }, in_recordId, selectedArticles ); var theCategoryIsEmpty = (selectedArticles.length == 0); if (theCategoryIsEmpty) await removeRecordFromDatabase(in_recordId, out_deleted); else throw new Error(“There are articles in this category”); } catch (error) { throw error; } }; // module.exports The above select-top query operation is very common and is often used when we want to select the first few records in a large result set. ## Combined query operation join Let's say we need data to create a single article page. Now in addition to the data fields provided by the article record, we will need to add the name field of the corresponding category record. Code that uses databaseManager from the outside can be handled by calling the select-article-by-id procedure to get the article record, and then retrieving the category-id and continuing to call procedure select-category-by-id to get the corresponding category record and then retrieve name. A union query operation like this is very common when using relational database and so relational database management systems often provide a method called join that joins the two versions. related records to form a new conjugate data type as the return result. To write similar processing code for simple database management software, we can define a federated data type class ArticleJoinCategory, and then write a procedure that performs the associated query operation. match to return a result object of that data type. database/type/ArticleJoinCategory–all-join-name.js const Article = require(“./Article”); const Category = require(“./Category”); const ArticleJoinCategory = class extends Map { constructor(…params) { super(…params); ArticleJoinCategory.initialize(“@id”, this) .initialize(“title”, this) .initialize(“short-title”, this) .initialize(“keywords”, this) .initialize(“edited-datetime”, this ) .initialize(“markdown”, this) .initialize(“category-id”, this) .initialize(“category-name”, this); return this; } static initialize( in_key = “”, out_article = new Article() ) { if (out_article.has(in_key)) /* do nothing */ ; else out_article.set(in_key, null); return Article; } static populate( in_article = new Article(), in_category = new Category(), out_joined = new ArticleJoinCategory() ) { var allArticleEntries = [ …in_article ]; for (var entry of allArticleEntries) { var [key, value] = entry; out_joined.set(key, value); } // for var categoryName = in_category.get(“name”); out_joined.set(“category-name”, categoryName); } }; // ArticleJoinCategory module.exports = ArticleJoinCategory; procedure/article-join-category–all-join-name/select-by-article-id–async-throw.js const ArticleJoinCategory = require(“../../type/ArticleJoinCategory –all-join-name”); const Article = require(“../../type/Article”); const Category = require(“../../type/Category”); const selectArticleById = require(“./select-by-id–async-throw”); const selectCategoryById = require(“../category/select-by-id–async-throw”); module.exports = async ( in_articleId = “”, out_selectedJoin = new ArticleJoinCategory() ) => { var selectedArticle = new Article(); await selectArticleById(in_articleId, selectedArticle); var categoryId = selectedArticle.get(“category-id”); var selectedCategory = new Category(); await selectCategoryById(categoryId, selectedCategory); ArticleJoinCategory.populate(selectedArticle, selectedCategory, out_selectedJoin); }; database/manager.js const storedProcedure = new Map(); /* other procedures … */ storedProcedure.set( “select-article-by-id-join-category–all-join-name”, require(“./procedure/article-join-category–all- join-name/select-by-article-id–async-throw”) ); exports.execute = async ( procedureName = “procedure-name”, …parameters ) => { await storedProcedure .get(procedureName) .call(null, …parameters); }; express-blog/test.js const databaseManager = require(“./database/manager”); const ArticleJoinCategory = require(“./database/type/ArticleJoinCategory–all-join-name”); void async function() { var procedureName, id, selected; await databaseManager.execute( procedureName = “select-article-by-id-join-category–all-join-name”, id = “01”, selected = new ArticleJoinCategory() ); console.log(selected); }(); // void CMD | Terminal npm test ArticleJoinCategory(8) [Map] { ‘@id’ => ‘0001’, ‘title’ => ‘How To Create A Web Page?’, ‘short-title’ => ‘Introduction’, ‘keywords’ => [ ‘basic tutorial’, ‘web programming’, ‘html’, ‘introduction’ ], ‘edited-datetime’ => ‘Sat, 16 Apr 2022 10 :13:22 GMT’, ‘markdown’ => ‘Text of first post…’, ‘category-id’ => ’01’, ‘category-name’ => ‘html5’ } ## Initializing & Using view The concept of view - or viewport - in managing database is no different from other contexts we have seen since view comes before . A view is an interface that presents information to an observer - and in database management in particular a view is considered a data table interface with data fields designed to meet meet certain query and usage needs. Derived from the procedure union query we just wrote above; The result we get is an object describing a union record of class ArticleJoinCategory with the data fields @id, title, ..., category-name. If we query all the associated article records and put the resulting objects into an array one by one, we can consider that array as a view; And this view can be expressed in tabular form as follows - +——+——————–+– ———+————+———-+ | @id | title | ……… | category-id | category-name | +——+————————–+———–+———- —-+—————+ | 0000 | How To … | ……… | 01 | html | +——+————————–+———–+———- —-+—————+ | 0001 | How to Insert Pictures… | ……… | 01 | html | +——+————————–+———–+———- —-+—————+ | …. | ………… | ……… | .. | …. | +——+————————–+———–+———- —-+—————+ | 1001 | Complete Series | ……… | .. | …. | +——+————————–+———–+———- —-+—————+ And below is the expression in the management code database - structure.txt [database] . | . +—–[data] . +—–[procedure] . | | . | +—–[article] . | +—–[category] . | +—–[article-join-category–all-join-name] . | | . | +—–select-by-article-id–async-throw.js . | . +—–[type] . +—–[view] . | . +—–article-join-category–all-join-name–async-throw.js database/view/article-join-category–all-join-name–async -throw.js const readAllArticleIds = require(“../procedure/article/sub-procedure/read-all-record-ids–async-throw”); const ArticleJoinCategory = require(“../type/ArticleJoinCategory–all-join-name”); const selectArticleByIdJoinCategory = require(“../procedure/article-join-category–all-join-name/select-by-article-id–async-throw”); const view = { indexData: async function* ( in_options = { reverseOrder: false } ) { var allArticleIds = []; await readAllArticleIds(allArticleIds); if (in_options.reverseOrder == false) /* do nothing */; else allArticleIds = allArticleIds.reverse(); for (var articleId of allArticleIds) { var joinedRecord = new ArticleJoinCategory(); await selectArticleByIdJoinCategory(articleId, joinedRecord); yield joinedRecord; } // for .. of } // indexData }; // view module.exports = view; Here we have view which is an object which contains the method indexData which is a generator function. When we call this method, the result is an abstract tuple containing all the associated article records - and the same data table we talked about above. Now we will loop through each record in this table and print to console. express-blog/test.js const view = require(“./database/view/article-join-category–all-join-name–async-throw”); void async function() { var allJoinedRecords = view.indexData({ reverseOrder: true }); for await (var record of allJoinedRecords) { console.log(record); } } (); // void CMD | Terminal npm test ArticleJoinCategory(8) [Map] { ‘@id’ => ‘0002’, ‘title’ => ‘How to Insert Images & Links’, ‘short-title’ => ‘Image & Links’, ‘keywords’ => [ ‘basic tutorial’, ‘web programming’, ‘html’, ‘photo’, ‘link’ ], ‘edited-datetime’ => ‘Sat, 16 Apr 2022 19:13:22 GMT’, ‘markdown’ => ‘Content of second article…’, ‘category-id’ => ’01’, ‘category-name’ => ‘html5’ } ArticleJoinCategory( 8) [Map] { ‘@id’ => ‘0001’, ‘title’ => ‘How to Create a Website?’, ‘short-title’ => ‘Introduction’, ‘keywords ‘ => [ ‘basic tutorial’, ‘web programming’, ‘html’, ‘introduction’ ], ‘edited-datetime’ => ‘Sat, 16 Apr 2022 10:13:22 GMT’, ‘markdown ‘ => ‘Content of first article…’, ‘category-id’ => ’01’, ‘category-name’ => ‘html5’ } ArticleJoinCategory(8) [Map] { ‘@id’ => ‘0000’, ‘title’ => ‘The content you searched for does not exist’, ‘short-title’ => ‘Content does not exist’, ‘keywords’ => [ ‘basic guide’, ‘web programming’ ], ‘edited-datetime’ => ‘Sat, 16 Apr 2022 01:13:2 2 GMT’, ‘markdown’ => ‘The content you are looking for does not exist…’, ‘category-id’ => ’00’, ‘category-name’ => ‘unknown’ } Thus, for other query operations related to the association record type ArticleJoinCategory, we can query through this view. A good example is when we want to select a few of the latest articles to present a short introduction on the homepage interface. Now we can write a select-top routine using this view as follows - procedure/article-join-category–all-join-name/select-top–async-throw .js const view = require(“../../view/article-join-category–all-join-name–async-throw”); module.exports = async ( in_options = { numberOfRecords: 0, reverseOrder: false }, out_selected = [] ) => { var allJoinedRecords = view.indexData({ …in_options }); for await (var record of allJoinedRecords) { if (out_selected.length < in_options.numberOfRecords) out_selected.push(record); else break; } // for await }; database/manager.js const storedProcedure = new Map(); /* other procedures … */ storedProcedure.set( “select-top-articles-join-category–all-join-name”, require(“./procedure/article-join-category–all-join- name/select-top-by-category-id–async-throw”) ); exports.execute = async ( procedureName = “procedure-name”, …parameters ) => { await storedProcedure .get(procedureName) .call(null, …parameters); }; database/test.js const databaseManager = require(“./database/manager”); void async function() { var procedure, options, selected; await databaseManager.execute( procedure = “select-top-articles-join-category–all-join-name”, options = { numberOfRecords: 3, reverseOrder: true }, selected = [] ); console.log(selected); }(); // void CMD | Terminal [ ArticleJoinCategory(8) [Map] { ‘@id’ => ‘0002’, ‘title’ => ‘How to Insert Pictures & Links’, ‘short-title’ => ‘Image & Links’ End’, ‘keywords’ => [ ‘basic tutorial’, ‘web programming’, ‘html’, ‘photo’, ‘link’ ], ‘edited-datetime’ => ‘Sat, 16 Apr 2022 19 :13:22 GMT’, ‘markdown’ => ‘Content of second article…’, ‘category-id’ => ’01’, ‘category-name’ => ‘html5’ }, ArticleJoinCategory( 8) [Map] { ‘@id’ => ‘0001’, ‘title’ => ‘How to Create a Website?’, ‘short-title’ => ‘Introduction’, ‘keywords ‘ => [ ‘basic tutorial’, ‘web programming’, ‘html’, ‘introduction’ ], ‘edited-datetime’ => ‘Sat, 16 Apr 2022 10:13:22 GMT’, ‘markdown ‘ => ‘Content of first article…’, ‘category-id’ => ’01’, ‘category-name’ => ‘html5’ }, ArticleJoinCategory(8) [Map] { ‘@id ‘ => ‘0000’, ‘title’ => ‘The content you searched for does not exist’, ‘short-title’ => ‘Content does not exist’, ‘keywords’ => [ ‘basic guide’ , ‘web programming’ ], ‘edited-datetime’ => ‘Sat, 16 Apr 2022 01:13:22 GMT ‘, ‘markdown’ => ‘The content you are looking for does not exist…’, ‘category-id’ => ’00’, ‘category-name’ => ‘unknown’ } ] # # End of the article So we got a rough idea of ​​the view concept in database management and some common compound query methods select-top and join. We will see these concepts again in Sub-Series SQL in more detail. For now we will pause Sub-Series Database` here for a short while to finalize the simple blog site under construction as previously planned. See you in the next articles. 😀 (Not Published) [**[Database] Lesson 8 – Take it slow to see what we need to learn more. Learn the natural way. :D**](#)

Share the news now

Source : Viblo