Example #1
0
            /// Doing so has several advantages:
            ///
            /// - All strings prone to typos (bean kind and field names) are encapsulated inside.
            /// - You get compile-time checks, IDE assistance and [typed properties](#typed-accessors).
            /// - With [Lifecycle Hooks](#lifecycle-hooks), it is easy to implement [data validation](#data-validation) and [relations](#relations).
            ///
            /// For [Custom Beans Classes](#custom-bean-classes), use method overloads with a generic parameter:
            ///
            void Overloads(BeanApi api)
            {
#if CODE
                api.Dispense <Book>();
                api.Load <Book>(1);
                api.Find <Book>("WHERE rating > {0}", 7);
                // and so on
#endif
            }
Example #2
0
        public void NotIsNewBean()
        {
            _storage.EnterFluidMode();

            var key = _storage.Store("foo", SharedChecks.MakeRow("a", 1));
            var foo = _api.Load("foo", key);

            Assert.False(_storage.IsNew(foo));
        }
        public DirtyTrackingTests()
        {
            _api = SQLitePortability.CreateApi();
            _api.Exec("create table foo(id, a, b)");
            _api.Exec("insert into foo values(1, 'initial', 'initial')");

            _bean = _api.Load("foo", 1);

            _api.QueryExecuting += cmd => _queryCount++;
        }
Example #4
0
        public DirtyTrackingTests()
        {
            _api = SQLitePortability.CreateApi();
            _api.Exec("create table foo(id, a, b)");
            _api.Exec("insert into foo values(1, 'initial', 'initial')");

            _bean = _api.Load("foo", 1);

            _api.QueryExecuting += cmd => _queryCount++;
        }
Example #5
0
        void CRUD(BeanApi api)
        {
            /// ## Getting Started: Basic CRUD (Create/Read/Update/Delete)
            ///
            /// For basic usage, LimeBean requires no configuration or table classes!
            ///
            /// Take a look at some basic CRUD scenarios:
            ///
            /// **Create**
#if CODE
            // Create a Bean.
            // "Bean" means row, and "Dispense" makes an empty Bean for a table.
            var bean = api.Dispense("book");

            // Each bean has a "Kind". Kind is a synonym for "table name"
            // You give a Bean its Kind when you Dispense it, or query the database
            var kind = bean.GetKind();
            Console.WriteLine(kind);

            // Fill the new Bean with some data
            bean["title"]  = "Three Comrades";
            bean["rating"] = 10;

            // You can also chain .Put() to do this
            bean.Put("title", "Three Comrades")
            .Put("rating", 10);

            // Store it
            // Store() will Create or Update a record intelligently
            var id = api.Store(bean);

            // Store also returns the Primary Key for the saved Bean, even for multi-column/compound keys
            Console.WriteLine(id);
#endif
            /// **Read** and **Update**
#if CODE
            // Load a Bean with a known ID
            bean = api.Load("book", id);

            // Make some edits
            bean["release_date"] = new DateTime(2015, 7, 30);
            bean["rating"]       = 5;

            // Update database
            api.Store(bean);
#endif
            /// **Delete**
#if CODE
            api.Trash(bean);
#endif
        }
Example #6
0
        public void Assigned_FrozenMode()
        {
            _api.Exec("create table foo (pk, prop)");
            _api.Key("foo", "pk", false);

            var bean = _api.Dispense("foo");

            bean["pk"]   = "pk1";
            bean["prop"] = "value1";

            var key = _api.Store(bean);

            Assert.Equal("pk1", key);

            bean["prop"] = "value2";
            Assert.Equal(key, _api.Store(bean));

            bean = _api.Load("foo", key);
            Assert.Equal(key, bean["pk"]);
            Assert.Equal("value2", bean["prop"]);

            _api.Trash(bean);
            Assert.Equal(0, _api.Count("foo"));
        }
Example #7
0
        public void Scenario()
        {
            // Tell about your database
            var r = new BeanApi("data source=:memory:", SQLiteFactory.Instance);

            // Enable automatic schema update
            r.EnterFluidMode();

            // create a bean
            var bean = r.Dispense("person");

            // it's of kind "person"
            Console.WriteLine(bean.GetKind());

            // give me the Id of the newly stored bean
            var id = bean
                     // fill it
                     .Put("name", "Alex")
                     .Put("year", 1984)
                     .Put("smart", true)
                     // store it
                     .Store();

            // Database schema will be updated automatically for you

            // Now the bean has an id
            Console.WriteLine(bean["id"]);

            // load a bean
            bean = r.Load("person", id);

            bean
            // change it
            .Put("name", "Lexa")
            .Put("new_prop", 123)
            // commit changes
            .Store();

            // or delete it
            r.Trash(bean);

            // close the connection
            r.Dispose();
        }
Example #8
0
        void FluidMode(BeanApi api)
        {
            /// ## Fluid Mode
            /// LimeBean mitigates the common inconvenience associated with relational databases,
            /// namely necessity to manually create tables, columns and adjust their data types.
            /// In this sense, LimeBean takes SQL databases a little closer to NoSQL ones like MongoDB.
            ///
            /// **Fluid Mode** is optional, turned off by default, and is recommended for use only during early development stages
            /// (particularly for prototyping and scaffolding).
            /// To enable it, invoke the `EnterFluidMode` method on the `BeanApi` object:
#if CODE
            api.EnterFluidMode();

            // Make a Bean for a table which doesn't yet exist
            var bean = api.Dispense("book_types");

            // Fill it with some data
            // Limebean will automatically detect Types and create columns with the correct Type
            bean.Put("name", "War")
            .Put("fiction", true);

            // Store will automatically create any missing tables (with an auto-incrementing 'id' column) and columns,
            // then add the Bean as a new row
            var id = api.Store(bean);

            // The bean is now available in the database
            var savedBean = api.Load("book_types", id);
#endif
            /// How does this work? When you save a Bean while in Fluid Mode, LimeBean analyzes its fields and compares
            /// their names and types to the database schema.
            /// If new data cannot be stored to an existing table, schema alteration occurs.
            /// LimeBean can create new tables, add missing columns, and widen data types.
            /// It will never truncate data or delete unused columns.
            ///
            /// **NOTE:** LimeBean will not detect renamings.
            ///
            /// **CAUTION:** Automatically generated schema is usually sub-optimal and lacks indexes which are essential
            /// for performance. When most planned tables are already in place,
            /// it is recommended you turn Fluid Mode off, audit the database structure, add indexes, and make further schema
            /// changes with a dedicated database management tool (like HeidiSQL, SSMS, pgAdmin, etc).
            ///
        }
Example #9
0
        /// <summary>
        /// Gets the owner Bean (the "1"-side of a 1:n relation.
        /// If the Foreign Key Name of the (owned) Bean differs form the
        /// Name of the Owner Bean, it is possible to pass an alias name.
        /// </summary>
        /// <param name="ownerKind">Kind of the owner Bean.</param>
        /// <param name="fkAlias">Alias for the Owner Bean's Foreign Key Name (w/o Primary Key Name)</param>
        /// <returns>Owner Bean</returns>
        public Bean GetOwner(string ownerKind, string fkAlias = "")
        {
            var foreignKey = GetFkName(fkAlias == string.Empty ? ownerKind : fkAlias);

            return(Api.Load(ownerKind, _props[foreignKey]));
        }
Example #10
0
        void CRUD()
        {
            /// ## CRUD
            /// (Create / Read / Update / Delete)
            ///
            /// For basic usage, LimeBean requires zero configuration and no additional code!
            /// Database schema is maintained on-the-fly:
            /// no need to create tables and columns (see [Fluid Mode](#fluid-mode)).
            ///
            /// Take a look at the following sample scenario:
            ///
#if CODE
            // Use a temporary in-memory SQLite database
            var api = new BeanApi("Data Source=:memory:", SQLiteFactory.Instance);

            // Enter the "Fluid Mode"
            api.EnterFluidMode();
#endif
            /// **Create**
#if CODE
            // Create a bean. "Bean" means "data record", "dispense" means "instantiate new".
            var bean = api.Dispense("book");

            // Each bean has a kind. "Kind" is a synonym for "table name"
            var kind = bean.GetKind();
            Console.WriteLine(kind);

            // Fill it with some data
            bean["title"]  = "Three Comrades";
            bean["rating"] = 10;

            // Store it
            // Table "book" with 2 columns, one string and one integer, will be generated automatically
            var id = api.Store(bean);

            // Each saved bean has an ID, or primary key
            Console.WriteLine(id);
#endif
            /// **Read**
#if CODE
            // Load by ID
            bean = api.Load("book", id);
#endif
            /// **Update**
#if CODE
            // Make some edits
            bean["title"]        = "Learn LimeBean";
            bean["release_date"] = new DateTime(2015, 7, 30);
            bean["rating"]       = "good";

            // Save updated bean
            // One new column ("release_date") will be added
            // The type of column "rating" will be expanded from integer to string
            api.Store(bean);
#endif
            /// **Delete**
#if CODE
            api.Trash(bean);

            // Don't forget to close the connection
            api.Dispose();
#endif
        }
Example #11
0
        void CRUD()
        {
            /// ## CRUD
            /// (Create / Read / Update / Delete)
            ///
            /// For basic usage, LimeBean requires zero configuration and no additional code!
            /// Database schema is maintained on-the-fly:
            /// no need to create tables and columns (see [Fluid Mode](#fluid-mode)).
            ///
            /// Take a look at the following sample scenario:
            ///
            #if CODE
            // Use a temporary in-memory SQLite database
            var api = new BeanApi("Data Source=:memory:", SQLiteFactory.Instance);

            // Enter the "Fluid Mode"
            api.EnterFluidMode();
            #endif
            /// **Create**
            #if CODE
            // Create a bean. "Bean" means "data record", "dispense" means "instantiate new".
            var bean = api.Dispense("book");

            // Each bean has a kind. "Kind" is a synonym for "table name"
            var kind = bean.GetKind();
            Console.WriteLine(kind);

            // Fill it with some data
            bean["title"] = "Three Comrades";
            bean["rating"] = 10;

            // Store it
            // Table "book" with 2 columns, one string and one integer, will be generated automatically
            var id = api.Store(bean);

            // Each saved bean has an ID, or primary key
            Console.WriteLine(id);
            #endif
            /// **Read**
            #if CODE
            // Load by ID
            bean = api.Load("book", id);
            #endif
            /// **Update**
            #if CODE
            // Make some edits
            bean["title"] = "Learn LimeBean";
            bean["release_date"] = new DateTime(2015, 7, 30);
            bean["rating"] = "good";

            // Save updated bean
            // One new column ("release_date") will be added
            // The type of column "rating" will be expanded from integer to string
            api.Store(bean);
            #endif
            /// **Delete**
            #if CODE
            api.Trash(bean);

            // Don't forget to close the connection
            api.Dispose();
            #endif
        }
Example #12
0
 /// Doing so has several advantages:
 /// 
 /// - All strings prone to typos (bean kind and field names) are encapsulated inside.
 /// - You get compile-time checks, IDE assistance and [typed properties](#typed-accessors).
 /// - With [Lifecycle Hooks](#lifecycle-hooks), it is easy to implement [data validation](#data-validation) and [relations](#relations).
 /// 
 /// For [Custom Beans Classes](#custom-bean-classes), use method overloads with a generic parameter:
 /// 
 void Overloads(BeanApi api)
 {
     #if CODE
     api.Dispense<Book>();
     api.Load<Book>(1);
     api.Find<Book>("WHERE rating > {0}", 7);
     // and so on
     #endif
 }
Example #13
0
        public void AttachesBean()
        {
            _api.Exec("CREATE TABLE Bean1 (id, Prop)");
            _api.Exec("INSERT INTO Bean1 VALUES(1, 'Bean1Prop')");
            _api.Exec("CREATE TABLE Bean4 (id, Bean1_id, Prop)");
            _api.Exec("INSERT INTO Bean4 VALUES (1, null, 'Bean4Prop1')");

            var bean1 = _api.Load("Bean1", 1);
            // existing Bean
            var bean41 = _api.Load("Bean4", 1);
            // new Bean
            var bean42 = _api.Dispense("Bean4").Put("Prop", "Bean4Prop2");

            Assert.True(bean1.AttachOwned(bean41));
            Assert.True(bean1.AttachOwned(bean42));

            var ownedBeans  = bean1.GetOwnedList("Bean4");
            var cOwnedBeans = bean1.GetOwnedList <Bean4>();

            Assert.Equal(2, ownedBeans.Count);
            Assert.Equal(2, cOwnedBeans.Count);
            Assert.Equal("Bean4Prop1", ownedBeans[0]["Prop"]);
            Assert.Equal("Bean4Prop2", ownedBeans[1]["Prop"]);
            Assert.Equal("Bean4Prop1", cOwnedBeans[0]["Prop"]);
            Assert.Equal("Bean4Prop2", cOwnedBeans[1]["Prop"]);

            // Attaching with missing FK in referencing Bean
            Assert.Throws <MissingForeignKeyColumnException>(() => bean41.AttachOwned(bean1));
        }